Auto merge of #47843 - estebank:teach, r=nikomatsakis

Add `-Zteach` documentation

Add extra inline documentation to E0019, E0016, E0013, E0396, E0017,
E0018, E0010, E0022, E0030, E0029, E0033, E0026 and E0027.

Follow up to #47652.
This commit is contained in:
bors 2018-02-12 09:38:40 +00:00
commit 16362c737f
486 changed files with 3255 additions and 55 deletions

View File

@ -175,6 +175,10 @@ fn configure_main(this: &mut EntryContext) {
err.emit();
this.session.abort_if_errors();
} else {
if this.session.teach(&err.get_code().unwrap()) {
err.note("If you don't know the basics of Rust, you can go look to the Rust Book \
to get started: https://doc.rust-lang.org/book/");
}
err.emit();
}
}

View File

@ -170,8 +170,20 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
fn not_const(&mut self) {
self.add(Qualif::NOT_CONST);
if self.mode != Mode::Fn {
span_err!(self.tcx.sess, self.span, E0019,
"{} contains unimplemented expression type", self.mode);
let mut err = struct_span_err!(
self.tcx.sess,
self.span,
E0019,
"{} contains unimplemented expression type",
self.mode
);
if self.tcx.sess.teach(&err.get_code().unwrap()) {
err.note("A function call isn't allowed in the const's initialization expression \
because the expression's value must be known at compile-time.");
err.note("Remember: you can't use a function call inside a const's initialization \
expression! However, you can use it anywhere else.");
}
err.emit();
}
}
@ -179,9 +191,19 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
fn statement_like(&mut self) {
self.add(Qualif::NOT_CONST);
if self.mode != Mode::Fn {
span_err!(self.tcx.sess, self.span, E0016,
"blocks in {}s are limited to items and tail expressions",
self.mode);
let mut err = struct_span_err!(
self.tcx.sess,
self.span,
E0016,
"blocks in {}s are limited to items and tail expressions",
self.mode
);
if self.tcx.sess.teach(&err.get_code().unwrap()) {
err.note("Blocks in constants may only contain items (such as constant, function \
definition, etc...) and a tail expression.");
err.help("To avoid it, you have to replace the non-item object.");
}
err.emit();
}
}
@ -475,9 +497,19 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
}
if self.mode == Mode::Const || self.mode == Mode::ConstFn {
span_err!(self.tcx.sess, self.span, E0013,
"{}s cannot refer to statics, use \
a constant instead", self.mode);
let mut err = struct_span_err!(self.tcx.sess, self.span, E0013,
"{}s cannot refer to statics, use \
a constant instead", self.mode);
if self.tcx.sess.teach(&err.get_code().unwrap()) {
err.note(
"Static and const variables can refer to other const variables. But a \
const variable cannot refer to a static variable."
);
err.help(
"To fix this, the value can be extracted as a const and then used."
);
}
err.emit()
}
}
Place::Projection(ref proj) => {
@ -498,13 +530,25 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
if let ty::TyRawPtr(_) = base_ty.sty {
this.add(Qualif::NOT_CONST);
if this.mode != Mode::Fn {
struct_span_err!(this.tcx.sess,
this.span, E0396,
let mut err = struct_span_err!(
this.tcx.sess,
this.span,
E0396,
"raw pointers cannot be dereferenced in {}s",
this.mode)
.span_label(this.span,
"dereference of raw pointer in constant")
.emit();
this.mode
);
err.span_label(this.span,
"dereference of raw pointer in constant");
if this.tcx.sess.teach(&err.get_code().unwrap()) {
err.note(
"The value behind a raw pointer can't be determined \
at compile-time (or even link-time), which means it \
can't be used in a constant expression."
);
err.help("A possible fix is to dereference your pointer \
at some point in run-time.");
}
err.emit();
}
}
}
@ -623,12 +667,22 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
if !allow {
self.add(Qualif::NOT_CONST);
if self.mode != Mode::Fn {
struct_span_err!(self.tcx.sess, self.span, E0017,
"references in {}s may only refer \
to immutable values", self.mode)
.span_label(self.span, format!("{}s require immutable values",
self.mode))
.emit();
let mut err = struct_span_err!(self.tcx.sess, self.span, E0017,
"references in {}s may only refer \
to immutable values", self.mode);
err.span_label(self.span, format!("{}s require immutable values",
self.mode));
if self.tcx.sess.teach(&err.get_code().unwrap()) {
err.note("References in statics and constants may only refer to \
immutable values.\n\n\
Statics are shared everywhere, and if they refer to \
mutable data one might violate memory safety since \
holding multiple mutable references to shared data is \
not allowed.\n\n\
If you really want global mutable state, try using \
static mut or a global UnsafeCell.");
}
err.emit();
}
}
} else {
@ -669,9 +723,42 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
(CastTy::FnPtr, CastTy::Int(_)) => {
self.add(Qualif::NOT_CONST);
if self.mode != Mode::Fn {
span_err!(self.tcx.sess, self.span, E0018,
"raw pointers cannot be cast to integers in {}s",
self.mode);
let mut err = struct_span_err!(
self.tcx.sess,
self.span,
E0018,
"raw pointers cannot be cast to integers in {}s",
self.mode
);
if self.tcx.sess.teach(&err.get_code().unwrap()) {
err.note("\
The value of static and constant integers must be known at compile time. You can't cast a pointer \
to an integer because the address of a pointer can vary.
For example, if you write:
```
static MY_STATIC: u32 = 42;
static MY_STATIC_ADDR: usize = &MY_STATIC as *const _ as usize;
static WHAT: usize = (MY_STATIC_ADDR^17) + MY_STATIC_ADDR;
```
Then `MY_STATIC_ADDR` would contain the address of `MY_STATIC`. However, the address can change \
when the program is linked, as well as change between different executions due to ASLR, and many \
linkers would not be able to calculate the value of `WHAT`.
On the other hand, static and constant pointers can point either to a known numeric address or to \
the address of a symbol.
```
static MY_STATIC: u32 = 42;
static MY_STATIC_ADDR: &'static u32 = &MY_STATIC;
const CONST_ADDR: *const u8 = 0x5f3759df as *const u8;
```
This does not pose a problem by itself because they can't be accessed directly.");
}
err.emit();
}
}
_ => {}
@ -702,10 +789,18 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
Rvalue::NullaryOp(NullOp::Box, _) => {
self.add(Qualif::NOT_CONST);
if self.mode != Mode::Fn {
struct_span_err!(self.tcx.sess, self.span, E0010,
"allocations are not allowed in {}s", self.mode)
.span_label(self.span, format!("allocation not allowed in {}s", self.mode))
.emit();
let mut err = struct_span_err!(self.tcx.sess, self.span, E0010,
"allocations are not allowed in {}s", self.mode);
err.span_label(self.span, format!("allocation not allowed in {}s", self.mode));
if self.tcx.sess.teach(&err.get_code().unwrap()) {
err.note(
"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."
);
}
err.emit();
}
}
@ -931,9 +1026,22 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
// Avoid a generic error for other uses of arguments.
if self.qualif.intersects(Qualif::FN_ARGUMENT) {
let decl = &self.mir.local_decls[index];
span_err!(self.tcx.sess, decl.source_info.span, E0022,
"arguments of constant functions can only \
be immutable by-value bindings");
let mut err = struct_span_err!(
self.tcx.sess,
decl.source_info.span,
E0022,
"arguments of constant functions can only be immutable by-value bindings"
);
if self.tcx.sess.teach(&err.get_code().unwrap()) {
err.note("Constant functions are not allowed to mutate anything. Thus, \
binding to an argument with a mutable pattern is not allowed.");
err.note("Remove any mutable bindings from the argument list to fix this \
error. In case you need to mutate the argument, try lazily \
initializing a global variable instead of using a const fn, or \
refactoring the code to a functional style to avoid mutation if \
possible.");
}
err.emit();
return;
}
}

View File

@ -237,10 +237,20 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> {
Ok(Ordering::Less) |
Ok(Ordering::Equal) => {}
Ok(Ordering::Greater) => {
struct_span_err!(self.tcx.sess, start.span, E0030,
"lower range bound must be less than or equal to upper")
.span_label(start.span, "lower bound larger than upper bound")
.emit();
let mut err = struct_span_err!(
self.tcx.sess,
start.span,
E0030,
"lower range bound must be less than or equal to upper"
);
err.span_label(start.span, "lower bound larger than upper bound");
if self.tcx.sess.teach(&err.get_code().unwrap()) {
err.note("When matching against a range, the compiler verifies that \
the range is non-empty. Range patterns include both \
end-points, so this is equivalent to requiring the start of \
the range to be less than or equal to the end of the range.");
}
err.emit();
}
Err(ErrorReported) => {}
}

View File

@ -214,12 +214,25 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
end.span
};
struct_span_err!(tcx.sess, span, E0029,
"only char and numeric types are allowed in range patterns")
.span_label(span, "ranges require char or numeric types")
.note(&format!("start type: {}", self.ty_to_string(lhs_ty)))
.note(&format!("end type: {}", self.ty_to_string(rhs_ty)))
.emit();
let mut err = struct_span_err!(
tcx.sess,
span,
E0029,
"only char and numeric types are allowed in range patterns"
);
err.span_label(span, "ranges require char or numeric types");
err.note(&format!("start type: {}", self.ty_to_string(lhs_ty)));
err.note(&format!("end type: {}", self.ty_to_string(rhs_ty)));
if tcx.sess.teach(&err.get_code().unwrap()) {
err.note(
"In a match expression, only numbers and characters can be matched \
against a range. This is because the compiler checks that the range \
is non-empty at compile-time, and is unable to evaluate arbitrary \
comparison functions. If you want to capture values of an orderable \
type between two end-points, you can use a guard."
);
}
err.emit();
return;
}
@ -505,10 +518,25 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// This is "x = SomeTrait" being reduced from
// "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error.
let type_str = self.ty_to_string(expected);
struct_span_err!(self.tcx.sess, span, E0033,
"type `{}` cannot be dereferenced", type_str)
.span_label(span, format!("type `{}` cannot be dereferenced", type_str))
.emit();
let mut err = struct_span_err!(
self.tcx.sess,
span,
E0033,
"type `{}` cannot be dereferenced",
type_str
);
err.span_label(span, format!("type `{}` cannot be dereferenced", type_str));
if self.tcx.sess.teach(&err.get_code().unwrap()) {
err.note("\
This error indicates that a pointer to a trait type cannot be implicitly dereferenced by a \
pattern. Every trait defines a type, but because the size of trait implementors isn't fixed, \
this type has no compile-time size. Therefore, all accesses to trait types must be through \
pointers. If you encounter this error you should try to avoid dereferencing the pointer.
You can read more about trait objects in the Trait Objects section of the Reference: \
https://doc.rust-lang.org/reference/types.html#trait-objects");
}
err.emit();
return false
}
}
@ -881,17 +909,33 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
self.field_ty(span, f, substs)
})
.unwrap_or_else(|| {
struct_span_err!(tcx.sess, span, E0026,
"{} `{}` does not have a field named `{}`",
kind_name,
tcx.item_path_str(variant.did),
field.name)
.span_label(span,
format!("{} `{}` does not have field `{}`",
kind_name,
tcx.item_path_str(variant.did),
field.name))
.emit();
let mut err = struct_span_err!(
tcx.sess,
span,
E0026,
"{} `{}` does not have a field named `{}`",
kind_name,
tcx.item_path_str(variant.did),
field.name
);
err.span_label(span,
format!("{} `{}` does not have field `{}`",
kind_name,
tcx.item_path_str(variant.did),
field.name));
if tcx.sess.teach(&err.get_code().unwrap()) {
err.note(
"This error indicates that a struct pattern attempted to \
extract a non-existent field from a struct. Struct fields \
are identified by the name used before the colon : so struct \
patterns should resemble the declaration of the struct type \
being matched.\n\n\
If you are using shorthand field patterns but want to refer \
to the struct field by a different name, you should rename \
it explicitly."
);
}
err.emit();
tcx.types.err
})
@ -927,6 +971,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
if variant.ctor_kind == CtorKind::Fn {
diag.note("trying to match a tuple variant with a struct variant pattern");
}
if tcx.sess.teach(&diag.get_code().unwrap()) {
diag.note(
"This error indicates that a pattern for a struct fails to specify a \
sub-pattern for every one of the struct's fields. Ensure that each field \
from the struct's definition is mentioned in the pattern, or use `..` to \
ignore unwanted fields."
);
}
diag.emit();
}
}

View File

@ -0,0 +1,14 @@
error: unreachable pattern
--> $DIR/E0001.rs:18:9
|
18 | _ => {/* ... */} //~ ERROR unreachable pattern
| ^
|
note: lint level defined here
--> $DIR/E0001.rs:11:9
|
11 | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error

View File

@ -0,0 +1,14 @@
error[E0004]: non-exhaustive patterns: type std::option::Option<i32> is non-empty
--> $DIR/E0004-2.rs:14:11
|
14 | match x { } //~ ERROR E0004
| ^
|
help: Please ensure that all possible cases are being handled; possibly adding wildcards or more match arms.
--> $DIR/E0004-2.rs:14:11
|
14 | match x { } //~ ERROR E0004
| ^
error: aborting due to previous error

View File

@ -0,0 +1,8 @@
error[E0004]: non-exhaustive patterns: `HastaLaVistaBaby` not covered
--> $DIR/E0004.rs:19:11
|
19 | match x { //~ ERROR E0004
| ^ pattern `HastaLaVistaBaby` not covered
error: aborting due to previous error

View File

@ -0,0 +1,8 @@
error[E0005]: refutable pattern in local binding: `None` not covered
--> $DIR/E0005.rs:13:9
|
13 | let Some(y) = x; //~ ERROR E0005
| ^^^^^^^ pattern `None` not covered
error: aborting due to previous error

View File

@ -0,0 +1,14 @@
error[E0007]: cannot bind by-move with sub-bindings
--> $DIR/E0007.rs:14:9
|
14 | op_string @ Some(s) => {},
| ^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it
error[E0303]: pattern bindings are not allowed after an `@`
--> $DIR/E0007.rs:14:26
|
14 | op_string @ Some(s) => {},
| ^ not allowed after `@`
error: aborting due to 2 previous errors

View File

@ -0,0 +1,8 @@
error[E0008]: cannot bind by-move into a pattern guard
--> $DIR/E0008.rs:13:14
|
13 | Some(s) if s.len() == 0 => {},
| ^ moves value into pattern guard
error: aborting due to previous error

View File

@ -0,0 +1,10 @@
error[E0009]: cannot bind by-move and by-ref in the same pattern
--> $DIR/E0009.rs:15:15
|
15 | Some((y, ref z)) => {},
| ^ ----- both by-ref and by-move used
| |
| by-move pattern here
error: aborting due to previous error

View 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.
// compile-flags: -Z teach
#![feature(box_syntax)]
#![allow(warnings)]
const CON : Box<i32> = box 0; //~ ERROR E0010
fn main() {}

View File

@ -0,0 +1,10 @@
error[E0010]: allocations are not allowed in constants
--> $DIR/E0010-teach.rs:16:24
|
16 | const CON : Box<i32> = box 0; //~ ERROR E0010
| ^^^^^ allocation not allowed in constants
|
= note: 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.
error: aborting due to previous error

View File

@ -0,0 +1,8 @@
error[E0010]: allocations are not allowed in constants
--> $DIR/E0010.rs:14:24
|
14 | const CON : Box<i32> = box 0; //~ ERROR E0010
| ^^^^^ allocation not allowed in constants
error: aborting due to previous error

View File

@ -0,0 +1,26 @@
error[E0017]: references in constants may only refer to immutable values
--> $DIR/E0017.rs:14:30
|
14 | const CR: &'static mut i32 = &mut C; //~ ERROR E0017
| ^^^^^^ constants require immutable values
error[E0017]: references in statics may only refer to immutable values
--> $DIR/E0017.rs:15:39
|
15 | static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
| ^^^^^^ statics require immutable values
error[E0596]: cannot borrow immutable static item as mutable
--> $DIR/E0017.rs:15:44
|
15 | static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
| ^
error[E0017]: references in statics may only refer to immutable values
--> $DIR/E0017.rs:17:38
|
17 | static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0017
| ^^^^^^ statics require immutable values
error: aborting due to 4 previous errors

View File

@ -0,0 +1,20 @@
error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields
--> $DIR/E0023.rs:20:9
|
20 | Fruit::Apple(a) => {}, //~ ERROR E0023
| ^^^^^^^^^^^^^^^ expected 2 fields, found 1
error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields
--> $DIR/E0023.rs:21:9
|
21 | Fruit::Apple(a, b, c) => {}, //~ ERROR E0023
| ^^^^^^^^^^^^^^^^^^^^^ expected 2 fields, found 3
error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field
--> $DIR/E0023.rs:22:9
|
22 | Fruit::Pear(1, 2) => {}, //~ ERROR E0023
| ^^^^^^^^^^^^^^^^^ expected 1 field, found 2
error: aborting due to 3 previous errors

View File

@ -0,0 +1,10 @@
error[E0025]: field `a` bound multiple times in the pattern
--> $DIR/E0025.rs:18:21
|
18 | let Foo { a: x, a: y, b: 0 } = x;
| ---- ^^^^ multiple uses of `a` in pattern
| |
| first use of `a`
error: aborting due to previous error

View 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.
// compile-flags: -Z teach
struct Thing {
x: u32,
y: u32
}
fn main() {
let thing = Thing { x: 0, y: 0 };
match thing {
Thing { x, y, z } => {}
//~^ ERROR struct `Thing` does not have a field named `z` [E0026]
}
}

View File

@ -0,0 +1,12 @@
error[E0026]: struct `Thing` does not have a field named `z`
--> $DIR/E0026-teach.rs:21:23
|
21 | Thing { x, y, z } => {}
| ^ struct `Thing` does not have field `z`
|
= note: This error indicates that a struct pattern attempted to extract a non-existent field from a struct. Struct fields are identified by the name used before the colon : so struct patterns should resemble the declaration of the struct type being matched.
If you are using shorthand field patterns but want to refer to the struct field by a different name, you should rename it explicitly.
error: aborting due to previous error

View File

@ -0,0 +1,8 @@
error[E0026]: struct `Thing` does not have a field named `z`
--> $DIR/E0026.rs:19:23
|
19 | Thing { x, y, z } => {}
| ^ struct `Thing` does not have field `z`
error: aborting due to previous error

View File

@ -0,0 +1,25 @@
// 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.
// compile-flags: -Z teach
struct Dog {
name: String,
age: u32,
}
fn main() {
let d = Dog { name: "Rusty".to_string(), age: 8 };
match d {
Dog { age: x } => {}
//~^ ERROR pattern does not mention field `name`
}
}

View File

@ -0,0 +1,10 @@
error[E0027]: pattern does not mention field `name`
--> $DIR/E0027-teach.rs:22:9
|
22 | Dog { age: x } => {}
| ^^^^^^^^^^^^^^ missing field `name`
|
= note: This error indicates that a pattern for a struct fails to specify a sub-pattern for every one of the struct's fields. Ensure that each field from the struct's definition is mentioned in the pattern, or use `..` to ignore unwanted fields.
error: aborting due to previous error

View File

@ -0,0 +1,8 @@
error[E0027]: pattern does not mention field `name`
--> $DIR/E0027.rs:20:9
|
20 | Dog { age: x } => {}
| ^^^^^^^^^^^^^^ missing field `name`
error: aborting due to previous error

View 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.
// compile-flags: -Z teach
fn main() {
let s = "hoho";
match s {
"hello" ... "world" => {}
//~^ ERROR only char and numeric types are allowed in range patterns
//~| ERROR non-reference pattern used to match a reference
_ => {}
}
}

View File

@ -0,0 +1,20 @@
error[E0658]: non-reference pattern used to match a reference (see issue #42640)
--> $DIR/E0029-teach.rs:17:9
|
17 | "hello" ... "world" => {}
| ^^^^^^^^^^^^^^^^^^^ help: consider using a reference: `&"hello" ... "world"`
|
= help: add #![feature(match_default_bindings)] to the crate attributes to enable
error[E0029]: only char and numeric types are allowed in range patterns
--> $DIR/E0029-teach.rs:17:9
|
17 | "hello" ... "world" => {}
| ^^^^^^^^^^^^^^^^^^^ ranges require char or numeric types
|
= note: start type: &'static str
= note: end type: &'static str
= note: In a match expression, only numbers and characters can be matched against a range. This is because the compiler checks that the range is non-empty at compile-time, and is unable to evaluate arbitrary comparison functions. If you want to capture values of an orderable type between two end-points, you can use a guard.
error: aborting due to 2 previous errors

View File

@ -0,0 +1,19 @@
error[E0658]: non-reference pattern used to match a reference (see issue #42640)
--> $DIR/E0029.rs:15:9
|
15 | "hello" ... "world" => {}
| ^^^^^^^^^^^^^^^^^^^ help: consider using a reference: `&"hello" ... "world"`
|
= help: add #![feature(match_default_bindings)] to the crate attributes to enable
error[E0029]: only char and numeric types are allowed in range patterns
--> $DIR/E0029.rs:15:9
|
15 | "hello" ... "world" => {}
| ^^^^^^^^^^^^^^^^^^^ ranges require char or numeric types
|
= note: start type: &'static str
= note: end type: &'static str
error: aborting due to 2 previous errors

View 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.
// compile-flags: -Z teach
fn main() {
match 5u32 {
1000 ... 5 => {}
//~^ ERROR lower range bound must be less than or equal to upper
}
}

View File

@ -0,0 +1,10 @@
error[E0030]: lower range bound must be less than or equal to upper
--> $DIR/E0030-teach.rs:15:9
|
15 | 1000 ... 5 => {}
| ^^^^ lower bound larger than upper bound
|
= note: When matching against a range, the compiler verifies that the range is non-empty. Range patterns include both end-points, so this is equivalent to requiring the start of the range to be less than or equal to the end of the range.
error: aborting due to previous error

View File

@ -0,0 +1,8 @@
error[E0030]: lower range bound must be less than or equal to upper
--> $DIR/E0030.rs:14:9
|
14 | 1000 ... 5 => {}
| ^^^^ lower bound larger than upper bound
error: aborting due to previous error

View File

@ -0,0 +1,25 @@
// 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.
// compile-flags: -Z teach
trait SomeTrait {
fn foo();
}
fn main() {
let trait_obj: &SomeTrait = SomeTrait;
//~^ ERROR expected value, found trait `SomeTrait`
//~| ERROR E0038
//~| method `foo` has no receiver
let &invalid = trait_obj;
//~^ ERROR E0033
}

View File

@ -0,0 +1,26 @@
error[E0423]: expected value, found trait `SomeTrait`
--> $DIR/E0033-teach.rs:18:33
|
18 | let trait_obj: &SomeTrait = SomeTrait;
| ^^^^^^^^^ not a value
error[E0038]: the trait `SomeTrait` cannot be made into an object
--> $DIR/E0033-teach.rs:18:20
|
18 | let trait_obj: &SomeTrait = SomeTrait;
| ^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object
|
= note: method `foo` has no receiver
error[E0033]: type `&SomeTrait` cannot be dereferenced
--> $DIR/E0033-teach.rs:23:9
|
23 | let &invalid = trait_obj;
| ^^^^^^^^ type `&SomeTrait` cannot be dereferenced
|
= note: This error indicates that a pointer to a trait type cannot be implicitly dereferenced by a pattern. Every trait defines a type, but because the size of trait implementors isn't fixed, this type has no compile-time size. Therefore, all accesses to trait types must be through pointers. If you encounter this error you should try to avoid dereferencing the pointer.
You can read more about trait objects in the Trait Objects section of the Reference: https://doc.rust-lang.org/reference/types.html#trait-objects
error: aborting due to 3 previous errors

View File

@ -0,0 +1,22 @@
error[E0423]: expected value, found trait `SomeTrait`
--> $DIR/E0033.rs:16:33
|
16 | let trait_obj: &SomeTrait = SomeTrait;
| ^^^^^^^^^ not a value
error[E0038]: the trait `SomeTrait` cannot be made into an object
--> $DIR/E0033.rs:16:20
|
16 | let trait_obj: &SomeTrait = SomeTrait;
| ^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object
|
= note: method `foo` has no receiver
error[E0033]: type `&SomeTrait` cannot be dereferenced
--> $DIR/E0033.rs:21:9
|
21 | let &invalid = trait_obj;
| ^^^^^^^^ type `&SomeTrait` cannot be dereferenced
error: aborting due to 3 previous errors

View File

@ -0,0 +1,19 @@
error[E0034]: multiple applicable items in scope
--> $DIR/E0034.rs:30:5
|
30 | Test::foo() //~ ERROR multiple applicable items in scope
| ^^^^^^^^^ multiple `foo` found
|
note: candidate #1 is defined in an impl of the trait `Trait1` for the type `Test`
--> $DIR/E0034.rs:22:5
|
22 | fn foo() {}
| ^^^^^^^^
note: candidate #2 is defined in an impl of the trait `Trait2` for the type `Test`
--> $DIR/E0034.rs:26:5
|
26 | fn foo() {}
| ^^^^^^^^
error: aborting due to previous error

View File

@ -0,0 +1,10 @@
error[E0038]: the trait `Trait` cannot be made into an object
--> $DIR/E0038.rs:15:1
|
15 | fn call_foo(x: Box<Trait>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` cannot be made into an object
|
= note: method `foo` references the `Self` type in its arguments or return type
error: aborting due to previous error

View File

@ -0,0 +1,8 @@
error[E0040]: explicit use of destructor method
--> $DIR/E0040.rs:23:7
|
23 | x.drop();
| ^^^^ explicit destructor calls not allowed
error: aborting due to previous error

View File

@ -0,0 +1,14 @@
error[E0044]: foreign items may not have type parameters
--> $DIR/E0044.rs:11:10
|
11 | extern { fn some_func<T>(x: T); } //~ ERROR E0044
| ^^^^^^^^^^^^^^^^^^^^^^
|
help: consider using specialization instead of type parameters
--> $DIR/E0044.rs:11:10
|
11 | extern { fn some_func<T>(x: T); } //~ ERROR E0044
| ^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error

View File

@ -0,0 +1,8 @@
error[E0045]: variadic function must have C or cdecl calling convention
--> $DIR/E0045.rs:11:17
|
11 | extern "Rust" { fn foo(x: u8, ...); } //~ ERROR E0045
| ^^^^^^^^^^^^^^^^^^^ variadics require C or cdecl calling convention
error: aborting due to previous error

View File

@ -0,0 +1,11 @@
error[E0049]: method `foo` has 0 type parameters but its trait declaration has 1 type parameter
--> $DIR/E0049.rs:18:5
|
12 | fn foo<T: Default>(x: T) -> Self;
| --------------------------------- expected 1 type parameter
...
18 | fn foo(x: bool) -> Self { Bar } //~ ERROR E0049
| ^^^^^^^^^^^^^^^^^^^^^^^ found 0 type parameters
error: aborting due to previous error

View File

@ -0,0 +1,29 @@
error[E0050]: method `foo` has 1 parameter but the declaration in trait `Foo::foo` has 2
--> $DIR/E0050.rs:20:12
|
12 | fn foo(&self, x: u8) -> bool;
| -- trait requires 2 parameters
...
20 | fn foo(&self) -> bool { true } //~ ERROR E0050
| ^^^^^ expected 2 parameters, found 1
error[E0050]: method `bar` has 1 parameter but the declaration in trait `Foo::bar` has 4
--> $DIR/E0050.rs:21:12
|
13 | fn bar(&self, x: u8, y: u8, z: u8);
| -- trait requires 4 parameters
...
21 | fn bar(&self) { } //~ ERROR E0050
| ^^^^^ expected 4 parameters, found 1
error[E0050]: method `less` has 4 parameters but the declaration in trait `Foo::less` has 1
--> $DIR/E0050.rs:22:37
|
14 | fn less(&self);
| ----- trait requires 1 parameter
...
22 | fn less(&self, x: u8, y: u8, z: u8) { } //~ ERROR E0050
| ^^ expected 1 parameter, found 4
error: aborting due to 3 previous errors

View File

@ -0,0 +1,10 @@
error[E0054]: cannot cast as `bool`
--> $DIR/E0054.rs:13:24
|
13 | let x_is_nonzero = x as bool; //~ ERROR E0054
| ^^^^^^^^^ unsupported cast
|
= help: compare with zero instead
error: aborting due to previous error

View File

@ -0,0 +1,10 @@
error[E0055]: reached the recursion limit while auto-dereferencing Foo
--> $DIR/E0055.rs:21:13
|
21 | ref_foo.foo();
| ^^^ deref recursion limit reached
|
= help: consider adding a `#![recursion_limit="4"]` attribute to your crate
error: aborting due to previous error

View File

@ -0,0 +1,14 @@
error[E0057]: this function takes 1 parameter but 0 parameters were supplied
--> $DIR/E0057.rs:13:13
|
13 | let a = f(); //~ ERROR E0057
| ^^^ expected 1 parameter
error[E0057]: this function takes 1 parameter but 2 parameters were supplied
--> $DIR/E0057.rs:15:13
|
15 | let c = f(2, 3); //~ ERROR E0057
| ^^^^^^^ expected 1 parameter
error: aborting due to 2 previous errors

View File

@ -0,0 +1,8 @@
error[E0059]: cannot use call notation; the first type parameter for the function trait is neither a tuple nor unit
--> $DIR/E0059.rs:13:41
|
13 | fn foo<F: Fn<i32>>(f: F) -> F::Output { f(3) } //~ ERROR E0059
| ^^^^
error: aborting due to previous error

View File

@ -0,0 +1,11 @@
error[E0060]: this function takes at least 1 parameter but 0 parameters were supplied
--> $DIR/E0060.rs:16:14
|
12 | fn printf(_: *const u8, ...) -> u32;
| ------------------------------------ defined here
...
16 | unsafe { printf(); }
| ^^^^^^^^ expected at least 1 parameter
error: aborting due to previous error

View File

@ -0,0 +1,20 @@
error[E0061]: this function takes 2 parameters but 1 parameter was supplied
--> $DIR/E0061.rs:16:5
|
11 | fn f(a: u16, b: &str) {}
| --------------------- defined here
...
16 | f(0);
| ^^^^ expected 2 parameters
error[E0061]: this function takes 1 parameter but 0 parameters were supplied
--> $DIR/E0061.rs:20:5
|
13 | fn f2(a: u16) {}
| ------------- defined here
...
20 | f2();
| ^^^^ expected 1 parameter
error: aborting due to 2 previous errors

View File

@ -0,0 +1,10 @@
error[E0062]: field `x` specified more than once
--> $DIR/E0062.rs:18:9
|
17 | x: 0,
| ---- first use of `x`
18 | x: 0,
| ^^ used more than once
error: aborting due to previous error

View File

@ -0,0 +1,26 @@
error[E0063]: missing field `x` in initializer of `SingleFoo`
--> $DIR/E0063.rs:42:13
|
42 | let w = SingleFoo { };
| ^^^^^^^^^ missing `x`
error[E0063]: missing fields `y`, `z` in initializer of `PluralFoo`
--> $DIR/E0063.rs:44:13
|
44 | let x = PluralFoo {x: 1};
| ^^^^^^^^^ missing `y`, `z`
error[E0063]: missing fields `a`, `b`, `y` and 1 other field in initializer of `TruncatedFoo`
--> $DIR/E0063.rs:46:13
|
46 | let y = TruncatedFoo{x:1};
| ^^^^^^^^^^^^ missing `a`, `b`, `y` and 1 other field
error[E0063]: missing fields `a`, `b`, `c` and 2 other fields in initializer of `TruncatedPluralFoo`
--> $DIR/E0063.rs:48:13
|
48 | let z = TruncatedPluralFoo{x:1};
| ^^^^^^^^^^^^^^^^^^ missing `a`, `b`, `c` and 2 other fields
error: aborting due to 4 previous errors

View File

@ -0,0 +1,16 @@
error[E0368]: binary assignment operation `+=` cannot be applied to type `std::collections::LinkedList<_>`
--> $DIR/E0067.rs:14:5
|
14 | LinkedList::new() += 1; //~ ERROR E0368
| -----------------^^^^^
| |
| cannot use `+=` on type `std::collections::LinkedList<_>`
error[E0067]: invalid left-hand side expression
--> $DIR/E0067.rs:14:5
|
14 | LinkedList::new() += 1; //~ ERROR E0368
| ^^^^^^^^^^^^^^^^^ invalid expression for left-hand side
error: aborting due to 2 previous errors

View File

@ -0,0 +1,8 @@
error[E0069]: `return;` in a function whose return type is not `()`
--> $DIR/E0069.rs:12:5
|
12 | return;
| ^^^^^^ return type is not ()
error: aborting due to previous error

View File

@ -0,0 +1,29 @@
error[E0070]: invalid left-hand side expression
--> $DIR/E0070.rs:16:5
|
16 | SOME_CONST = 14; //~ ERROR E0070
| ^^^^^^^^^^^^^^^ left-hand of expression not valid
error[E0070]: invalid left-hand side expression
--> $DIR/E0070.rs:17:5
|
17 | 1 = 3; //~ ERROR E0070
| ^^^^^ left-hand of expression not valid
error[E0308]: mismatched types
--> $DIR/E0070.rs:18:25
|
18 | some_other_func() = 4; //~ ERROR E0070
| ^ expected (), found integral variable
|
= note: expected type `()`
found type `{integer}`
error[E0070]: invalid left-hand side expression
--> $DIR/E0070.rs:18:5
|
18 | some_other_func() = 4; //~ ERROR E0070
| ^^^^^^^^^^^^^^^^^^^^^ left-hand of expression not valid
error: aborting due to 4 previous errors

View File

@ -0,0 +1,8 @@
error[E0071]: expected struct, variant or union type, found enum `Foo`
--> $DIR/E0071.rs:15:13
|
15 | let u = FooAlias { value: 0 };
| ^^^^^^^^ not a struct
error: aborting due to previous error

View File

@ -0,0 +1,8 @@
error[E0075]: SIMD vector cannot be empty
--> $DIR/E0075.rs:14:1
|
14 | struct Bad; //~ ERROR E0075
| ^^^^^^^^^^^
error: aborting due to previous error

View File

@ -0,0 +1,8 @@
error[E0076]: SIMD vector should be homogeneous
--> $DIR/E0076.rs:14:1
|
14 | struct Bad(u16, u32, u32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ SIMD elements must have the same type
error: aborting due to previous error

View File

@ -0,0 +1,8 @@
error[E0077]: SIMD vector element type should be machine type
--> $DIR/E0077.rs:14:1
|
14 | struct Bad(String); //~ ERROR E0077
| ^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error

View File

@ -0,0 +1,28 @@
warning: constant evaluation error: attempt to shift left with overflow
--> $DIR/E0080.rs:12:9
|
12 | X = (1 << 500), //~ ERROR E0080
| ^^^^^^^^^^
|
= note: #[warn(const_err)] on by default
error[E0080]: constant evaluation error
--> $DIR/E0080.rs:12:9
|
12 | X = (1 << 500), //~ ERROR E0080
| ^^^^^^^^^^ attempt to shift left with overflow
warning: constant evaluation error: attempt to divide by zero
--> $DIR/E0080.rs:14:9
|
14 | Y = (1 / 0) //~ ERROR E0080
| ^^^^^^^
error[E0080]: constant evaluation error
--> $DIR/E0080.rs:14:9
|
14 | Y = (1 / 0) //~ ERROR E0080
| ^^^^^^^ attempt to divide by zero
error: aborting due to 2 previous errors

View File

@ -0,0 +1,10 @@
error[E0081]: discriminant value `3isize` already exists
--> $DIR/E0081.rs:13:9
|
12 | P = 3,
| - first use of `3isize`
13 | X = 3,
| ^ enum already has `3isize`
error: aborting due to previous error

View File

@ -0,0 +1,10 @@
error[E0084]: unsupported representation for zero-variant enum
--> $DIR/E0084.rs:11:1
|
11 | #[repr(i32)] //~ ERROR: E0084
| ^^^^^^^^^^^^
12 | enum Foo {}
| ----------- zero-variant enum
error: aborting due to previous error

View File

@ -0,0 +1,14 @@
error[E0087]: too many type parameters provided: expected at most 0 type parameters, found 1 type parameter
--> $DIR/E0087.rs:15:11
|
15 | foo::<f64>(); //~ ERROR expected at most 0 type parameters, found 1 type parameter [E0087]
| ^^^ expected 0 type parameters
error[E0087]: too many type parameters provided: expected at most 1 type parameter, found 2 type parameters
--> $DIR/E0087.rs:17:16
|
17 | bar::<f64, u64>(); //~ ERROR expected at most 1 type parameter, found 2 type parameters [E0087]
| ^^^ expected 1 type parameter
error: aborting due to 2 previous errors

Some files were not shown because too many files have changed in this diff Show More