This error suggests that the expression arm corresponding to the noted pattern will never be reached as for all possible values of the expression being matched, one of the preceding patterns will match.
This means that perhaps some of the preceding patterns are too general, this one is too specific or the ordering is incorrect.
This error indicates that an empty match expression is illegal because the type it is matching on is non-empty (there exist values of this type). In safe code it is impossible to create an instance of an empty type, so empty match expressions are almost never desired. This error is typically fixed by adding one or more cases to the match expression.
An example of an empty type is enum Empty { }
`enum Empty { }`.
Not-a-Number (NaN) values cannot be compared for equality and hence can never
match the input to a match expression. To match against NaN values, you should
instead use the is_nan
`is_nanmethod in a guard, as in:
` method in a guard, as in: x if x.is_nan() => ...
`x if x.is_nan() => ...`
This error indicates that the compiler cannot guarantee a matching pattern for one or more possible inputs to a match expression. Guaranteed matches are required in order to assign values to match expressions, or alternatively, determine the flow of execution.
If you encounter this error you must alter your patterns so that every possible
value of the input type is matched. For types with a small number of variants
(like enums) you should probably cover all cases explicitly. Alternatively, the
underscore _
`_` wildcard pattern can be added after all other patterns to match
"anything else".
Patterns used to bind names must be irrefutable, that is, they must guarantee
that a name will be extracted in all cases. If you encounter this error you
probably need to use a match
`matchor
` or if let
`if let` to deal with the possibility of
failure.
Patterns used to bind names must be irrefutable, that is, they must guarantee
that a name will be extracted in all cases. If you encounter this error you
probably need to use a match
`matchor
` or if let
`if let` to deal with the possibility of
failure.
This error indicates that the bindings in a match arm would require a value to
be moved into more than one location, thus violating unique ownership. Code like
the following is invalid as it requires the entire Option<String>
`Optionto be moved into a variable called
` to be moved
into a variable called op_string
`op_stringwhile simultaneously requiring the inner String to be moved into a variable called
` while simultaneously requiring the inner
String to be moved into a variable called s
`s`.
let x = Some("s".to_string()); match x { op_string @ Some(s) => ... None => ... }
See also Error 303.
Names bound in match arms retain their type in pattern guards. As such, if a name is bound by move in a pattern, it should also be moved to wherever it is referenced in the pattern guard code. Doing so however would prevent the name from being available in the body of the match arm. Consider the following:
match Some("hi".to_string()) { Some(s) if s.len() == 0 => // use s. ... }
The variable s
`shas type
` has type String
`String, and its use in the guard is as a variable of type
`, and its use in the guard is as a variable of
type String
`String`. The guard code effectively executes in a separate scope to the
body of the arm, so the value would be moved into this anonymous scope and
therefore become unavailable in the body of the arm. Although this example seems
innocuous, the problem is most clear when considering functions that take their
argument by value.
match Some("hi".to_string()) { Some(s) if { drop(s); false } => (), Some(s) => // use s. ... }
The value would be dropped in the guard then become unavailable not only in the body of that arm but also in all subsequent arms! The solution is to bind by reference when using guards or refactor the entire expression, perhaps by putting the condition inside the body of the arm.
In a pattern, all values that don't implement the Copy
`Copy` trait have to be bound
the same way. The goal here is to avoid binding simultaneously by-move and
by-ref.
This limitation may be removed in a future version of Rust.
Wrong example:
struct X { x: (), } let x = Some((X { x: () }, X { x: () })); match x { Some((y, ref z)) => {}, None => panic!() }
You have two solutions:
Solution #1: Bind the pattern's values the same way.
struct X { x: (), } let x = Some((X { x: () }, X { x: () })); match x { Some((ref y, ref z)) => {}, // or Some((y, z)) => {} None => panic!() }
Solution #2: Implement the Copy
`Copytrait for the
` trait for the X
`X` structure.
However, please keep in mind that the first solution should be preferred.
#[derive(Clone, Copy)] struct X { x: (), } let x = Some((X { x: () }, X { x: () })); match x { Some((y, ref z)) => {}, None => panic!() }
The value of statics and constants must be known at compile time, and they live for the entire lifetime of a program. Creating a boxed value allocates memory on the heap at runtime, and therefore cannot be done at compile time.
No description.
No description.
Static and const variables can refer to other const variables. But a const
variable cannot refer to a static variable. For example, Y
`Ycannot refer to
` cannot refer to X
`X`
here:
static X: i32 = 42; const Y: i32 = X;
To fix this, the value can be extracted as a const and then used:
const A: i32 = 42; static X: i32 = A; const Y: i32 = A;
No description.
The only function calls allowed in static or constant expressions are enum variant constructors or struct constructors (for unit or tuple structs). This is because Rust currently does not support compile-time function execution.
No description.
No description.
The value of static and const variables must be known at compile time. You can't cast a pointer as an integer because we can't know what value the address will take.
However, pointers to other constants' addresses are allowed in constants, example:
const X: u32 = 50; const Y: *const u32 = &X;
Therefore, casting one of these non-constant pointers to an integer results in a non-constant integer which lead to this error. Example:
const X: u32 = 50; const Y: *const u32 = &X; println!("{:?}", Y);
No description.
This error indicates that an attempt was made to divide by zero (or take the remainder of a zero divisor) in a static or constant expression.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
When trying to make some type implement a trait Foo
`Foo, you must, at minimum, provide implementations for all of
`, you must, at minimum,
provide implementations for all of Foo
`Foo`'s required methods (meaning the
methods that do not have default implementations), as well as any required
trait items like associated types or constants.
This error indicates that an attempted implementation of a trait method has the wrong number of type parameters.
For example, the trait below has a method foo
`foowith a type parameter
` with a type parameter T
`T, but the implementation of
`,
but the implementation of foo
`foofor the type
` for the type Bar
`Bar` is missing this parameter:
trait Foo { fn foo<T: Default>(x: T) -> Self; } struct Bar; // error: method `foo` has 0 type parameters but its trait declaration has 1 // type parameter impl Foo for Bar { fn foo(x: bool) -> Self { Bar } }
This error indicates that an attempted implementation of a trait method has the wrong number of function parameters.
For example, the trait below has a method foo
`foowith two function parameters (
` with two function parameters
(&self
`&selfand
` and u8
`u8), but the implementation of
`), but the implementation of foo
`foofor the type
` for the type Bar
`Baromits the
` omits
the u8
`u8` parameter:
trait Foo { fn foo(&self, x: u8) -> bool; } struct Bar; // error: method `foo` has 1 parameter but the declaration in trait `Foo::foo` // has 2 impl Foo for Bar { fn foo(&self) -> bool { true } }
For any given method of a trait, the mutabilities of the parameters must match between the trait definition and the implementation.
Here's an example where the mutability of the self
`self` parameter is wrong:
trait Foo { fn foo(&self); } struct Bar; impl Foo for Bar { // error, the signature should be `fn foo(&self)` instead fn foo(&mut self) { } } fn main() {}
Here's another example, this time for a non-self
`self` parameter:
trait Foo { fn foo(x: &mut bool) -> bool; } struct Bar; impl Foo for Bar { // error, the type of `x` should be `&mut bool` instead fn foo(x: &bool) -> bool { *x } } fn main() {}
It is not allowed to cast to a bool. If you are trying to cast a numeric type to a bool, you can compare it with zero instead:
let x = 5; // Ok let x_is_nonzero = x != 0; // Not allowed, won't compile let x_is_nonzero = x as bool;
No description.
No description.
No description.
No description.
No description.
This error indicates that during an attempt to build a struct or struct-like enum variant, one of the fields was specified more than once. Each field should be specified exactly one time.
This error indicates that during an attempt to build a struct or struct-like enum variant, one of the fields was not provided. Each field should be specified exactly once.
Box placement expressions (like C++'s "placement new") do not yet support any
place expression except the exchange heap (i.e. std::boxed::HEAP
`std::boxed::HEAP). Furthermore, the syntax is changing to use
`).
Furthermore, the syntax is changing to use in
`ininstead of
` instead of box
`box`. See RFC 470
and RFC 809 for more details.
The left-hand side of an assignment operator must be an lvalue expression. An lvalue expression represents a memory location and includes item paths (ie, namespaced variables), dereferences, indexing expressions, and field references.
use std::collections::LinkedList; // Good let mut list = LinkedList::new(); // Bad: assignment to non-lvalue expression LinkedList::new() += 1;
No description.
The compiler found a function whose body contains a return;
`return;statement but whose return type is not
` statement but
whose return type is not ()
`()`. An example of this is:
// error fn foo() -> u8 { return; }
Since return;
`return;is just like
` is just like return ();
`return ();`, there is a mismatch between the
function's return type and the value being returned.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
Enum variants which contain no data can be given a custom integer representation. This error indicates that the value provided is not an integer literal and is therefore invalid.
This error indicates that the compiler was unable to sensibly evaluate an integer expression provided as an enum discriminant. Attempting to divide by 0 or causing integer overflow are two ways to induce this error. For example:
enum Enum { X = (1 << 500), Y = (1 / 0) }
Ensure that the expressions given can be evaluated as the desired integer type. See the FFI section of the Reference for more information about using a custom integer type:
Enum discriminants are used to differentiate enum variants stored in memory. This error indicates that the same value was used for two or more variants, making them impossible to tell apart.
// Good. enum Enum { P, X = 3, Y = 5 } // Bad. enum Enum { P = 3, X = 3, Y = 5 }
Note that variants without a manually specified discriminant are numbered from top to bottom starting from 0, so clashes can occur with seemingly unrelated variants.
enum Bad { X, Y = 0 }
Here X
`Xwill have already been assigned the discriminant 0 by the time
` will have already been assigned the discriminant 0 by the time Y
`Y` is
encountered, so a conflict occurs.
The default type for enum discriminants is isize
`isize, but it can be adjusted by adding the
`, but it can be adjusted by
adding the repr
`repr` attribute to the enum declaration. This error indicates that
an integer literal given as a discriminant is not a member of the discriminant
type. For example:
#[repr(u8)] enum Thing { A = 1024, B = 5 }
Here, 1024 lies outside the valid range for u8
`u8, so the discriminant for
`, so the discriminant for A
`A` is
invalid. You may want to change representation types to fix this, or else change
invalid discriminant values so that they fit within the existing type.
Note also that without a representation manually defined, the compiler will optimize by using the smallest integer type possible.
At present, it's not possible to define a custom representation for an enum with
a single variant. As a workaround you can add a Dummy
`Dummy` variant.
It is impossible to define an integer type to be used to represent zero-variant enum values because there are no zero-variant enum values. There is no way to construct an instance of the following type using only safe code:
enum Empty {}
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
This error indicates that a lifetime is missing from a type. If it is an error inside a function signature, the problem may be with failing to adhere to the lifetime elision rules (see below).
Here are some simple examples of where you'll run into this error:
struct Foo { x: &bool } // error struct Foo<'a> { x: &'a bool } // correct enum Bar { A(u8), B(&bool), } // error enum Bar<'a> { A(u8), B(&'a bool), } // correct type MyStr = &str; // error type MyStr<'a> = &'a str; //correct
Lifetime elision is a special, limited kind of inference for lifetimes in function signatures which allows you to leave out lifetimes in certain cases. For more background on lifetime elision see the book.
The lifetime elision rules require that any function signature with an elided output lifetime must either have
&self
`&selfor
` or &mut self
`&mut self` receiverIn the first case, the output lifetime is inferred to be the same as the unique
input lifetime. In the second case, the lifetime is instead inferred to be the
same as the lifetime on &self
`&selfor
` or &mut self
`&mut self`.
Here are some examples of elision errors:
// error, no input lifetimes fn foo() -> &str { ... } // error, `x` and `y` have distinct lifetimes inferred fn bar(x: &str, y: &str) -> &str { ... } // error, `y`'s lifetime is inferred to be distinct from `x`'s fn baz<'a>(x: &'a str, y: &str) -> &str { ... }
This error means that an incorrect number of lifetime parameters were provided for a type (like a struct or enum) or trait.
Some basic examples include:
struct Foo<'a>(&'a str); enum Bar { A, B, C } struct Baz<'a> { foo: Foo, // error: expected 1, found 0 bar: Bar<'a>, // error: expected 0, found 1 }
Here's an example that is currently an error, but may work in a future version of Rust:
struct Foo<'a>(&'a str); trait Quux { } impl Quux for Foo { } // error: expected 1, found 0
Lifetime elision in implementation headers was part of the lifetime elision RFC. It is, however, currently unimplemented.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
It is not possible to define main
`mainwith type parameters, or even with function parameters. When
` with type parameters, or even with function
parameters. When main
`mainis present, it must take no arguments and return
` is present, it must take no arguments and return ()
`()`.
It is not possible to declare type parameters on a function that has the start
`start`
attribute. Such a function must have the following type signature:
fn(isize, *const *const u8) -> isize
Using unsafe functionality, such as dereferencing raw pointers and calling
functions via FFI or marked as unsafe, is potentially dangerous and disallowed
by safety checks. As such, those safety checks can be temporarily relaxed by
wrapping the unsafe instructions inside an unsafe
`unsafe` block. For instance:
unsafe fn f() { return; } fn main() { unsafe { f(); } }
No description.
No description.
No description.
This error indicates that the compiler found multiple functions with the
#[main]
`#[main]` attribute. This is an error because there must be a unique entry
point into a Rust program.
No description.
No description.
No description.
Lang items are already implemented in the standard library. Unless you are writing a free-standing application (e.g. a kernel), you do not need to provide them yourself.
You can build a free-standing crate by adding #![no_std]
`#![no_std]` to the crate
attributes:
#![feature(no_std)] #![no_std]
No description.
Imports (use
`use` statements) are not allowed after non-item statements, such as
variable declarations and expression statements.
Here is an example that demonstrates the error:
fn f() { // Variable declaration before import let x = 0; use std::io::Read; ... }
The solution is to declare the imports at the top of the block, function, or file.
Here is the previous example again, with the correct order:
fn f() { use std::io::Read; let x = 0; ... }
See the Declaration Statements section of the reference for more information about what constitutes an Item declaration and what does not:
No description.
const
`constand
` and static
`staticmean different things. A
` mean different things. A const
`const` is a compile-time
constant, an alias for a literal value. This property means you can match it
directly within a pattern.
The static
`statickeyword, on the other hand, guarantees a fixed location in memory. This does not always mean that the value is constant. For example, a global mutex can be declared
` keyword, on the other hand, guarantees a fixed location in memory.
This does not always mean that the value is constant. For example, a global
mutex can be declared static
`static` as well.
If you want to match against a static
`static`, consider using a guard instead:
static FORTY_TWO: i32 = 42; match Some(42) { Some(x) if x == FORTY_TWO => ... ... }
No description.
In Rust, you can only move a value when its size is known at compile time.
To work around this restriction, consider "hiding" the value behind a reference:
either &x
`&xor
` or &mut x
`&mut x`. Since a reference has a fixed size, this lets you move
it around as usual.
An if-let pattern attempts to match the pattern, and enters the body if the
match was successful. If the match is irrefutable (when it cannot fail to
match), use a regular let
`let`-binding instead. For instance:
struct Irrefutable(i32); let irr = Irrefutable(0); // This fails to compile because the match is irrefutable. if let Irrefutable(x) = irr { // This body will always be executed. foo(x); } // Try this instead: let Irrefutable(x) = irr; foo(x);
No description.
No description.
A while-let pattern attempts to match the pattern, and enters the body if the
match was successful. If the match is irrefutable (when it cannot fail to
match), use a regular let
`let-binding inside a
`-binding inside a loop
`loop` instead. For instance:
struct Irrefutable(i32); let irr = Irrefutable(0); // This fails to compile because the match is irrefutable. while let Irrefutable(x) = irr { ... } // Try this instead: loop { let Irrefutable(x) = irr; ... }
This error means that the compiler found a return expression in a function
marked as diverging. A function diverges if it has !
`!` in the place of the
return type in its signature. For example:
fn foo() -> ! { return; } // error
For a function that diverges, every control path in the function must never
return, for example with a loop
`loopthat never breaks or a call to another diverging function (such as
` that never breaks or a call to another
diverging function (such as panic!()
`panic!()`).
No description.
No description.
Enum variants are qualified by default. For example, given this type:
enum Method { GET, POST }
you would match it using:
match m { Method::GET => ... Method::POST => ... }
If you don't qualify the names, the code will bind new variables named "GET" and
"POST" instead. This behavior is likely not what you want, so rustc
`rustc` warns when
that happens.
Qualified names are good practice, and most code works well with them. But if you prefer them unqualified, you can import the variants into scope:
use Method::*; enum Method { GET, POST }
No description.
No description.
No description.
No description.
No description.
No description.
Explicitly implementing both Drop and Copy for a type is currently disallowed. This feature can make some sense in theory, but the current implementation is incorrect and can lead to memory unsafety (see issue #20126), so it has been disabled for now.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
Inherent implementations (one that do not implement a trait but provide
methods associated with a type) are always safe because they are not
implementing an unsafe trait. Removing the unsafe
`unsafe` keyword from the inherent
implementation will resolve this error.
struct Foo; // this will cause this error unsafe impl Foo { } // converting it to this will fix it impl Foo { }
A negative implementation is one that excludes a type from implementing a particular trait. Not being able to use a trait is always a safe operation, so negative implementations are always safe and never need to be marked as unsafe.
struct Foo; // unsafe is unnecessary unsafe impl !Clone for Foo { } // this will compile impl !Clone for Foo { }
Safe traits should not have unsafe implementations, therefore marking an implementation for a safe trait unsafe will cause a compiler error. Removing the unsafe marker on the trait noted in the error will resolve this problem.
struct Foo; trait Bar { } // this won't compile because Bar is safe unsafe impl Bar for Foo { } // this will compile impl Bar for Foo { }
Unsafe traits must have unsafe implementations. This error occurs when an implementation for an unsafe trait isn't marked as unsafe. This may be resolved by marking the unsafe implementation as unsafe.
struct Foo; unsafe trait Bar { } // this won't compile because Bar is unsafe and impl isn't unsafe impl Bar for Foo { } // this will compile unsafe impl Bar for Foo { }
It is an error to define a method--a trait method or an inherent method--more than once.
For example,
struct Foo(u8); impl Foo { fn bar() {} // error: duplicate method fn bar(&self) -> bool { self.0 > 5 } }
No description.
No description.
An attempt to implement the Copy
`Copytrait for a struct failed because one of the fields does not implement
` trait for a struct failed because one of the
fields does not implement Copy
`Copy. To fix this, you must implement
`. To fix this, you must implement Copy
`Copy` for the
mentioned field. Note that this may not be possible, as in the example of
struct Foo { foo : Vec<u32>, } impl Copy for Foo { }
This fails because Vec<T>
`Vecdoes not implement
` does not implement Copy
`Copyfor any
` for any T
`T`.
Here's another example that will fail:
#[derive(Copy)] struct Foo<'a> { ty: &'a mut bool, }
This fails because &mut T
`&mut Tis not
` is not Copy
`Copy, even when
`, even when T
`Tis
` is Copy
`Copy(this differs from the behavior for
` (this
differs from the behavior for &T
`&T, which is always
`, which is always Copy
`Copy`).
An attempt to implement the Copy
`Copytrait for an enum failed because one of the variants does not implement
` trait for an enum failed because one of the
variants does not implement Copy
`Copy. To fix this, you must implement
`. To fix this, you must implement Copy
`Copy` for
the mentioned variant. Note that this may not be possible, as in the example of
enum Foo { Bar(Vec<u32>), Baz, } impl Copy for Foo { }
This fails because Vec<T>
`Vecdoes not implement
` does not implement Copy
`Copyfor any
` for any T
`T`.
Here's another example that will fail:
#[derive(Copy)] enum Foo<'a> { Bar(&'a mut bool), Baz }
This fails because &mut T
`&mut Tis not
` is not Copy
`Copy, even when
`, even when T
`Tis
` is Copy
`Copy(this differs from the behavior for
` (this
differs from the behavior for &T
`&T, which is always
`, which is always Copy
`Copy`).
You can only implement Copy
`Copyfor a struct or enum. Both of the following examples will fail, because neither
` for a struct or enum. Both of the following
examples will fail, because neither i32
`i32(primitive type) nor
` (primitive type) nor &'static Bar
`&'static Bar(reference to
`
(reference to Bar
`Bar`) is a struct or enum:
type Foo = i32; impl Copy for Foo { } // error #[derive(Copy, Clone)] struct Bar; impl Copy for &'static Bar { } // error
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
This error indicates that not enough type parameters were found in a type or trait.
For example, the Foo
`Foostruct below is defined to be generic in
` struct below is defined to be generic in T
`T, but the type parameter is missing in the definition of
`, but the
type parameter is missing in the definition of Bar
`Bar`:
struct Foo<T> { x: T } struct Bar { x: Foo }
This error indicates that too many type parameters were found in a type or trait.
For example, the Foo
`Foostruct below has no type parameters, but is supplied with two in the definition of
` struct below has no type parameters, but is supplied
with two in the definition of Bar
`Bar`:
struct Foo { x: bool } struct Bar<S, T> { x: Foo<S, T> }
No description.
No description.
No description.
No description.
This error indicates a constant expression for the array length was found, but it was not an integer (signed or unsigned) expression.
Some examples of code that produces this error are:
const A: [u32; "hello"] = []; // error const B: [u32; true] = []; // error const C: [u32; 0.0] = []; // error
This means there was an error while evaluating the expression for the length of a fixed-size array type.
Some examples of code that produces this error are:
// divide by zero in the length expression const A: [u32; 1/0] = []; // Rust currently will not evaluate the function `foo` at compile time fn foo() -> usize { 12 } const B: [u32; foo()] = []; // it is an error to try to add `u8` and `f64` use std::{f64, u8}; const C: [u32; u8::MAX + f64::EPSILON] = [];
Two items of the same name cannot be imported without rebinding one of the items under a new local name.
An example of this error:
use foo::baz; use bar::*; // error, do `use foo::baz as quux` instead on the previous line fn main() {} mod foo { pub struct baz; } mod bar { pub mod baz {} }
Two items of the same name cannot be imported without rebinding one of the items under a new local name.
An example of this error:
use foo::baz; use bar::baz; // error, do `use bar::baz as quux` instead fn main() {} mod foo { pub struct baz; } mod bar { pub mod baz {} }
No description.
No description.
You can't import a value whose name is the same as another value defined in the module.
An example of this error:
use bar::foo; // error, do `use bar::foo as baz` instead fn foo() {} mod bar { pub fn foo() {} } fn main() {}
You can't import a type or module when the name of the item being imported is the same as another type or submodule defined in the module.
An example of this error:
use foo::Bar; // error type Bar = u32; mod foo { pub mod Bar { } } fn main() {}
No description.
No description.
The name chosen for an external crate conflicts with another external crate that has been imported into the current module.
Wrong example:
extern crate a; extern crate crate_a as a;
The solution is to choose a different name that doesn't conflict with any external crate imported into the current module.
Correct example:
extern crate a; extern crate crate_a as other_name;
The name for an item declaration conflicts with an external crate's name.
For instance,
extern crate abc; struct abc;
There are two possible solutions:
Solution #1: Rename the item.
extern crate abc; struct xyz;
Solution #2: Import the crate with a different name.
extern crate abc as xyz; struct abc;
See the Declaration Statements section of the reference for more information about what constitutes an Item declaration and what does not:
No description.
No description.
No description.
No description.
This error indicates that a static or constant references itself. All statics and constants need to resolve to a value in an acyclic manner.
For example, neither of the following can be sensibly compiled:
const X: u32 = X;
const X: u32 = Y; const Y: u32 = X;
No description.
This error indicates the use of a loop keyword (break
`breakor
` or continue
`continue`) inside a
closure but outside of any loop. Break and continue can be used as normal inside
closures as long as they are also contained within a loop. To halt the execution
of a closure you should instead use a return statement.
This error indicates the use of a loop keyword (break
`breakor
` or continue
`continue`) outside
of a loop. Without a loop to break out of or continue in, no sensible action can
be taken.
No description.
No description.
This is because of a type mismatch between the associated type of some
trait (e.g. T::Bar
`T::Bar, where
`, where T
`Timplements
` implements trait Quux { type Bar; }
`trait Quux { type Bar; }) and another type
`)
and another type U
`Uthat is required to be equal to
` that is required to be equal to T::Bar
`T::Bar`, but is not.
Examples follow.
Here is a basic example:
trait Trait { type AssociatedType; } fn foo<T>(t: T) where T: Trait<AssociatedType=u32> { println!("in foo"); } impl Trait for i8 { type AssociatedType = &'static str; } foo(3_i8);
Here is that same example again, with some explanatory comments:
trait Trait { type AssociatedType; } fn foo<T>(t: T) where T: Trait<AssociatedType=u32> { // ~~~~~~~~ ~~~~~~~~~~~~~~~~~~ // | | // This says `foo` can | // only be used with | // some type that | // implements `Trait`. | // | // This says not only must // `T` be an impl of `Trait` // but also that the impl // must assign the type `u32` // to the associated type. println!("in foo"); } impl Trait for i8 { type AssociatedType = &'static str; } ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // | | // `i8` does have | // implementation | // of `Trait`... | // ... but it is an implementation // that assigns `&'static str` to // the associated type. foo(3_i8); // Here, we invoke `foo` with an `i8`, which does not satisfy // the constraint `<i8 as Trait>::AssociatedType=32`, and // therefore the type-checker complains with this error code.
Here is a more subtle instance of the same problem, that can arise with for-loops in Rust:
let vs: Vec<i32> = vec![1, 2, 3, 4]; for v in &vs { match v { 1 => {} _ => {} } }
The above fails because of an analogous type mismatch, though may be harder to see. Again, here are some explanatory comments for the same example:
{ let vs = vec![1, 2, 3, 4]; // `for`-loops use a protocol based on the `Iterator` // trait. Each item yielded in a `for` loop has the // type `Iterator::Item` -- that is,I `Item` is the // associated type of the concrete iterator impl. for v in &vs { // ~ ~~~ // | | // | We borrow `vs`, iterating over a sequence of // | *references* of type `&Elem` (where `Elem` is // | vector's element type). Thus, the associated // | type `Item` must be a reference `&`-type ... // | // ... and `v` has the type `Iterator::Item`, as dictated by // the `for`-loop protocol ... match v { 1 => {} // ~ // | // ... but *here*, `v` is forced to have some integral type; // only types like `u8`,`i8`,`u16`,`i16`, et cetera can // match the pattern `1` ... _ => {} } // ... therefore, the compiler complains, because it sees // an attempt to solve the equations // `some integral-type` = type-of-`v` // = `Iterator::Item` // = `&Elem` (i.e. `some reference type`) // // which cannot possibly all be true. } }
To avoid those issues, you have to make the types match correctly. So we can fix the previous examples like this:
// Basic Example: trait Trait { type AssociatedType; } fn foo<T>(t: T) where T: Trait<AssociatedType = &'static str> { println!("in foo"); } impl Trait for i8 { type AssociatedType = &'static str; } foo(3_i8); // For-Loop Example: let vs = vec![1, 2, 3, 4]; for v in &vs { match v { &1 => {} _ => {} } }
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
This error indicates that type inference did not result in one unique possible type, and extra information is required. In most cases this can be provided by adding a type annotation. Sometimes you need to specify a generic type parameter manually.
A common example is the collect
`collectmethod on
` method on Iterator
`Iterator. It has a generic type parameter with a
`. It has a generic type
parameter with a FromIterator
`FromIteratorbound, which for a
` bound, which for a char
`chariterator is implemented by
` iterator is
implemented by Vec
`Vecand
` and String
`String` among others. Consider the following snippet
that reverses the characters of a string:
let x = "hello".chars().rev().collect();
In this case, the compiler cannot infer what the type of x
`xshould be:
` should be:
Vec<char>
`Vecand
` and String
`Stringare both suitable candidates. To specify which type to use, you can use a type annotation on
` are both suitable candidates. To specify which type to
use, you can use a type annotation on x
`x`:
let x: Vec<char> = "hello".chars().rev().collect();
It is not necessary to annotate the full type. Once the ambiguity is resolved, the compiler can infer the rest:
let x: Vec<_> = "hello".chars().rev().collect();
Another way to provide the compiler with enough information, is to specify the generic type parameter:
let x = "hello".chars().rev().collect::<Vec<char>>();
Again, you need not specify the full type if the compiler can infer it:
let x = "hello".chars().rev().collect::<Vec<_>>();
Apart from a method or function with a generic type parameter, this error can occur when a type parameter of a struct or trait cannot be inferred. In that case it is not always possible to use a type annotation, because all candidates have the same return type. For instance:
struct Foo<T> { // Some fields omitted. } impl<T> Foo<T> { fn bar() -> i32 { 0 } fn baz() { let number = Foo::bar(); } }
This will fail because the compiler does not know which instance of Foo
`Footo call
` to
call bar
`baron. Change
` on. Change Foo::bar()
`Foo::bar()to
` to Foo::<T>::bar()
`Foo::
No description.
No description.
No description.
This error indicates that the given recursion limit could not be parsed. Ensure that the value provided is a positive integer between quotes, like so:
#![recursion_limit="1000"]
Patterns used to bind names must be irrefutable. That is, they must guarantee
that a name will be extracted in all cases. Instead of pattern matching the
loop variable, consider using a match
`matchor
` or if let
`if let` inside the loop body. For
instance:
// This fails because `None` is not covered. for Some(x) in xs { ... } // Match inside the loop instead: for item in xs { match item { Some(x) => ... None => ... } } // Or use `if let`: for item in xs { if let Some(x) = item { ... } }
No description.
No description.
No description.
Mutable borrows are not allowed in pattern guards, because matching cannot have side effects. Side effects could alter the matched object or the environment on which the match depends in such a way, that the match would not be exhaustive. For instance, the following would not match any arm if mutable borrows were allowed:
match Some(()) { None => { }, option if option.take().is_none() => { /* impossible, option is `Some` */ }, Some(_) => { } // When the previous match failed, the option became `None`. }
Assignments are not allowed in pattern guards, because matching cannot have side effects. Side effects could alter the matched object or the environment on which the match depends in such a way, that the match would not be exhaustive. For instance, the following would not match any arm if assignments were allowed:
match Some(()) { None => { }, option if { option = None; false } { }, Some(_) => { } // When the previous match failed, the option became `None`. }
In certain cases it is possible for sub-bindings to violate memory safety. Updates to the borrow checker in a future version of Rust may remove this restriction, but for now patterns must be rewritten without sub-bindings.
// Code like this... match Some(5) { ref op_num @ Some(num) => ... None => ... } // After. match Some("hi".to_string()) { Some(ref s) => { let op_string_ref = &Some(&s); ... } None => ... }
The op_string_ref
`op_string_refbinding has type
` binding has type &Option<&String>
`&Option<&String>` in both cases.
No description.
No description.
In an array literal [x; N]
`[x; N],
`, N
`N` is the number of elements in the array. This
number cannot be negative.
The length of an array is part of its type. For this reason, this length must be a compile-time constant.
This error occurs when the compiler was unable to infer the concrete type of a variable. This error can occur for several cases, the most common of which is a mismatch in the expected type that the compiler inferred for a variable's initializing expression, and the actual type explicitly assigned to the variable.
For example:
let x: i32 = "I am not a number!"; // ~~~ ~~~~~~~~~~~~~~~~~~~~ // | | // | initializing expression; // | compiler infers type `&str` // | // type `i32` assigned to variable `x`
Types in type definitions have lifetimes associated with them that represent how long the data stored within them is guaranteed to be live. This lifetime must be as long as the data needs to be alive, and missing the constraint that denotes this will cause this error.
// This won't compile because T is not constrained, meaning the data // stored in it is not guaranteed to last as long as the reference struct Foo<'a, T> { foo: &'a T } // This will compile, because it has the constraint on the type parameter struct Foo<'a, T: 'a> { foo: &'a T }
Types in type definitions have lifetimes associated with them that represent how long the data stored within them is guaranteed to be live. This lifetime must be as long as the data needs to be alive, and missing the constraint that denotes this will cause this error.
// This won't compile because T is not constrained to the static lifetime // the reference needs struct Foo<T> { foo: &'static T } // This will compile, because it has the constraint on the type parameter struct Foo<T: 'static> { foo: &'static T }
No description.
No description.
No description.
No description.
No description.
No description.
User-defined types or type parameters cannot shadow the primitive types. This error indicates you tried to define a type, struct or enum with the same name as an existing primitive type.
See the Types section of the reference for more information about the primitive types:
No description.
No description.
No description.
No description.
The Sized
`Sized` trait is a special trait built-in to the compiler for types with a
constant size known at compile-time. This trait is automatically implemented
for types as needed by the compiler, and it is currently disallowed to
explicitly implement it for a type.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
This error indicates that a binary assignment operator like +=
`+=or
` or ^=
`=` was
applied to the wrong types.
A couple examples of this are as follows:
let mut x: u16 = 5; x ^= true; // error, `^=` cannot be applied to types `u16` and `bool` x += (); // error, `+=` cannot be applied to types `u16` and `()`
Another problem you might be facing is this: suppose you've overloaded the +
`+operator for some type
`
operator for some type Foo
`Fooby implementing the
` by implementing the std::ops::Add
`std::ops::Addtrait for
` trait for
Foo
`Foo, but you find that using
`, but you find that using +=
`+=` does not work, as in this example:
use std::ops::Add; struct Foo(u32); impl Add for Foo { type Output = Foo; fn add(self, rhs: Foo) -> Foo { Foo(self.0 + rhs.0) } } fn main() { let mut x: Foo = Foo(5); x += Foo(7); // error, `+= cannot be applied to types `Foo` and `Foo` }
This is because the binary assignment operators currently do not work off of traits, so it is not possible to overload them. See RFC 953 for a proposal to change this.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.
No description.