问题
I am attempting to set up a project very similar to dueboot. That is, Rust on embedded ARM. Right now, I'm only up to the point of compiling the Rust code, but I can't get it to compile.
I've basically copied the rust code exactly from that project, but I don't fully understand the lang_items
feature.
#![feature(asm)]
#![feature(lang_items)]
#![feature(no_std)]
#![no_std]
use arduino::{init, delay, pinMode, digitalWrite, analogWrite, LOW, HIGH, OUTPUT};
mod arduino;
#[lang="sized"]
trait Sized {}
#[lang="copy"]
trait Copy {}
#[lang="sync"]
trait Sync {}
static PWM:u32 = 2;
static LED:u32 = 11;
#[no_mangle]
pub fn main() {
// ...
}
Attempting to compile the code as above, results in this error:
main.rs:11:1: 11:15 error: parameter `Self` is never used
main.rs:11 trait Sized {}
^~~~~~~~~~~~~~
main.rs:14:1: 14:14 error: parameter `Self` is never used
main.rs:14 trait Copy {}
^~~~~~~~~~~~~
main.rs:17:1: 17:14 error: parameter `Self` is never used
main.rs:17 trait Sync {}
^~~~~~~~~~~~~
error: aborting due to 3 previous errors
I also attempted to comment out all of the lines relating to the lang_items
, including the feature line at the top. This is the resulting error message:
// more lines of the same message
error: requires `sized` lang_item
error: requires `sized` lang_item
error: requires `sized` lang_item
error: requires `sized` lang_item
error: requires `sized` lang_item
error: aborting due to 54 previous errors
I'm using rust built from master, as of yesterday.
Any suggestions?
回答1:
A few days ago, Rust added the rule that all type parameters must appear in the methods of the trait (RFC 738). But since Sized
(and Copy
and Sync
) doesn't have any methods of its own, it breaks this rule by default.
The official workaround is to mark the trait as PhantomFn
, which silences the error:
#![feature(asm)]
#![feature(lang_items)]
#![feature(no_std)]
#![no_std]
use arduino::{init, delay, pinMode, digitalWrite, analogWrite, LOW, HIGH, OUTPUT};
mod arduino;
// Copied from <http://doc.rust-lang.org/core/marker/trait.PhantomFn.html>
#[lang="phantom_fn"]
trait PhantomFn<A: ?Sized, R: ?Sized = ()> {}
#[lang="sized"]
trait Sized: PhantomFn<Self> {}
#[lang="copy"]
trait Copy: PhantomFn<Self> {}
#[lang="sync"]
trait Sync: PhantomFn<Self> {}
static PWM:u32 = 2;
static LED:u32 = 11;
#[no_mangle]
pub fn main() {
// ...
}
This change should make the code compile again.
Addendum: What are lang items?
A lang item is a symbol that's marked as "special" to the compiler. Some examples are:
The heap allocator
Procedures for unwinding on
panic
Types and traits that ensure type safety, like
Send
andDrop
andPhantomData
Traits for operator overloading, like
Add
andEq
andDeref
You can find a list of them in lang_items.rs.
These items are critical to the semantics of the language, but are impractical to implement in the compiler itself. So we put them in the standard library instead, with special annotations that tell the compiler where they are.
Now, while you can define these items itself, it's recommended to link to core instead, which declares these lang items for you. But I'm not sure how well that would work with your setup.
来源:https://stackoverflow.com/questions/28649120/unable-to-compile-rust-with-no-std-lang-items