From 2f5294e1d6ec900f1d650879954016146e5df748 Mon Sep 17 00:00:00 2001 From: Mikhail Modin Date: Fri, 5 Aug 2016 18:57:37 +0300 Subject: [PATCH 01/10] Fixes #35304 --- src/librustc_typeck/collect.rs | 7 ++++--- src/test/compile-fail/impl-duplicate-methods.rs | 4 +++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index ec95afe15bd51..6429faf35ff80 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -772,9 +772,10 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) { let mut err = struct_span_err!(tcx.sess, impl_item.span, E0201, "duplicate definitions with name `{}`:", impl_item.name); - span_note!(&mut err, *entry.get(), - "previous definition of `{}` here", - impl_item.name); + err.span_label(*entry.get(), + &format!("previous definition of `{}` here", + impl_item.name)); + err.span_label(impl_item.span, &format!("duplicate definition")); err.emit(); } Vacant(entry) => { diff --git a/src/test/compile-fail/impl-duplicate-methods.rs b/src/test/compile-fail/impl-duplicate-methods.rs index 981eddc9dd96b..f6e9ab2d614bc 100644 --- a/src/test/compile-fail/impl-duplicate-methods.rs +++ b/src/test/compile-fail/impl-duplicate-methods.rs @@ -12,7 +12,9 @@ struct Foo; impl Foo { fn orange(&self) {} //~ NOTE previous definition of `orange` here - fn orange(&self) {} //~ ERROR duplicate definitions with name `orange` + fn orange(&self) {} + //~^ ERROR duplicate definition + //~| NOTE duplicate definition } fn main() {} From 424e77200d0b9f4d60d1f2e73c8462d65ed750fb Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 5 Aug 2016 22:17:41 +0200 Subject: [PATCH 02/10] Add error code check in librustc_const_eval/diagnostics.rs --- src/librustc_const_eval/diagnostics.rs | 48 ++++++++++++++------------ 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/src/librustc_const_eval/diagnostics.rs b/src/librustc_const_eval/diagnostics.rs index 45414c33c0754..9cdc76f25a63f 100644 --- a/src/librustc_const_eval/diagnostics.rs +++ b/src/librustc_const_eval/diagnostics.rs @@ -25,8 +25,8 @@ one is too specific or the ordering is incorrect. For example, the following `match` block has too many arms: -```compile_fail -match foo { +```compile_fail,E0001 +match Some(0) { Some(bar) => {/* ... */} None => {/* ... */} _ => {/* ... */} // All possible cases have already been handled @@ -108,7 +108,7 @@ 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. Erroneous code example: -```compile_fail +```compile_fail,E0004 enum Terminator { HastaLaVistaBaby, TalkToMyHand, @@ -153,7 +153,7 @@ E0005: r##" Patterns used to bind names must be irrefutable, that is, they must guarantee that a name will be extracted in all cases. Erroneous code example: -```compile_fail +```compile_fail,E0005 let x = Some(1); let Some(y) = x; // error: refutable pattern in local binding: `None` not covered @@ -187,7 +187,7 @@ like the following is invalid as it requires the entire `Option` to be moved into a variable called `op_string` while simultaneously requiring the inner `String` to be moved into a variable called `s`. -```compile_fail +```compile_fail,E0007 let x = Some("s".to_string()); match x { @@ -205,7 +205,7 @@ 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: -```compile_fail +```compile_fail,E0008 match Some("hi".to_string()) { Some(s) if s.len() == 0 => {}, // use s. _ => {}, @@ -229,7 +229,7 @@ match Some("hi".to_string()) { Though this example seems innocuous and easy to solve, the problem becomes clear when it encounters functions which consume the value: -```compile_fail +```compile_fail,E0008 struct A{} impl A { @@ -283,7 +283,7 @@ This limitation may be removed in a future version of Rust. Erroneous code example: -```compile_fail +```compile_fail,E0009 struct X { x: (), } let x = Some((X { x: () }, X { x: () })); @@ -351,25 +351,25 @@ 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`-binding instead. For instance: -```compile_fail +```compile_fail,E0162 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: -```ignore +``` struct Irrefutable(i32); let irr = Irrefutable(0); let Irrefutable(x) = irr; -foo(x); +println!("{}", x); ``` "##, @@ -378,7 +378,7 @@ 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`-binding inside a `loop` instead. For instance: -```compile_fail +```compile_fail,E0165 struct Irrefutable(i32); let irr = Irrefutable(0); @@ -455,7 +455,7 @@ that a name will be extracted in all cases. Instead of pattern matching the loop variable, consider using a `match` or `if let` inside the loop body. For instance: -```compile_fail +```compile_fail,E0297 let xs : Vec> = vec!(Some(1), None); // This fails because `None` is not covered. @@ -497,7 +497,7 @@ 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: -```compile_fail +```compile_fail,E0301 match Some(()) { None => { }, option if option.take().is_none() => { @@ -515,10 +515,10 @@ 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: -```compile_fail +```compile_fail,E0302 match Some(()) { None => { }, - option if { option = None; false } { }, + option if { option = None; false } => { }, Some(_) => { } // When the previous match failed, the option became `None`. } ``` @@ -529,14 +529,18 @@ 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. -```ignore -// Before. +Before: + +```compile_fail,E0303 match Some("hi".to_string()) { ref op_string_ref @ Some(s) => {}, None => {}, } +``` + +After: -// After. +``` match Some("hi".to_string()) { Some(ref s) => { let op_string_ref = &Some(s); @@ -556,7 +560,7 @@ This error indicates that the compiler was unable to sensibly evaluate an constant expression that had to be evaluated. Attempting to divide by 0 or causing integer overflow are two ways to induce this error. For example: -```compile_fail +```compile_fail,E0080 enum Enum { X = (1 << 500), Y = (1 / 0) @@ -575,7 +579,7 @@ E0306: r##" In an array literal `[x; N]`, `N` is the number of elements in the array. This must be an unsigned integer. Erroneous code example: -```compile_fail +```compile_fail,E0306 let x = [0i32; true]; // error: expected positive integer for repeat count, // found boolean ``` From 5bab0e65eb9f8d23dfcb8a3b9d1595f25c9b11b4 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Fri, 5 Aug 2016 16:14:11 -0700 Subject: [PATCH 03/10] Update E0206 message to new format --- src/librustc_typeck/coherence/mod.rs | 15 +++++++++++---- src/test/compile-fail/E0206.rs | 10 +++++++--- src/test/compile-fail/coherence-impls-copy.rs | 15 ++++++++++----- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 198e9afd5e12c..333c2a690071a 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -316,10 +316,17 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> { name) } Err(CopyImplementationError::NotAnAdt) => { - span_err!(tcx.sess, span, E0206, - "the trait `Copy` may not be implemented \ - for this type; type is not a structure or \ - enumeration") + let item = tcx.map.expect_item(impl_node_id); + let span = if let ItemImpl(_, _, _, _, ref ty, _) = item.node { + ty.span + } else { + span + }; + + struct_span_err!(tcx.sess, span, E0206, + "the trait `Copy` may not be implemented for this type") + .span_label(span, &format!("type is not a structure or enumeration")) + .emit(); } Err(CopyImplementationError::HasDestructor) => { span_err!(tcx.sess, span, E0184, diff --git a/src/test/compile-fail/E0206.rs b/src/test/compile-fail/E0206.rs index 31b01da3d75b5..6e43812874f2d 100644 --- a/src/test/compile-fail/E0206.rs +++ b/src/test/compile-fail/E0206.rs @@ -10,13 +10,17 @@ type Foo = i32; -impl Copy for Foo { } //~ ERROR E0206 - //~^ ERROR E0117 +impl Copy for Foo { } +//~^ ERROR the trait `Copy` may not be implemented for this type +//~| NOTE type is not a structure or enumeration +//~| ERROR E0117 #[derive(Copy, Clone)] struct Bar; -impl Copy for &'static Bar { } //~ ERROR E0206 +impl Copy for &'static Bar { } +//~^ ERROR the trait `Copy` may not be implemented for this type +//~| NOTE type is not a structure or enumeration fn main() { } diff --git a/src/test/compile-fail/coherence-impls-copy.rs b/src/test/compile-fail/coherence-impls-copy.rs index 9c210c132a313..ec00041a88884 100644 --- a/src/test/compile-fail/coherence-impls-copy.rs +++ b/src/test/compile-fail/coherence-impls-copy.rs @@ -27,22 +27,27 @@ impl Clone for TestE { fn clone(&self) -> Self { *self } } impl Copy for MyType {} impl Copy for &'static mut MyType {} -//~^ ERROR E0206 +//~^ ERROR the trait `Copy` may not be implemented for this type +//~| NOTE type is not a structure or enumeration impl Clone for MyType { fn clone(&self) -> Self { *self } } impl Copy for (MyType, MyType) {} -//~^ ERROR E0206 +//~^ ERROR the trait `Copy` may not be implemented for this type +//~| NOTE type is not a structure or enumeration //~| ERROR E0117 impl Copy for &'static NotSync {} -//~^ ERROR E0206 +//~^ ERROR the trait `Copy` may not be implemented for this type +//~| NOTE type is not a structure or enumeration impl Copy for [MyType] {} -//~^ ERROR E0206 +//~^ ERROR the trait `Copy` may not be implemented for this type +//~| NOTE type is not a structure or enumeration //~| ERROR E0117 impl Copy for &'static [NotSync] {} -//~^ ERROR E0206 +//~^ ERROR the trait `Copy` may not be implemented for this type +//~| NOTE type is not a structure or enumeration //~| ERROR E0117 fn main() { From 065c685e80930379ada8c4358cdd69c2c99ebb15 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Fri, 5 Aug 2016 20:41:25 -0700 Subject: [PATCH 04/10] Update E0223 to the new format --- src/librustc_typeck/astconv.rs | 10 ++++++---- src/test/compile-fail/E0223.rs | 5 ++++- .../associated-types-in-ambiguous-context.rs | 6 ++++++ src/test/compile-fail/issue-34209.rs | 4 +++- src/test/compile-fail/qualified-path-params-2.rs | 8 ++++++-- src/test/compile-fail/self-impl.rs | 8 ++++++-- 6 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index a11df5ae05d6f..953c6b56948cb 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1211,10 +1211,12 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { type_str: &str, trait_str: &str, name: &str) { - span_err!(self.tcx().sess, span, E0223, - "ambiguous associated type; specify the type using the syntax \ - `<{} as {}>::{}`", - type_str, trait_str, name); + struct_span_err!(self.tcx().sess, span, E0223, "ambiguous associated type") + .span_label(span, &format!("ambiguous associated type")) + .note(&format!("specify the type using the syntax `<{} as {}>::{}`", + type_str, trait_str, name)) + .emit(); + } // Search for a bound on a type parameter which includes the associated item diff --git a/src/test/compile-fail/E0223.rs b/src/test/compile-fail/E0223.rs index bbf7d762ef00b..56057b372599d 100644 --- a/src/test/compile-fail/E0223.rs +++ b/src/test/compile-fail/E0223.rs @@ -11,5 +11,8 @@ trait MyTrait { type X; } fn main() { - let foo: MyTrait::X; //~ ERROR E0223 + let foo: MyTrait::X; + //~^ ERROR ambiguous associated type + //~| NOTE ambiguous associated type + //~| NOTE specify the type using the syntax `::X` } diff --git a/src/test/compile-fail/associated-types-in-ambiguous-context.rs b/src/test/compile-fail/associated-types-in-ambiguous-context.rs index becbc27138b77..ff886e63dc59e 100644 --- a/src/test/compile-fail/associated-types-in-ambiguous-context.rs +++ b/src/test/compile-fail/associated-types-in-ambiguous-context.rs @@ -15,15 +15,21 @@ trait Get { fn get(x: T, y: U) -> Get::Value {} //~^ ERROR ambiguous associated type +//~| NOTE ambiguous associated type +//~| NOTE specify the type using the syntax `::Value` trait Grab { type Value; fn grab(&self) -> Grab::Value; //~^ ERROR ambiguous associated type + //~| NOTE ambiguous associated type + //~| NOTE specify the type using the syntax `::Value` } type X = std::ops::Deref::Target; //~^ ERROR ambiguous associated type +//~| NOTE ambiguous associated type +//~| NOTE specify the type using the syntax `::Target` fn main() { } diff --git a/src/test/compile-fail/issue-34209.rs b/src/test/compile-fail/issue-34209.rs index 6fae18dec10a6..5e3b777cc0b62 100644 --- a/src/test/compile-fail/issue-34209.rs +++ b/src/test/compile-fail/issue-34209.rs @@ -15,7 +15,9 @@ enum S { fn bug(l: S) { match l { S::B{ } => { }, - //~^ ERROR ambiguous associated type; specify the type using the syntax `::B` + //~^ ERROR ambiguous associated type + //~| NOTE ambiguous associated type + //~| NOTE specify the type using the syntax `::B` } } diff --git a/src/test/compile-fail/qualified-path-params-2.rs b/src/test/compile-fail/qualified-path-params-2.rs index 5c661bfcdc0c9..e685ebc272098 100644 --- a/src/test/compile-fail/qualified-path-params-2.rs +++ b/src/test/compile-fail/qualified-path-params-2.rs @@ -25,7 +25,11 @@ impl S { fn f() {} } -type A = ::A::f; //~ ERROR type parameters are not allowed on this type -//~^ ERROR ambiguous associated type; specify the type using the syntax `<::A as Trait>::f` +type A = ::A::f; +//~^ ERROR type parameters are not allowed on this type +//~| NOTE type parameter not allowed +//~| ERROR ambiguous associated type +//~| NOTE ambiguous associated type +//~| NOTE specify the type using the syntax `<::A as Trait>::f` fn main() {} diff --git a/src/test/compile-fail/self-impl.rs b/src/test/compile-fail/self-impl.rs index d058c6a5a3b93..860e69fcaec4d 100644 --- a/src/test/compile-fail/self-impl.rs +++ b/src/test/compile-fail/self-impl.rs @@ -31,9 +31,13 @@ impl SuperFoo for Bar { impl Bar { fn f() { let _: ::Baz = true; -//~^ERROR: ambiguous associated type; specify the type using the syntax `::Baz` + //~^ ERROR ambiguous associated type + //~| NOTE ambiguous associated type + //~| NOTE specify the type using the syntax `::Baz` let _: Self::Baz = true; -//~^ERROR: ambiguous associated type; specify the type using the syntax `::Baz` + //~^ ERROR ambiguous associated type + //~| NOTE ambiguous associated type + //~| NOTE specify the type using the syntax `::Baz` } } From c9e9d425769274b59734d852a8ae64c9fef16d78 Mon Sep 17 00:00:00 2001 From: silenuss Date: Fri, 5 Aug 2016 20:25:34 -0600 Subject: [PATCH 05/10] Update compiler error 0027 to use new error format. --- src/librustc_typeck/check/_match.rs | 8 +++++--- src/test/compile-fail/E0027.rs | 4 +++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index aae6e3ad36dfe..47f75e2f4990e 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -700,9 +700,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { for field in variant.fields .iter() .filter(|field| !used_fields.contains_key(&field.name)) { - span_err!(tcx.sess, span, E0027, - "pattern does not mention field `{}`", - field.name); + struct_span_err!(tcx.sess, span, E0027, + "pattern does not mention field `{}`", + field.name) + .span_label(span, &format!("missing field `{}`", field.name)) + .emit(); } } } diff --git a/src/test/compile-fail/E0027.rs b/src/test/compile-fail/E0027.rs index b2f20442b77ad..ca496a24701fb 100644 --- a/src/test/compile-fail/E0027.rs +++ b/src/test/compile-fail/E0027.rs @@ -17,6 +17,8 @@ fn main() { let d = Dog { name: "Rusty".to_string(), age: 8 }; match d { - Dog { age: x } => {} //~ ERROR E0027 + Dog { age: x } => {} + //~^ ERROR pattern does not mention field `name` + //~| NOTE missing field `name` } } From 1d25e2eeccc40cbde2a1ed5be043889c1450cd93 Mon Sep 17 00:00:00 2001 From: silenuss Date: Sat, 6 Aug 2016 00:33:59 -0600 Subject: [PATCH 06/10] Update compiler error 0029 to use new error format. --- src/librustc_typeck/check/_match.rs | 13 ++++++------- src/test/compile-fail/E0029.rs | 6 +++++- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index aae6e3ad36dfe..82a100f189933 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -93,13 +93,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { end.span }; - // Note: spacing here is intentional, we want a space before "start" and "end". - span_err!(tcx.sess, span, E0029, - "only char and numeric types are allowed in range patterns\n \ - start type: {}\n end type: {}", - self.ty_to_string(lhs_ty), - self.ty_to_string(rhs_ty) - ); + struct_span_err!(tcx.sess, span, E0029, + "only char and numeric types are allowed in range patterns") + .span_label(span, &format!("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(); return; } diff --git a/src/test/compile-fail/E0029.rs b/src/test/compile-fail/E0029.rs index 9cbdec9952053..ec84e2a3f8a36 100644 --- a/src/test/compile-fail/E0029.rs +++ b/src/test/compile-fail/E0029.rs @@ -12,7 +12,11 @@ fn main() { let s = "hoho"; match s { - "hello" ... "world" => {} //~ ERROR E0029 + "hello" ... "world" => {} + //~^ ERROR only char and numeric types are allowed in range patterns + //~| NOTE ranges require char or numeric types + //~| NOTE start type: &'static str + //~| NOTE end type: &'static str _ => {} } } From f4dd1f9500e5d5fedc79994b23f9fdf79672ce71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Medzi=C5=84ski?= Date: Fri, 5 Aug 2016 13:06:09 +0200 Subject: [PATCH 07/10] Updated error message E0252 --- src/librustc_resolve/lib.rs | 6 +++++- src/test/compile-fail/double-import.rs | 3 +-- src/test/compile-fail/issue-26886.rs | 2 ++ src/test/compile-fail/use-mod.rs | 3 ++- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index c1511b29c9e01..1c74546a4dc4a 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3367,7 +3367,11 @@ impl<'a> Resolver<'a> { (true, _) | (_, true) => struct_span_err!(self.session, span, E0260, "{}", msg), _ => match (old_binding.is_import(), binding.is_import()) { (false, false) => struct_span_err!(self.session, span, E0428, "{}", msg), - (true, true) => struct_span_err!(self.session, span, E0252, "{}", msg), + (true, true) => { + let mut e = struct_span_err!(self.session, span, E0252, "{}", msg); + e.span_label(span, &format!("already imported")); + e + }, _ => { let mut e = struct_span_err!(self.session, span, E0255, "{}", msg); e.span_label(span, &format!("`{}` was already imported", name)); diff --git a/src/test/compile-fail/double-import.rs b/src/test/compile-fail/double-import.rs index 7b915647884f2..bd190a6df8e39 100644 --- a/src/test/compile-fail/double-import.rs +++ b/src/test/compile-fail/double-import.rs @@ -7,8 +7,6 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(no_core)] -#![no_core] // This tests that conflicting imports shows both `use` lines // when reporting the error. @@ -23,5 +21,6 @@ mod sub2 { use sub1::foo; //~ NOTE previous import of `foo` here use sub2::foo; //~ ERROR a value named `foo` has already been imported in this module [E0252] + //~| NOTE already imported fn main() {} diff --git a/src/test/compile-fail/issue-26886.rs b/src/test/compile-fail/issue-26886.rs index c849716f21a37..46e82363c8bd8 100644 --- a/src/test/compile-fail/issue-26886.rs +++ b/src/test/compile-fail/issue-26886.rs @@ -11,7 +11,9 @@ use std::sync::{self, Arc}; //~ NOTE previous import //~^ NOTE previous import use std::sync::Arc; //~ ERROR a type named + //~| NOTE already imported use std::sync; //~ ERROR a module named + //~| NOTE already imported fn main() { } diff --git a/src/test/compile-fail/use-mod.rs b/src/test/compile-fail/use-mod.rs index bbb063770c148..6be878dce1fb9 100644 --- a/src/test/compile-fail/use-mod.rs +++ b/src/test/compile-fail/use-mod.rs @@ -15,7 +15,8 @@ use foo::bar::{ Bar, self //~^ NOTE another `self` import appears here -//~^^ ERROR a module named `bar` has already been imported in this module +//~| ERROR a module named `bar` has already been imported in this module +//~| NOTE already imported }; use {self}; From eb469d60b6bba039b94d55ddf3b44e7f81bf3bda Mon Sep 17 00:00:00 2001 From: Federico Ravasio Date: Sat, 6 Aug 2016 15:29:12 +0200 Subject: [PATCH 08/10] Updated E0225 to new format. --- src/librustc_typeck/astconv.rs | 7 +++++-- src/test/compile-fail/E0225.rs | 4 +++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index a11df5ae05d6f..749dcc4e1c614 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -2091,8 +2091,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { if !trait_bounds.is_empty() { let b = &trait_bounds[0]; - span_err!(self.tcx().sess, b.trait_ref.path.span, E0225, - "only the builtin traits can be used as closure or object bounds"); + let span = b.trait_ref.path.span; + struct_span_err!(self.tcx().sess, span, E0225, + "only the builtin traits can be used as closure or object bounds") + .span_label(span, &format!("non-builtin trait used as bounds")) + .emit(); } let region_bound = diff --git a/src/test/compile-fail/E0225.rs b/src/test/compile-fail/E0225.rs index 190350c5a5571..b013788ceff85 100644 --- a/src/test/compile-fail/E0225.rs +++ b/src/test/compile-fail/E0225.rs @@ -9,5 +9,7 @@ // except according to those terms. fn main() { - let _: Box; //~ ERROR E0225 + let _: Box; + //~^ ERROR only the builtin traits can be used as closure or object bounds [E0225] + //~| NOTE non-builtin trait used as bounds } From 4e2dd8d24ae58fad215416b89bf00e2444a5128e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 5 Aug 2016 22:18:01 +0200 Subject: [PATCH 09/10] Add new error code tests --- src/test/compile-fail/E0271.rs | 21 +++++++++++++++++++++ src/test/compile-fail/E0275.rs | 18 ++++++++++++++++++ src/test/compile-fail/E0276.rs | 20 ++++++++++++++++++++ src/test/compile-fail/E0277.rs | 21 +++++++++++++++++++++ src/test/compile-fail/E0281.rs | 16 ++++++++++++++++ src/test/compile-fail/E0282.rs | 13 +++++++++++++ src/test/compile-fail/E0283.rs | 29 +++++++++++++++++++++++++++++ src/test/compile-fail/E0296.rs | 13 +++++++++++++ src/test/compile-fail/E0297.rs | 15 +++++++++++++++ src/test/compile-fail/E0301.rs | 17 +++++++++++++++++ src/test/compile-fail/E0302.rs | 17 +++++++++++++++++ src/test/compile-fail/E0303.rs | 17 +++++++++++++++++ 12 files changed, 217 insertions(+) create mode 100644 src/test/compile-fail/E0271.rs create mode 100644 src/test/compile-fail/E0275.rs create mode 100644 src/test/compile-fail/E0276.rs create mode 100644 src/test/compile-fail/E0277.rs create mode 100644 src/test/compile-fail/E0281.rs create mode 100644 src/test/compile-fail/E0282.rs create mode 100644 src/test/compile-fail/E0283.rs create mode 100644 src/test/compile-fail/E0296.rs create mode 100644 src/test/compile-fail/E0297.rs create mode 100644 src/test/compile-fail/E0301.rs create mode 100644 src/test/compile-fail/E0302.rs create mode 100644 src/test/compile-fail/E0303.rs diff --git a/src/test/compile-fail/E0271.rs b/src/test/compile-fail/E0271.rs new file mode 100644 index 0000000000000..d322c8b1caf56 --- /dev/null +++ b/src/test/compile-fail/E0271.rs @@ -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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait Trait { type AssociatedType; } + +fn foo(t: T) where T: Trait { + println!("in foo"); +} + +impl Trait for i8 { type AssociatedType = &'static str; } + +fn main() { + foo(3_i8); //~ ERROR E0271 +} diff --git a/src/test/compile-fail/E0275.rs b/src/test/compile-fail/E0275.rs new file mode 100644 index 0000000000000..8dfd1d9b4afc9 --- /dev/null +++ b/src/test/compile-fail/E0275.rs @@ -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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait Foo {} + +struct Bar(T); + +impl Foo for T where Bar: Foo {} //~ ERROR E0275 + +fn main() { +} diff --git a/src/test/compile-fail/E0276.rs b/src/test/compile-fail/E0276.rs new file mode 100644 index 0000000000000..62e43b02ca85f --- /dev/null +++ b/src/test/compile-fail/E0276.rs @@ -0,0 +1,20 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait Foo { + fn foo(x: T); +} + +impl Foo for bool { + fn foo(x: T) where T: Copy {} //~ ERROR E0276 +} + +fn main() { +} diff --git a/src/test/compile-fail/E0277.rs b/src/test/compile-fail/E0277.rs new file mode 100644 index 0000000000000..7737f12ac3714 --- /dev/null +++ b/src/test/compile-fail/E0277.rs @@ -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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait Foo { + fn bar(&self); +} + +fn some_func(foo: T) { + foo.bar(); +} + +fn main() { + some_func(5i32); //~ ERROR E0277 +} diff --git a/src/test/compile-fail/E0281.rs b/src/test/compile-fail/E0281.rs new file mode 100644 index 0000000000000..d468cd3ff1bf4 --- /dev/null +++ b/src/test/compile-fail/E0281.rs @@ -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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn foo(x: F) { } + +fn main() { + foo(|y| { }); //~ ERROR E0281 + //~^ ERROR E0281 +} diff --git a/src/test/compile-fail/E0282.rs b/src/test/compile-fail/E0282.rs new file mode 100644 index 0000000000000..dfc702670ce46 --- /dev/null +++ b/src/test/compile-fail/E0282.rs @@ -0,0 +1,13 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let x = "hello".chars().rev().collect(); //~ ERROR E0282 +} diff --git a/src/test/compile-fail/E0283.rs b/src/test/compile-fail/E0283.rs new file mode 100644 index 0000000000000..844c47f41b81a --- /dev/null +++ b/src/test/compile-fail/E0283.rs @@ -0,0 +1,29 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait Generator { + fn create() -> u32; +} + +struct Impl; + +impl Generator for Impl { + fn create() -> u32 { 1 } +} + +struct AnotherImpl; + +impl Generator for AnotherImpl { + fn create() -> u32 { 2 } +} + +fn main() { + let cont: u32 = Generator::create(); //~ ERROR E0283 +} diff --git a/src/test/compile-fail/E0296.rs b/src/test/compile-fail/E0296.rs new file mode 100644 index 0000000000000..562fd00a18aa6 --- /dev/null +++ b/src/test/compile-fail/E0296.rs @@ -0,0 +1,13 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![recursion_limit] //~ ERROR E0296 + +fn main() {} diff --git a/src/test/compile-fail/E0297.rs b/src/test/compile-fail/E0297.rs new file mode 100644 index 0000000000000..43166c1a9e83e --- /dev/null +++ b/src/test/compile-fail/E0297.rs @@ -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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let xs : Vec> = vec!(Some(1), None); + + for Some(x) in xs {} //~ ERROR E0297 +} diff --git a/src/test/compile-fail/E0301.rs b/src/test/compile-fail/E0301.rs new file mode 100644 index 0000000000000..06e98289b0d57 --- /dev/null +++ b/src/test/compile-fail/E0301.rs @@ -0,0 +1,17 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + match Some(()) { + None => { }, + option if option.take().is_none() => {}, //~ ERROR E0301 + Some(_) => { } + } +} diff --git a/src/test/compile-fail/E0302.rs b/src/test/compile-fail/E0302.rs new file mode 100644 index 0000000000000..6a5ad40b10907 --- /dev/null +++ b/src/test/compile-fail/E0302.rs @@ -0,0 +1,17 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + match Some(()) { + None => { }, + option if { option = None; false } => { }, //~ ERROR E0302 + Some(_) => { } + } +} diff --git a/src/test/compile-fail/E0303.rs b/src/test/compile-fail/E0303.rs new file mode 100644 index 0000000000000..67947fd087c05 --- /dev/null +++ b/src/test/compile-fail/E0303.rs @@ -0,0 +1,17 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + match Some("hi".to_string()) { + ref op_string_ref @ Some(s) => {}, //~ ERROR E0303 + //~^ ERROR E0009 + None => {}, + } +} From 24ddca05e75ab16fec6bbe009eabc3420eb68e78 Mon Sep 17 00:00:00 2001 From: Vincent Prouillet Date: Sat, 6 Aug 2016 11:35:42 +0100 Subject: [PATCH 10/10] Update error message for E0243 and E0244 --- src/librustc_typeck/astconv.rs | 29 ++++++++++++------- src/test/compile-fail/E0243.rs | 4 ++- src/test/compile-fail/E0244.rs | 5 +++- .../generic-type-less-params-with-defaults.rs | 4 ++- .../generic-type-more-params-with-defaults.rs | 3 +- src/test/compile-fail/issue-14092.rs | 4 ++- src/test/compile-fail/issue-23024.rs | 7 ++++- .../typeck-builtin-bound-type-parameters.rs | 15 ++++++---- .../typeck_type_placeholder_lifetime_1.rs | 3 +- .../typeck_type_placeholder_lifetime_2.rs | 3 +- .../unboxed-closure-sugar-wrong-trait.rs | 3 +- 11 files changed, 55 insertions(+), 25 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 3b2bca4ab3912..fd5334e1a9267 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -2248,20 +2248,27 @@ fn check_type_argument_count(tcx: TyCtxt, span: Span, supplied: usize, } else { "expected" }; - span_err!(tcx.sess, span, E0243, - "wrong number of type arguments: {} {}, found {}", - expected, required, supplied); + struct_span_err!(tcx.sess, span, E0243, "wrong number of type arguments") + .span_label( + span, + &format!("{} {} type arguments, found {}", expected, required, supplied) + ) + .emit(); } else if supplied > accepted { - let expected = if required < accepted { - "expected at most" + let expected = if required == 0 { + "expected no".to_string() + } else if required < accepted { + format!("expected at most {}", accepted) } else { - "expected" + format!("expected {}", accepted) }; - span_err!(tcx.sess, span, E0244, - "wrong number of type arguments: {} {}, found {}", - expected, - accepted, - supplied); + + struct_span_err!(tcx.sess, span, E0244, "wrong number of type arguments") + .span_label( + span, + &format!("{} type arguments, found {}", expected, supplied) + ) + .emit(); } } diff --git a/src/test/compile-fail/E0243.rs b/src/test/compile-fail/E0243.rs index 8cc245c10cbe9..77c9856c261ff 100644 --- a/src/test/compile-fail/E0243.rs +++ b/src/test/compile-fail/E0243.rs @@ -9,7 +9,9 @@ // except according to those terms. struct Foo { x: T } -struct Bar { x: Foo } //~ ERROR E0243 +struct Bar { x: Foo } + //~^ ERROR E0243 + //~| NOTE expected 1 type arguments, found 0 fn main() { } diff --git a/src/test/compile-fail/E0244.rs b/src/test/compile-fail/E0244.rs index 4c57447109296..5678a7fd450d8 100644 --- a/src/test/compile-fail/E0244.rs +++ b/src/test/compile-fail/E0244.rs @@ -9,7 +9,10 @@ // except according to those terms. struct Foo { x: bool } -struct Bar { x: Foo } //~ ERROR E0244 +struct Bar { x: Foo } + //~^ ERROR E0244 + //~| NOTE expected no type arguments, found 2 + fn main() { } diff --git a/src/test/compile-fail/generic-type-less-params-with-defaults.rs b/src/test/compile-fail/generic-type-less-params-with-defaults.rs index 37737fda4749e..d9ac715fa9548 100644 --- a/src/test/compile-fail/generic-type-less-params-with-defaults.rs +++ b/src/test/compile-fail/generic-type-less-params-with-defaults.rs @@ -16,5 +16,7 @@ struct Vec( marker::PhantomData<(T,A)>); fn main() { - let _: Vec; //~ ERROR wrong number of type arguments: expected at least 1, found 0 + let _: Vec; + //~^ ERROR E0243 + //~| NOTE expected at least 1 type arguments, found 0 } diff --git a/src/test/compile-fail/generic-type-more-params-with-defaults.rs b/src/test/compile-fail/generic-type-more-params-with-defaults.rs index ad7e4f190c5b9..8f733ddfce187 100644 --- a/src/test/compile-fail/generic-type-more-params-with-defaults.rs +++ b/src/test/compile-fail/generic-type-more-params-with-defaults.rs @@ -17,5 +17,6 @@ struct Vec( fn main() { let _: Vec; - //~^ ERROR wrong number of type arguments: expected at most 2, found 3 + //~^ ERROR E0244 + //~| NOTE expected at most 2 type arguments, found 3 } diff --git a/src/test/compile-fail/issue-14092.rs b/src/test/compile-fail/issue-14092.rs index c87dcb8ae79b2..dd02fa7ac151c 100644 --- a/src/test/compile-fail/issue-14092.rs +++ b/src/test/compile-fail/issue-14092.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn fn1(0: Box) {} //~ ERROR: wrong number of type arguments: expected 1, found 0 +fn fn1(0: Box) {} + //~^ ERROR E0243 + //~| NOTE expected 1 type arguments, found 0 fn main() {} diff --git a/src/test/compile-fail/issue-23024.rs b/src/test/compile-fail/issue-23024.rs index df2a70160f866..50f1323d39c55 100644 --- a/src/test/compile-fail/issue-23024.rs +++ b/src/test/compile-fail/issue-23024.rs @@ -18,6 +18,11 @@ fn main() vfnfer.push(box h); println!("{:?}",(vfnfer[0] as Fn)(3)); //~^ ERROR the precise format of `Fn`-family traits' - //~| ERROR wrong number of type arguments: expected 1, found 0 + //~| ERROR E0243 + //~| NOTE expected 1 type arguments, found 0 //~| ERROR the value of the associated type `Output` (from the trait `std::ops::FnOnce`) + //~| NOTE in this expansion of println! + //~| NOTE in this expansion of println! + //~| NOTE in this expansion of println! + //~| NOTE in this expansion of println! } diff --git a/src/test/compile-fail/typeck-builtin-bound-type-parameters.rs b/src/test/compile-fail/typeck-builtin-bound-type-parameters.rs index fb6c43a19059a..55ccb8c7db9ab 100644 --- a/src/test/compile-fail/typeck-builtin-bound-type-parameters.rs +++ b/src/test/compile-fail/typeck-builtin-bound-type-parameters.rs @@ -9,20 +9,25 @@ // except according to those terms. fn foo1, U>(x: T) {} -//~^ ERROR: wrong number of type arguments: expected 0, found 1 +//~^ ERROR E0244 +//~| NOTE expected no type arguments, found 1 trait Trait: Copy {} -//~^ ERROR: wrong number of type arguments: expected 0, found 1 +//~^ ERROR E0244 +//~| NOTE expected no type arguments, found 1 struct MyStruct1>; -//~^ ERROR wrong number of type arguments: expected 0, found 1 +//~^ ERROR E0244 +//~| NOTE expected no type arguments, found 1 struct MyStruct2<'a, T: Copy<'a>>; //~^ ERROR: wrong number of lifetime parameters: expected 0, found 1 + fn foo2<'a, T:Copy<'a, U>, U>(x: T) {} -//~^ ERROR: wrong number of type arguments: expected 0, found 1 -//~^^ ERROR: wrong number of lifetime parameters: expected 0, found 1 +//~^ ERROR E0244 +//~| NOTE expected no type arguments, found 1 +//~| ERROR: wrong number of lifetime parameters: expected 0, found 1 fn main() { } diff --git a/src/test/compile-fail/typeck_type_placeholder_lifetime_1.rs b/src/test/compile-fail/typeck_type_placeholder_lifetime_1.rs index 2cb46cc352bec..f60d925a74864 100644 --- a/src/test/compile-fail/typeck_type_placeholder_lifetime_1.rs +++ b/src/test/compile-fail/typeck_type_placeholder_lifetime_1.rs @@ -17,5 +17,6 @@ struct Foo<'a, T:'a> { pub fn main() { let c: Foo<_, _> = Foo { r: &5 }; - //~^ ERROR wrong number of type arguments: expected 1, found 2 + //~^ ERROR E0244 + //~| NOTE expected 1 type arguments, found 2 } diff --git a/src/test/compile-fail/typeck_type_placeholder_lifetime_2.rs b/src/test/compile-fail/typeck_type_placeholder_lifetime_2.rs index 8178335de5931..ec2675ece74b0 100644 --- a/src/test/compile-fail/typeck_type_placeholder_lifetime_2.rs +++ b/src/test/compile-fail/typeck_type_placeholder_lifetime_2.rs @@ -17,5 +17,6 @@ struct Foo<'a, T:'a> { pub fn main() { let c: Foo<_, usize> = Foo { r: &5 }; - //~^ ERROR wrong number of type arguments: expected 1, found 2 + //~^ ERROR E0244 + //~| NOTE expected 1 type arguments, found 2 } diff --git a/src/test/compile-fail/unboxed-closure-sugar-wrong-trait.rs b/src/test/compile-fail/unboxed-closure-sugar-wrong-trait.rs index 04bbfc445edea..1209757610251 100644 --- a/src/test/compile-fail/unboxed-closure-sugar-wrong-trait.rs +++ b/src/test/compile-fail/unboxed-closure-sugar-wrong-trait.rs @@ -13,7 +13,8 @@ trait Trait {} fn f isize>(x: F) {} -//~^ ERROR wrong number of type arguments: expected 0, found 1 +//~^ ERROR E0244 +//~| NOTE expected no type arguments, found 1 //~| ERROR associated type `Output` not found fn main() {}