Auto merge of #33658 - Manishearth:rollup, r=Manishearth
Rollup of 14 pull requests - Successful merges: #33342, #33393, #33415, #33475, #33517, #33533, #33534, #33565, #33580, #33584, #33585, #33590, #33591, #33598 - Failed merges: #33578
This commit is contained in:
commit
9f58fb776a
26 changed files with 618 additions and 42 deletions
|
@ -525,14 +525,16 @@ impl<I: ExactSizeIterator + ?Sized> ExactSizeIterator for Box<I> {}
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[rustc_paren_sugar]
|
#[rustc_paren_sugar]
|
||||||
#[unstable(feature = "fnbox", reason = "Newly introduced", issue = "28796")]
|
#[unstable(feature = "fnbox",
|
||||||
|
reason = "will be deprecated if and when Box<FnOnce> becomes usable", issue = "28796")]
|
||||||
pub trait FnBox<A> {
|
pub trait FnBox<A> {
|
||||||
type Output;
|
type Output;
|
||||||
|
|
||||||
fn call_box(self: Box<Self>, args: A) -> Self::Output;
|
fn call_box(self: Box<Self>, args: A) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "fnbox", reason = "Newly introduced", issue = "28796")]
|
#[unstable(feature = "fnbox",
|
||||||
|
reason = "will be deprecated if and when Box<FnOnce> becomes usable", issue = "28796")]
|
||||||
impl<A, F> FnBox<A> for F where F: FnOnce<A>
|
impl<A, F> FnBox<A> for F where F: FnOnce<A>
|
||||||
{
|
{
|
||||||
type Output = F::Output;
|
type Output = F::Output;
|
||||||
|
@ -542,7 +544,8 @@ impl<A, F> FnBox<A> for F where F: FnOnce<A>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "fnbox", reason = "Newly introduced", issue = "28796")]
|
#[unstable(feature = "fnbox",
|
||||||
|
reason = "will be deprecated if and when Box<FnOnce> becomes usable", issue = "28796")]
|
||||||
impl<'a, A, R> FnOnce<A> for Box<FnBox<A, Output = R> + 'a> {
|
impl<'a, A, R> FnOnce<A> for Box<FnBox<A, Output = R> + 'a> {
|
||||||
type Output = R;
|
type Output = R;
|
||||||
|
|
||||||
|
@ -551,7 +554,8 @@ impl<'a, A, R> FnOnce<A> for Box<FnBox<A, Output = R> + 'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "fnbox", reason = "Newly introduced", issue = "28796")]
|
#[unstable(feature = "fnbox",
|
||||||
|
reason = "will be deprecated if and when Box<FnOnce> becomes usable", issue = "28796")]
|
||||||
impl<'a, A, R> FnOnce<A> for Box<FnBox<A, Output = R> + Send + 'a> {
|
impl<'a, A, R> FnOnce<A> for Box<FnBox<A, Output = R> + Send + 'a> {
|
||||||
type Output = R;
|
type Output = R;
|
||||||
|
|
||||||
|
|
|
@ -184,7 +184,7 @@ use boxed::Box;
|
||||||
/// let len = story.len();
|
/// let len = story.len();
|
||||||
/// let capacity = story.capacity();
|
/// let capacity = story.capacity();
|
||||||
///
|
///
|
||||||
/// // story has thirteen bytes
|
/// // story has nineteen bytes
|
||||||
/// assert_eq!(19, len);
|
/// assert_eq!(19, len);
|
||||||
///
|
///
|
||||||
/// // Now that we have our parts, we throw the story away.
|
/// // Now that we have our parts, we throw the story away.
|
||||||
|
|
|
@ -142,13 +142,13 @@ pub enum Ordering {
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
Relaxed,
|
Relaxed,
|
||||||
/// When coupled with a store, all previous writes become visible
|
/// When coupled with a store, all previous writes become visible
|
||||||
/// to another thread that performs a load with `Acquire` ordering
|
/// to the other threads that perform a load with `Acquire` ordering
|
||||||
/// on the same value.
|
/// on the same value.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
Release,
|
Release,
|
||||||
/// When coupled with a load, all subsequent loads will see data
|
/// When coupled with a load, all subsequent loads will see data
|
||||||
/// written before a store with `Release` ordering on the same value
|
/// written before a store with `Release` ordering on the same value
|
||||||
/// in another thread.
|
/// in other threads.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
Acquire,
|
Acquire,
|
||||||
/// When coupled with a load, uses `Acquire` ordering, and with a store
|
/// When coupled with a load, uses `Acquire` ordering, and with a store
|
||||||
|
|
|
@ -378,6 +378,53 @@ let c = &i; // still ok!
|
||||||
```
|
```
|
||||||
"##,
|
"##,
|
||||||
|
|
||||||
|
E0500: r##"
|
||||||
|
A borrowed variable was used in another closure. Example of erroneous code:
|
||||||
|
|
||||||
|
```compile_fail
|
||||||
|
fn you_know_nothing(jon_snow: &mut i32) {
|
||||||
|
let nights_watch = || {
|
||||||
|
*jon_snow = 2;
|
||||||
|
};
|
||||||
|
let starks = || {
|
||||||
|
*jon_snow = 3; // error: closure requires unique access to `jon_snow`
|
||||||
|
// but it is already borrowed
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
In here, `jon_snow` is already borrowed by the `nights_watch` closure, so it
|
||||||
|
cannot be borrowed by the `starks` closure at the same time. To fix this issue,
|
||||||
|
you can put the closure in its own scope:
|
||||||
|
|
||||||
|
```
|
||||||
|
fn you_know_nothing(jon_snow: &mut i32) {
|
||||||
|
{
|
||||||
|
let nights_watch = || {
|
||||||
|
*jon_snow = 2;
|
||||||
|
};
|
||||||
|
} // At this point, `jon_snow` is free.
|
||||||
|
let starks = || {
|
||||||
|
*jon_snow = 3;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Or, if the type implements the `Clone` trait, you can clone it between
|
||||||
|
closures:
|
||||||
|
|
||||||
|
```
|
||||||
|
fn you_know_nothing(jon_snow: &mut i32) {
|
||||||
|
let mut jon_copy = jon_snow.clone();
|
||||||
|
let nights_watch = || {
|
||||||
|
jon_copy = 2;
|
||||||
|
};
|
||||||
|
let starks = || {
|
||||||
|
*jon_snow = 3;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
"##,
|
||||||
|
|
||||||
E0501: r##"
|
E0501: r##"
|
||||||
This error indicates that a mutable variable is being used while it is still
|
This error indicates that a mutable variable is being used while it is still
|
||||||
captured by a closure. Because the closure has borrowed the variable, it is not
|
captured by a closure. Because the closure has borrowed the variable, it is not
|
||||||
|
@ -642,6 +689,85 @@ fn print_fancy_ref(fancy_ref: &FancyNum){
|
||||||
```
|
```
|
||||||
"##,
|
"##,
|
||||||
|
|
||||||
|
E0505: r##"
|
||||||
|
A value was moved out while it was still borrowed.
|
||||||
|
Erroneous code example:
|
||||||
|
|
||||||
|
```compile_fail
|
||||||
|
struct Value {}
|
||||||
|
|
||||||
|
fn eat(val: Value) {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = Value{};
|
||||||
|
{
|
||||||
|
let _ref_to_val: &Value = &x;
|
||||||
|
eat(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Here, the function `eat` takes the ownership of `x`. However,
|
||||||
|
`x` cannot be moved because it was borrowed to `_ref_to_val`.
|
||||||
|
To fix that you can do few different things:
|
||||||
|
|
||||||
|
* Try to avoid moving the variable.
|
||||||
|
* Release borrow before move.
|
||||||
|
* Implement the `Copy` trait on the type.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```
|
||||||
|
struct Value {}
|
||||||
|
|
||||||
|
fn eat(val: &Value) {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = Value{};
|
||||||
|
{
|
||||||
|
let _ref_to_val: &Value = &x;
|
||||||
|
eat(&x); // pass by reference, if it's possible
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Or:
|
||||||
|
|
||||||
|
```
|
||||||
|
struct Value {}
|
||||||
|
|
||||||
|
fn eat(val: Value) {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = Value{};
|
||||||
|
{
|
||||||
|
let _ref_to_val: &Value = &x;
|
||||||
|
}
|
||||||
|
eat(x); // release borrow and then move it.
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Or:
|
||||||
|
|
||||||
|
```
|
||||||
|
#[derive(Clone, Copy)] // implement Copy trait
|
||||||
|
struct Value {}
|
||||||
|
|
||||||
|
fn eat(val: Value) {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = Value{};
|
||||||
|
{
|
||||||
|
let _ref_to_val: &Value = &x;
|
||||||
|
eat(x); // it will be copied here.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
You can find more information about borrowing in the rust-book:
|
||||||
|
http://doc.rust-lang.org/stable/book/references-and-borrowing.html
|
||||||
|
"##,
|
||||||
|
|
||||||
E0507: r##"
|
E0507: r##"
|
||||||
You tried to move out of a value which was borrowed. Erroneous code example:
|
You tried to move out of a value which was borrowed. Erroneous code example:
|
||||||
|
|
||||||
|
@ -857,10 +983,8 @@ fn main() {
|
||||||
register_diagnostics! {
|
register_diagnostics! {
|
||||||
E0385, // {} in an aliasable location
|
E0385, // {} in an aliasable location
|
||||||
E0388, // {} in a static location
|
E0388, // {} in a static location
|
||||||
E0500, // closure requires unique access to `..` but .. is already borrowed
|
|
||||||
E0502, // cannot borrow `..`.. as .. because .. is also borrowed as ...
|
E0502, // cannot borrow `..`.. as .. because .. is also borrowed as ...
|
||||||
E0503, // cannot use `..` because it was mutably borrowed
|
E0503, // cannot use `..` because it was mutably borrowed
|
||||||
E0505, // cannot move out of `..` because it is borrowed
|
|
||||||
E0508, // cannot move out of type `..`, a non-copy fixed-size array
|
E0508, // cannot move out of type `..`, a non-copy fixed-size array
|
||||||
E0524, // two closures require unique access to `..` at the same time
|
E0524, // two closures require unique access to `..` at the same time
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,8 +62,6 @@ fn foo(x: Empty) {
|
||||||
However, this won't:
|
However, this won't:
|
||||||
|
|
||||||
```compile_fail
|
```compile_fail
|
||||||
enum Empty {}
|
|
||||||
|
|
||||||
fn foo(x: Option<String>) {
|
fn foo(x: Option<String>) {
|
||||||
match x {
|
match x {
|
||||||
// empty
|
// empty
|
||||||
|
@ -191,7 +189,7 @@ inner `String` to be moved into a variable called `s`.
|
||||||
let x = Some("s".to_string());
|
let x = Some("s".to_string());
|
||||||
|
|
||||||
match x {
|
match x {
|
||||||
op_string @ Some(s) => {},
|
op_string @ Some(s) => {}, // error: cannot bind by-move with sub-bindings
|
||||||
None => {},
|
None => {},
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -288,7 +286,8 @@ struct X { x: (), }
|
||||||
|
|
||||||
let x = Some((X { x: () }, X { x: () }));
|
let x = Some((X { x: () }, X { x: () }));
|
||||||
match x {
|
match x {
|
||||||
Some((y, ref z)) => {},
|
Some((y, ref z)) => {}, // error: cannot bind by-move and by-ref in the
|
||||||
|
// same pattern
|
||||||
None => panic!()
|
None => panic!()
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -574,6 +573,12 @@ be a compile-time constant. Erroneous code example:
|
||||||
let x = [0i32; len]; // error: expected constant integer for repeat count,
|
let x = [0i32; len]; // error: expected constant integer for repeat count,
|
||||||
// found variable
|
// found variable
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Working example:
|
||||||
|
|
||||||
|
```
|
||||||
|
let x = [0i32; 10];
|
||||||
|
```
|
||||||
"##,
|
"##,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,27 @@ name. Example:
|
||||||
```
|
```
|
||||||
"##,
|
"##,
|
||||||
|
|
||||||
|
E0455: r##"
|
||||||
|
Linking with `kind=framework` is only supported when targeting OS X,
|
||||||
|
as frameworks are specific to that operating system.
|
||||||
|
|
||||||
|
Erroneous code example:
|
||||||
|
|
||||||
|
```compile_fail"
|
||||||
|
#[link(name = "FooCoreServices", kind = "framework")] extern {}
|
||||||
|
// OS used to compile is Linux for example
|
||||||
|
```
|
||||||
|
|
||||||
|
To solve this error you can use conditional compilation:
|
||||||
|
|
||||||
|
```
|
||||||
|
#[cfg_attr(target="macos", link(name = "FooCoreServices", kind = "framework"))]
|
||||||
|
extern {}
|
||||||
|
```
|
||||||
|
|
||||||
|
See more: https://doc.rust-lang.org/book/conditional-compilation.html
|
||||||
|
"##,
|
||||||
|
|
||||||
E0458: r##"
|
E0458: r##"
|
||||||
An unknown "kind" was specified for a link attribute. Erroneous code example:
|
An unknown "kind" was specified for a link attribute. Erroneous code example:
|
||||||
|
|
||||||
|
@ -73,7 +94,6 @@ well, and you link to them the same way.
|
||||||
}
|
}
|
||||||
|
|
||||||
register_diagnostics! {
|
register_diagnostics! {
|
||||||
E0455, // native frameworks are only available on OSX targets
|
|
||||||
E0456, // plugin `..` is not available for triple `..`
|
E0456, // plugin `..` is not available for triple `..`
|
||||||
E0457, // plugin `..` only found in rlib format, but must be available...
|
E0457, // plugin `..` only found in rlib format, but must be available...
|
||||||
E0514, // metadata version mismatch
|
E0514, // metadata version mismatch
|
||||||
|
|
|
@ -84,7 +84,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
span: Span,
|
span: Span,
|
||||||
method_name: ast::Name,
|
method_name: ast::Name,
|
||||||
self_ty: ty::Ty<'tcx>,
|
self_ty: ty::Ty<'tcx>,
|
||||||
call_expr_id: ast::NodeId)
|
call_expr_id: ast::NodeId,
|
||||||
|
allow_private: bool)
|
||||||
-> bool
|
-> bool
|
||||||
{
|
{
|
||||||
let mode = probe::Mode::MethodCall;
|
let mode = probe::Mode::MethodCall;
|
||||||
|
@ -93,7 +94,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
Err(NoMatch(..)) => false,
|
Err(NoMatch(..)) => false,
|
||||||
Err(Ambiguity(..)) => true,
|
Err(Ambiguity(..)) => true,
|
||||||
Err(ClosureAmbiguity(..)) => true,
|
Err(ClosureAmbiguity(..)) => true,
|
||||||
Err(PrivateMatch(..)) => true,
|
Err(PrivateMatch(..)) => allow_private,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3053,12 +3053,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
|
|
||||||
if let Some((did, field_ty)) = private_candidate {
|
if let Some((did, field_ty)) = private_candidate {
|
||||||
let struct_path = self.tcx().item_path_str(did);
|
let struct_path = self.tcx().item_path_str(did);
|
||||||
let msg = format!("field `{}` of struct `{}` is private", field.node, struct_path);
|
|
||||||
self.tcx().sess.span_err(expr.span, &msg);
|
|
||||||
self.write_ty(expr.id, field_ty);
|
self.write_ty(expr.id, field_ty);
|
||||||
|
let msg = format!("field `{}` of struct `{}` is private", field.node, struct_path);
|
||||||
|
let mut err = self.tcx().sess.struct_span_err(expr.span, &msg);
|
||||||
|
// Also check if an accessible method exists, which is often what is meant.
|
||||||
|
if self.method_exists(field.span, field.node, expr_t, expr.id, false) {
|
||||||
|
err.note(&format!("a method `{}` also exists, perhaps you wish to call it",
|
||||||
|
field.node));
|
||||||
|
}
|
||||||
|
err.emit();
|
||||||
} else if field.node == keywords::Invalid.name() {
|
} else if field.node == keywords::Invalid.name() {
|
||||||
self.write_error(expr.id);
|
self.write_error(expr.id);
|
||||||
} else if self.method_exists(field.span, field.node, expr_t, expr.id) {
|
} else if self.method_exists(field.span, field.node, expr_t, expr.id, true) {
|
||||||
self.type_error_struct(field.span, |actual| {
|
self.type_error_struct(field.span, |actual| {
|
||||||
format!("attempted to take value of method `{}` on type \
|
format!("attempted to take value of method `{}` on type \
|
||||||
`{}`", field.node, actual)
|
`{}`", field.node, actual)
|
||||||
|
@ -3307,7 +3313,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
let expr_ty = self.instantiate_type(def.def_id(), path);
|
let expr_ty = self.instantiate_type(def.def_id(), path);
|
||||||
self.write_ty(expr.id, expr_ty);
|
self.write_ty(expr.id, expr_ty);
|
||||||
|
|
||||||
self.check_expr_struct_fields(expr_ty, expr.span, variant, fields,
|
self.check_expr_struct_fields(expr_ty, path.span, variant, fields,
|
||||||
base_expr.is_none());
|
base_expr.is_none());
|
||||||
if let &Some(ref base_expr) = base_expr {
|
if let &Some(ref base_expr) = base_expr {
|
||||||
self.check_expr_has_type(base_expr, expr_ty);
|
self.check_expr_has_type(base_expr, expr_ty);
|
||||||
|
|
|
@ -45,8 +45,8 @@ Matching with the wrong number of fields has no sensible interpretation:
|
||||||
|
|
||||||
```compile_fail
|
```compile_fail
|
||||||
enum Fruit {
|
enum Fruit {
|
||||||
Apple(String, String),
|
Fruit::Apple(String, String),
|
||||||
Pear(u32),
|
Fruit::Pear(u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
let x = Fruit::Apple(String::new(), String::new());
|
let x = Fruit::Apple(String::new(), String::new());
|
||||||
|
@ -77,8 +77,8 @@ enum Number {
|
||||||
|
|
||||||
// Assuming x is a Number we can pattern match on its contents.
|
// Assuming x is a Number we can pattern match on its contents.
|
||||||
match x {
|
match x {
|
||||||
Zero(inside) => {},
|
Number::Zero(inside) => {},
|
||||||
One(inside) => {},
|
Number::One(inside) => {},
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -3284,6 +3284,164 @@ impl Baz for Bar { } // Note: This is OK
|
||||||
```
|
```
|
||||||
"##,
|
"##,
|
||||||
|
|
||||||
|
E0374: r##"
|
||||||
|
A struct without a field containing an unsized type cannot implement
|
||||||
|
`CoerceUnsized`. An
|
||||||
|
[unsized type](https://doc.rust-lang.org/book/unsized-types.html)
|
||||||
|
is any type that the compiler doesn't know the length or alignment of at
|
||||||
|
compile time. Any struct containing an unsized type is also unsized.
|
||||||
|
|
||||||
|
Example of erroneous code:
|
||||||
|
|
||||||
|
```compile_fail
|
||||||
|
#![feature(coerce_unsized)]
|
||||||
|
use std::ops::CoerceUnsized;
|
||||||
|
|
||||||
|
struct Foo<T: ?Sized> {
|
||||||
|
a: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
// error: Struct `Foo` has no unsized fields that need `CoerceUnsized`.
|
||||||
|
impl<T, U> CoerceUnsized<Foo<U>> for Foo<T>
|
||||||
|
where T: CoerceUnsized<U> {}
|
||||||
|
```
|
||||||
|
|
||||||
|
`CoerceUnsized` is used to coerce one struct containing an unsized type
|
||||||
|
into another struct containing a different unsized type. If the struct
|
||||||
|
doesn't have any fields of unsized types then you don't need explicit
|
||||||
|
coercion to get the types you want. To fix this you can either
|
||||||
|
not try to implement `CoerceUnsized` or you can add a field that is
|
||||||
|
unsized to the struct.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```
|
||||||
|
#![feature(coerce_unsized)]
|
||||||
|
use std::ops::CoerceUnsized;
|
||||||
|
|
||||||
|
// We don't need to impl `CoerceUnsized` here.
|
||||||
|
struct Foo {
|
||||||
|
a: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
// We add the unsized type field to the struct.
|
||||||
|
struct Bar<T: ?Sized> {
|
||||||
|
a: i32,
|
||||||
|
b: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
// The struct has an unsized field so we can implement
|
||||||
|
// `CoerceUnsized` for it.
|
||||||
|
impl<T, U> CoerceUnsized<Bar<U>> for Bar<T>
|
||||||
|
where T: CoerceUnsized<U> {}
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that `CoerceUnsized` is mainly used by smart pointers like `Box`, `Rc`
|
||||||
|
and `Arc` to be able to mark that they can coerce unsized types that they
|
||||||
|
are pointing at.
|
||||||
|
"##,
|
||||||
|
|
||||||
|
E0375: r##"
|
||||||
|
A struct with more than one field containing an unsized type cannot implement
|
||||||
|
`CoerceUnsized`. This only occurs when you are trying to coerce one of the
|
||||||
|
types in your struct to another type in the struct. In this case we try to
|
||||||
|
impl `CoerceUnsized` from `T` to `U` which are both types that the struct
|
||||||
|
takes. An [unsized type](https://doc.rust-lang.org/book/unsized-types.html)
|
||||||
|
is any type that the compiler doesn't know the length or alignment of at
|
||||||
|
compile time. Any struct containing an unsized type is also unsized.
|
||||||
|
|
||||||
|
Example of erroneous code:
|
||||||
|
|
||||||
|
```compile_fail
|
||||||
|
#![feature(coerce_unsized)]
|
||||||
|
use std::ops::CoerceUnsized;
|
||||||
|
|
||||||
|
struct Foo<T: ?Sized, U: ?Sized> {
|
||||||
|
a: i32,
|
||||||
|
b: T,
|
||||||
|
c: U,
|
||||||
|
}
|
||||||
|
|
||||||
|
// error: Struct `Foo` has more than one unsized field.
|
||||||
|
impl<T, U> CoerceUnsized<Foo<U, T>> for Foo<T, U> {}
|
||||||
|
```
|
||||||
|
|
||||||
|
`CoerceUnsized` only allows for coercion from a structure with a single
|
||||||
|
unsized type field to another struct with a single unsized type field.
|
||||||
|
In fact Rust only allows for a struct to have one unsized type in a struct
|
||||||
|
and that unsized type must be the last field in the struct. So having two
|
||||||
|
unsized types in a single struct is not allowed by the compiler. To fix this
|
||||||
|
use only one field containing an unsized type in the struct and then use
|
||||||
|
multiple structs to manage each unsized type field you need.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```
|
||||||
|
#![feature(coerce_unsized)]
|
||||||
|
use std::ops::CoerceUnsized;
|
||||||
|
|
||||||
|
struct Foo<T: ?Sized> {
|
||||||
|
a: i32,
|
||||||
|
b: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl <T, U> CoerceUnsized<Foo<U>> for Foo<T>
|
||||||
|
where T: CoerceUnsized<U> {}
|
||||||
|
|
||||||
|
fn coerce_foo<T: CoerceUnsized<U>, U>(t: T) -> Foo<U> {
|
||||||
|
Foo { a: 12i32, b: t } // we use coercion to get the `Foo<U>` type we need
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
"##,
|
||||||
|
|
||||||
|
E0376: r##"
|
||||||
|
The type you are trying to impl `CoerceUnsized` for is not a struct.
|
||||||
|
`CoerceUnsized` can only be implemented for a struct. Unsized types are
|
||||||
|
already able to be coerced without an implementation of `CoerceUnsized`
|
||||||
|
whereas a struct containing an unsized type needs to know the unsized type
|
||||||
|
field it's containing is able to be coerced. An
|
||||||
|
[unsized type](https://doc.rust-lang.org/book/unsized-types.html)
|
||||||
|
is any type that the compiler doesn't know the length or alignment of at
|
||||||
|
compile time. Any struct containing an unsized type is also unsized.
|
||||||
|
|
||||||
|
Example of erroneous code:
|
||||||
|
|
||||||
|
```compile_fail
|
||||||
|
#![feature(coerce_unsized)]
|
||||||
|
use std::ops::CoerceUnsized;
|
||||||
|
|
||||||
|
struct Foo<T: ?Sized> {
|
||||||
|
a: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
// error: The type `U` is not a struct
|
||||||
|
impl<T, U> CoerceUnsized<U> for Foo<T> {}
|
||||||
|
```
|
||||||
|
|
||||||
|
The `CoerceUnsized` trait takes a struct type. Make sure the type you are
|
||||||
|
providing to `CoerceUnsized` is a struct with only the last field containing an
|
||||||
|
unsized type.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```
|
||||||
|
#![feature(coerce_unsized)]
|
||||||
|
use std::ops::CoerceUnsized;
|
||||||
|
|
||||||
|
struct Foo<T> {
|
||||||
|
a: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
// The `Foo<U>` is a struct so `CoerceUnsized` can be implemented
|
||||||
|
impl<T, U> CoerceUnsized<Foo<U>> for Foo<T> where T: CoerceUnsized<U> {}
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that in Rust, structs can only contain an unsized type if the field
|
||||||
|
containing the unsized type is the last and only unsized type field in the
|
||||||
|
struct.
|
||||||
|
"##,
|
||||||
|
|
||||||
E0379: r##"
|
E0379: r##"
|
||||||
Trait methods cannot be declared `const` by design. For more information, see
|
Trait methods cannot be declared `const` by design. For more information, see
|
||||||
[RFC 911].
|
[RFC 911].
|
||||||
|
@ -3777,13 +3935,6 @@ register_diagnostics! {
|
||||||
E0320, // recursive overflow during dropck
|
E0320, // recursive overflow during dropck
|
||||||
E0328, // cannot implement Unsize explicitly
|
E0328, // cannot implement Unsize explicitly
|
||||||
// E0372, // coherence not object safe
|
// E0372, // coherence not object safe
|
||||||
E0374, // the trait `CoerceUnsized` may only be implemented for a coercion
|
|
||||||
// between structures with one field being coerced, none found
|
|
||||||
E0375, // the trait `CoerceUnsized` may only be implemented for a coercion
|
|
||||||
// between structures with one field being coerced, but multiple
|
|
||||||
// fields need coercions
|
|
||||||
E0376, // the trait `CoerceUnsized` may only be implemented for a coercion
|
|
||||||
// between structures
|
|
||||||
E0377, // the trait `CoerceUnsized` may only be implemented for a coercion
|
E0377, // the trait `CoerceUnsized` may only be implemented for a coercion
|
||||||
// between structures with the same definition
|
// between structures with the same definition
|
||||||
E0399, // trait items need to be implemented because the associated
|
E0399, // trait items need to be implemented because the associated
|
||||||
|
|
|
@ -452,16 +452,16 @@ pub fn home_dir() -> Option<PathBuf> {
|
||||||
|
|
||||||
/// Returns the path of a temporary directory.
|
/// Returns the path of a temporary directory.
|
||||||
///
|
///
|
||||||
/// On Unix, returns the value of the 'TMPDIR' environment variable if it is
|
/// On Unix, returns the value of the `TMPDIR` environment variable if it is
|
||||||
/// set, otherwise for non-Android it returns '/tmp'. If Android, since there
|
/// set, otherwise for non-Android it returns `/tmp`. If Android, since there
|
||||||
/// is no global temporary folder (it is usually allocated per-app), we return
|
/// is no global temporary folder (it is usually allocated per-app), it returns
|
||||||
/// '/data/local/tmp'.
|
/// `/data/local/tmp`.
|
||||||
///
|
///
|
||||||
/// On Windows, returns the value of, in order, the 'TMP', 'TEMP',
|
/// On Windows, returns the value of, in order, the `TMP`, `TEMP`,
|
||||||
/// 'USERPROFILE' environment variable if any are set and not the empty
|
/// `USERPROFILE` environment variable if any are set and not the empty
|
||||||
/// string. Otherwise, tmpdir returns the path of the Windows directory. This
|
/// string. Otherwise, `temp_dir` returns the path of the Windows directory.
|
||||||
/// behavior is identical to that of [GetTempPath][msdn], which this function
|
/// This behavior is identical to that of [`GetTempPath`][msdn], which this
|
||||||
/// uses internally.
|
/// function uses internally.
|
||||||
///
|
///
|
||||||
/// [msdn]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa364992(v=vs.85).aspx
|
/// [msdn]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa364992(v=vs.85).aspx
|
||||||
///
|
///
|
||||||
|
|
|
@ -218,7 +218,6 @@ impl Once {
|
||||||
/// The closure `f` is yielded a structure which can be used to query the
|
/// The closure `f` is yielded a structure which can be used to query the
|
||||||
/// state of this `Once` (whether initialization has previously panicked or
|
/// state of this `Once` (whether initialization has previously panicked or
|
||||||
/// not).
|
/// not).
|
||||||
/// poisoned or not.
|
|
||||||
#[unstable(feature = "once_poison", issue = "31688")]
|
#[unstable(feature = "once_poison", issue = "31688")]
|
||||||
pub fn call_once_force<F>(&'static self, f: F) where F: FnOnce(&OnceState) {
|
pub fn call_once_force<F>(&'static self, f: F) where F: FnOnce(&OnceState) {
|
||||||
// same as above, just with a different parameter to `call_inner`.
|
// same as above, just with a different parameter to `call_inner`.
|
||||||
|
|
|
@ -76,7 +76,7 @@ pub struct Instant(time::Instant);
|
||||||
/// Distinct from the `Instant` type, this time measurement **is not
|
/// Distinct from the `Instant` type, this time measurement **is not
|
||||||
/// monotonic**. This means that you can save a file to the file system, then
|
/// monotonic**. This means that you can save a file to the file system, then
|
||||||
/// save another file to the file system, **and the second file has a
|
/// save another file to the file system, **and the second file has a
|
||||||
/// `SystemTime` measurement earlier than the second**. In other words, an
|
/// `SystemTime` measurement earlier than the first**. In other words, an
|
||||||
/// operation that happens after another operation in real time may have an
|
/// operation that happens after another operation in real time may have an
|
||||||
/// earlier `SystemTime`!
|
/// earlier `SystemTime`!
|
||||||
///
|
///
|
||||||
|
|
18
src/test/compile-fail/E0001.rs
Normal file
18
src/test/compile-fail/E0001.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let foo = Some(1);
|
||||||
|
match foo {
|
||||||
|
Some(bar) => {/* ... */}
|
||||||
|
None => {/* ... */}
|
||||||
|
_ => {/* ... */} //~ ERROR E0001
|
||||||
|
}
|
||||||
|
}
|
15
src/test/compile-fail/E0002.rs
Normal file
15
src/test/compile-fail/E0002.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = Some(1);
|
||||||
|
|
||||||
|
match x { } //~ ERROR E0002
|
||||||
|
}
|
22
src/test/compile-fail/E0004.rs
Normal file
22
src/test/compile-fail/E0004.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
enum Terminator {
|
||||||
|
HastaLaVistaBaby,
|
||||||
|
TalkToMyHand,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = Terminator::HastaLaVistaBaby;
|
||||||
|
|
||||||
|
match x { //~ ERROR E0004
|
||||||
|
Terminator::TalkToMyHand => {}
|
||||||
|
}
|
||||||
|
}
|
14
src/test/compile-fail/E0005.rs
Normal file
14
src/test/compile-fail/E0005.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = Some(1);
|
||||||
|
let Some(y) = x; //~ ERROR E0005
|
||||||
|
}
|
18
src/test/compile-fail/E0007.rs
Normal file
18
src/test/compile-fail/E0007.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = Some("s".to_string());
|
||||||
|
match x {
|
||||||
|
op_string @ Some(s) => {}, //~ ERROR E0007
|
||||||
|
//~| ERROR E0303
|
||||||
|
None => {},
|
||||||
|
}
|
||||||
|
}
|
16
src/test/compile-fail/E0008.rs
Normal file
16
src/test/compile-fail/E0008.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
match Some("hi".to_string()) {
|
||||||
|
Some(s) if s.len() == 0 => {}, //~ ERROR E0008
|
||||||
|
_ => {},
|
||||||
|
}
|
||||||
|
}
|
18
src/test/compile-fail/E0009.rs
Normal file
18
src/test/compile-fail/E0009.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
struct X { x: (), }
|
||||||
|
let x = Some((X { x: () }, X { x: () }));
|
||||||
|
match x {
|
||||||
|
Some((y, ref z)) => {}, //~ ERROR E0009
|
||||||
|
None => panic!()
|
||||||
|
}
|
||||||
|
}
|
15
src/test/compile-fail/E0010.rs
Normal file
15
src/test/compile-fail/E0010.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![feature(box_syntax)]
|
||||||
|
|
||||||
|
const CON : Box<i32> = box 0; //~ ERROR E0010
|
||||||
|
|
||||||
|
fn main() {}
|
22
src/test/compile-fail/E0017.rs
Normal file
22
src/test/compile-fail/E0017.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
static X: i32 = 1;
|
||||||
|
const C: i32 = 2;
|
||||||
|
|
||||||
|
const CR: &'static mut i32 = &mut C; //~ ERROR E0017
|
||||||
|
//~| ERROR E0017
|
||||||
|
static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
|
||||||
|
//~| ERROR E0017
|
||||||
|
//~| ERROR E0388
|
||||||
|
static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0017
|
||||||
|
//~| ERROR E0017
|
||||||
|
|
||||||
|
fn main() {}
|
22
src/test/compile-fail/E0023.rs
Normal file
22
src/test/compile-fail/E0023.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
enum Fruit {
|
||||||
|
Apple(String, String),
|
||||||
|
Pear(u32),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = Fruit::Apple(String::new(), String::new());
|
||||||
|
match x {
|
||||||
|
Fruit::Apple(a) => {}, //~ ERROR E0023
|
||||||
|
Fruit::Apple(a, b, c) => {}, //~ ERROR E0023
|
||||||
|
}
|
||||||
|
}
|
22
src/test/compile-fail/E0024.rs
Normal file
22
src/test/compile-fail/E0024.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
enum Number {
|
||||||
|
Zero,
|
||||||
|
One(u32)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = Number::Zero;
|
||||||
|
match x {
|
||||||
|
Number::Zero(inside) => {}, //~ ERROR E0024
|
||||||
|
Number::One(inside) => {},
|
||||||
|
}
|
||||||
|
}
|
19
src/test/compile-fail/E0025.rs
Normal file
19
src/test/compile-fail/E0025.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
struct Foo {
|
||||||
|
a: u8,
|
||||||
|
b: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = Foo { a:1, b:2 };
|
||||||
|
let Foo { a: x, a: y, b: 0 } = x; //~ ERROR E0025
|
||||||
|
}
|
21
src/test/compile-fail/E0026.rs
Normal file
21
src/test/compile-fail/E0026.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
struct Thing {
|
||||||
|
x: u32,
|
||||||
|
y: u32
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let thing = Thing { x: 0, y: 0 };
|
||||||
|
match thing {
|
||||||
|
Thing { x, y, z } => {} //~ ERROR E0026
|
||||||
|
}
|
||||||
|
}
|
24
src/test/compile-fail/issue-26472.rs
Normal file
24
src/test/compile-fail/issue-26472.rs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
mod sub {
|
||||||
|
pub struct S { len: usize }
|
||||||
|
impl S {
|
||||||
|
pub fn new() -> S { S { len: 0 } }
|
||||||
|
pub fn len(&self) -> usize { self.len }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let s = sub::S::new();
|
||||||
|
let v = s.len;
|
||||||
|
//~^ ERROR field `len` of struct `sub::S` is private
|
||||||
|
//~| NOTE a method `len` also exists, perhaps you wish to call it
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue