Skip to content

Commit

Permalink
Auto merge of #51463 - estebank:error-codes, r=nikomatsakis
Browse files Browse the repository at this point in the history
Various changes to existing diagnostics

* [Add code to `invalid ABI` error, add span label, move list to help to make message shorter](23ae5af):
```
error[E0697]: invalid ABI: found `路濫狼á́́`
  --> $DIR/unicode.rs:11:8
   |
LL | extern "路濫狼á́́" fn foo() {} //~ ERROR invalid ABI
   |        ^^^^^^^^^ invalid ABI
   |
   = help: valid ABIs: cdecl, stdcall, fastcall, vectorcall, thiscall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, Rust, C, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted
```
* [Add code to incorrect `pub` restriction error](e96fdea)
* [Add message to `rustc_on_unimplemented` attributes in core to have them set a custom message _and_ label](2cc7e5e):
```
error[E0277]: `W` does not have a constant size known at compile-time
  --> $DIR/unsized-enum2.rs:33:8
   |
LL |     VA(W),
   |        ^ `W` does not have a constant size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `W`
   = help: consider adding a `where W: std::marker::Sized` bound
   = note: no field of an enum variant may have a dynamically sized type
```
```
error[E0277]: `Foo` cannot be sent between threads safely
  --> $DIR/E0277-2.rs:26:5
   |
LL |     is_send::<Foo>();
   |     ^^^^^^^^^^^^^^ `Foo` cannot be sent between threads safely
   |
   = help: the trait `std::marker::Send` is not implemented for `Foo`
```
```
error[E0277]: can't compare `{integer}` with `std::string::String`
  --> $DIR/binops.rs:16:7
   |
LL |     5 < String::new();
   |       ^ no implementation for `{integer} < std::string::String` and `{integer} > std::string::String`
   |
   = help: the trait `std::cmp::PartialOrd<std::string::String>` is not implemented for `{integer}`
```
```
error[E0277]: can't compare `{integer}` with `std::result::Result<{integer}, _>`
  --> $DIR/binops.rs:17:7
   |
LL |     6 == Ok(1);
   |       ^^ no implementation for `{integer} == std::result::Result<{integer}, _>`
   |
   = help: the trait `std::cmp::PartialEq<std::result::Result<{integer}, _>>` is not implemented for `{integer}`
```
```
error[E0277]: a collection of type `i32` cannot be built from an iterator over elements of type `i32`
  --> $DIR/type-check-defaults.rs:16:19
   |
LL | struct WellFormed<Z = Foo<i32, i32>>(Z);
   |                   ^ a collection of type `i32` cannot be built from `std::iter::Iterator<Item=i32>`
   |
   = help: the trait `std::iter::FromIterator<i32>` is not implemented for `i32`
note: required by `Foo`
  --> $DIR/type-check-defaults.rs:15:1
   |
LL | struct Foo<T, U: FromIterator<T>>(T, U);
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
* [Add link to book for `Sized` errors](1244dc7):
```
error[E0277]: `std::fmt::Debug + std::marker::Sync + 'static` does not have a constant size known at compile-time
  --> $DIR/const-unsized.rs:13:29
   |
LL | const CONST_0: Debug+Sync = *(&0 as &(Debug+Sync));
   |                             ^^^^^^^^^^^^^^^^^^^^^^ `std::fmt::Debug + std::marker::Sync + 'static` does not have a constant size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `std::fmt::Debug + std::marker::Sync + 'static`
   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
   = note: constant expressions must have a statically known size
```
* [Point to previous line for single expected token not found](4816516) (if the current token is in a different line)
  • Loading branch information
bors committed Jun 22, 2018
2 parents 0b8d817 + 28cea50 commit 4b17d31
Show file tree
Hide file tree
Showing 117 changed files with 559 additions and 376 deletions.
10 changes: 8 additions & 2 deletions src/liballoc/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1693,7 +1693,10 @@ impl<T: Hash> Hash for Vec<T> {
}

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
#[rustc_on_unimplemented(
message="vector indices are of type `usize` or ranges of `usize`",
label="vector indices are of type `usize` or ranges of `usize`",
)]
impl<T, I> Index<I> for Vec<T>
where
I: ::core::slice::SliceIndex<[T]>,
Expand All @@ -1707,7 +1710,10 @@ where
}

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
#[rustc_on_unimplemented(
message="vector indices are of type `usize` or ranges of `usize`",
label="vector indices are of type `usize` or ranges of `usize`",
)]
impl<T, I> IndexMut<I> for Vec<T>
where
I: ::core::slice::SliceIndex<[T]>,
Expand Down
10 changes: 8 additions & 2 deletions src/libcore/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,10 @@ use self::Ordering::*;
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(alias = "==")]
#[doc(alias = "!=")]
#[rustc_on_unimplemented = "can't compare `{Self}` with `{Rhs}`"]
#[rustc_on_unimplemented(
message="can't compare `{Self}` with `{Rhs}`",
label="no implementation for `{Self} == {Rhs}`",
)]
pub trait PartialEq<Rhs: ?Sized = Self> {
/// This method tests for `self` and `other` values to be equal, and is used
/// by `==`.
Expand Down Expand Up @@ -611,7 +614,10 @@ impl PartialOrd for Ordering {
#[doc(alias = "<")]
#[doc(alias = "<=")]
#[doc(alias = ">=")]
#[rustc_on_unimplemented = "can't compare `{Self}` with `{Rhs}`"]
#[rustc_on_unimplemented(
message="can't compare `{Self}` with `{Rhs}`",
label="no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`",
)]
pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
/// This method returns an ordering between `self` and `other` values if one exists.
///
Expand Down
7 changes: 5 additions & 2 deletions src/libcore/iter/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,11 @@ use super::LoopState;
/// assert_eq!(c.0, vec![0, 1, 2, 3, 4]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented="a collection of type `{Self}` cannot be \
built from an iterator over elements of type `{A}`"]
#[rustc_on_unimplemented(
message="a collection of type `{Self}` cannot be built from an iterator \
over elements of type `{A}`",
label="a collection of type `{Self}` cannot be built from `std::iter::Iterator<Item={A}>`",
)]
pub trait FromIterator<A>: Sized {
/// Creates a value from an iterator.
///
Expand Down
12 changes: 10 additions & 2 deletions src/libcore/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ use hash::Hasher;
/// [arc]: ../../std/sync/struct.Arc.html
/// [ub]: ../../reference/behavior-considered-undefined.html
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"]
#[rustc_on_unimplemented(
message="`{Self}` cannot be sent between threads safely",
label="`{Self}` cannot be sent between threads safely"
)]
pub unsafe auto trait Send {
// empty.
}
Expand Down Expand Up @@ -88,7 +91,12 @@ impl<T: ?Sized> !Send for *mut T { }
/// [trait object]: ../../book/first-edition/trait-objects.html
#[stable(feature = "rust1", since = "1.0.0")]
#[lang = "sized"]
#[rustc_on_unimplemented = "`{Self}` does not have a constant size known at compile-time"]
#[rustc_on_unimplemented(
message="the size for value values of type `{Self}` cannot be known at compilation time",
label="doesn't have a size known at compile-time",
note="to learn more, visit <https://doc.rust-lang.org/book/second-edition/\
ch19-04-advanced-types.html#dynamically-sized-types--sized>",
)]
#[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
pub trait Sized {
// Empty.
Expand Down
10 changes: 8 additions & 2 deletions src/libcore/ops/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,10 @@
/// assert_eq!(nucleotide_count[Nucleotide::T], 12);
/// ```
#[lang = "index"]
#[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"]
#[rustc_on_unimplemented(
message="the type `{Self}` cannot be indexed by `{Idx}`",
label="`{Self}` cannot be indexed by `{Idx}`",
)]
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(alias = "]")]
#[doc(alias = "[")]
Expand Down Expand Up @@ -147,7 +150,10 @@ pub trait Index<Idx: ?Sized> {
/// balance[Side::Left] = Weight::Kilogram(3.0);
/// ```
#[lang = "index_mut"]
#[rustc_on_unimplemented = "the type `{Self}` cannot be mutably indexed by `{Idx}`"]
#[rustc_on_unimplemented(
message="the type `{Self}` cannot be mutably indexed by `{Idx}`",
label="`{Self}` cannot be mutably indexed by `{Idx}`",
)]
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(alias = "[")]
#[doc(alias = "]")]
Expand Down
15 changes: 10 additions & 5 deletions src/libstd/panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,10 @@ pub use core::panic::{PanicInfo, Location};
///
/// [`AssertUnwindSafe`]: ./struct.AssertUnwindSafe.html
#[stable(feature = "catch_unwind", since = "1.9.0")]
#[rustc_on_unimplemented = "the type {Self} may not be safely transferred \
across an unwind boundary"]
#[rustc_on_unimplemented(
message="the type `{Self}` may not be safely transferred across an unwind boundary",
label="`{Self}` may not be safely transferred across an unwind boundary",
)]
pub auto trait UnwindSafe {}

/// A marker trait representing types where a shared reference is considered
Expand All @@ -126,9 +128,12 @@ pub auto trait UnwindSafe {}
/// [`UnsafeCell`]: ../cell/struct.UnsafeCell.html
/// [`UnwindSafe`]: ./trait.UnwindSafe.html
#[stable(feature = "catch_unwind", since = "1.9.0")]
#[rustc_on_unimplemented = "the type {Self} may contain interior mutability \
and a reference may not be safely transferrable \
across a catch_unwind boundary"]
#[rustc_on_unimplemented(
message="the type `{Self}` may contain interior mutability and a reference may not be safely \
transferrable across a catch_unwind boundary",
label="`{Self}` may contain interior mutability and a reference may not be safely \
transferrable across a catch_unwind boundary",
)]
pub auto trait RefUnwindSafe {}

/// A simple wrapper around a type to assert that it is unwind safe.
Expand Down
2 changes: 2 additions & 0 deletions src/libsyntax/diagnostic_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,4 +397,6 @@ register_diagnostics! {
E0630, // rustc_const_unstable attribute must be paired with stable/unstable attribute
E0693, // incorrect `repr(align)` attribute format
E0694, // an unknown tool name found in scoped attributes
E0703, // invalid ABI
E0704, // incorrect visibility restriction
}
49 changes: 32 additions & 17 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,26 @@ impl<'a> Parser<'a> {
let mut err = self.fatal(&format!("expected `{}`, found `{}`",
token_str,
this_token_str));
err.span_label(self.span, format!("expected `{}`", token_str));

let sp = if self.token == token::Token::Eof {
// EOF, don't want to point at the following char, but rather the last token
self.prev_span
} else {
self.sess.codemap().next_point(self.prev_span)
};
let label_exp = format!("expected `{}`", token_str);
let cm = self.sess.codemap();
match (cm.lookup_line(self.span.lo()), cm.lookup_line(sp.lo())) {
(Ok(ref a), Ok(ref b)) if a.line == b.line => {
// When the spans are in the same line, it means that the only content
// between them is whitespace, point only at the found token.
err.span_label(self.span, label_exp);
}
_ => {
err.span_label(sp, label_exp);
err.span_label(self.span, "unexpected token");
}
}
Err(err)
}
} else {
Expand Down Expand Up @@ -1205,14 +1224,6 @@ impl<'a> Parser<'a> {
fn span_fatal_err<S: Into<MultiSpan>>(&self, sp: S, err: Error) -> DiagnosticBuilder<'a> {
err.span_err(sp, self.diagnostic())
}
fn span_fatal_help<S: Into<MultiSpan>>(&self,
sp: S,
m: &str,
help: &str) -> DiagnosticBuilder<'a> {
let mut err = self.sess.span_diagnostic.struct_span_fatal(sp, m);
err.help(help);
err
}
fn bug(&self, m: &str) -> ! {
self.sess.span_diagnostic.span_bug(self.span, m)
}
Expand Down Expand Up @@ -5985,12 +5996,13 @@ impl<'a> Parser<'a> {
`pub(super)`: visible only in the current module's parent
`pub(in path::to::module)`: visible only on the specified path"##;
let path = self.parse_path(PathStyle::Mod)?;
let path_span = self.prev_span;
let sp = self.prev_span;
let help_msg = format!("make this visible only to module `{}` with `in`", path);
self.expect(&token::CloseDelim(token::Paren))?; // `)`
let mut err = self.span_fatal_help(path_span, msg, suggestion);
let mut err = struct_span_err!(self.sess.span_diagnostic, sp, E0704, "{}", msg);
err.help(suggestion);
err.span_suggestion_with_applicability(
path_span, &help_msg, format!("in {}", path), Applicability::MachineApplicable
sp, &help_msg, format!("in {}", path), Applicability::MachineApplicable
);
err.emit(); // emit diagnostic, but continue with public visibility
}
Expand Down Expand Up @@ -6534,12 +6546,15 @@ impl<'a> Parser<'a> {
Some(abi) => Ok(Some(abi)),
None => {
let prev_span = self.prev_span;
self.span_err(
let mut err = struct_span_err!(
self.sess.span_diagnostic,
prev_span,
&format!("invalid ABI: expected one of [{}], \
found `{}`",
abi::all_names().join(", "),
s));
E0703,
"invalid ABI: found `{}`",
s);
err.span_label(prev_span, "invalid ABI");
err.help(&format!("valid ABIs: {}", abi::all_names().join(", ")));
err.emit();
Ok(None)
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/associated-types-unsized.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ trait Get {
}

fn foo<T:Get>(t: T) {
let x = t.get(); //~ ERROR `<T as Get>::Value: std::marker::Sized` is not
let x = t.get(); //~ ERROR the size for value values of type
}

fn main() {
Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/bad-method-typaram-kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// except according to those terms.

fn foo<T:'static>() {
1.bar::<T>(); //~ ERROR `T: std::marker::Send` is not satisfied
1.bar::<T>(); //~ ERROR `T` cannot be sent between threads safely
}

trait bar {
Expand Down
4 changes: 2 additions & 2 deletions src/test/compile-fail/bad-sized.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ trait Trait {}
pub fn main() {
let x: Vec<Trait + Sized> = Vec::new();
//~^ ERROR only auto traits can be used as additional traits in a trait object
//~| ERROR the trait bound `Trait: std::marker::Sized` is not satisfied
//~| ERROR the trait bound `Trait: std::marker::Sized` is not satisfied
//~| ERROR the size for value values of type
//~| ERROR the size for value values of type
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
trait Foo : Send+Sync { }

impl <T: Sync+'static> Foo for (T,) { }
//~^ ERROR the trait bound `T: std::marker::Send` is not satisfied in `(T,)` [E0277]
//~^ ERROR `T` cannot be sent between threads safely [E0277]

impl <T: Send> Foo for (T,T) { }
//~^ ERROR `T` cannot be shared between threads safely [E0277]
Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/builtin-superkinds-in-metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ struct X<T>(T);
impl <T:Sync> RequiresShare for X<T> { }

impl <T:Sync+'static> RequiresRequiresShareAndSend for X<T> { }
//~^ ERROR `T: std::marker::Send` is not satisfied
//~^ ERROR `T` cannot be sent between threads safely [E0277]

fn main() { }
2 changes: 1 addition & 1 deletion src/test/compile-fail/builtin-superkinds-simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
trait Foo : Send { }

impl Foo for std::rc::Rc<i8> { }
//~^ ERROR `std::rc::Rc<i8>: std::marker::Send` is not satisfied
//~^ ERROR `std::rc::Rc<i8>` cannot be sent between threads safely

fn main() { }
3 changes: 2 additions & 1 deletion src/test/compile-fail/builtin-superkinds-typaram-not-send.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

trait Foo : Send { }

impl <T: Sync+'static> Foo for T { } //~ ERROR `T: std::marker::Send` is not satisfied
impl <T: Sync+'static> Foo for T { }
//~^ ERROR `T` cannot be sent between threads safely

fn main() { }
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ struct X<F> where F: FnOnce() + 'static + Send {
}

fn foo<F>(blk: F) -> X<F> where F: FnOnce() + 'static {
//~^ ERROR `F: std::marker::Send` is not satisfied
//~^ ERROR `F` cannot be sent between threads safely
return X { field: blk };
}

Expand Down
3 changes: 2 additions & 1 deletion src/test/compile-fail/dst-bad-assign-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,6 @@ pub fn main() {
let f5: &mut Fat<ToBar> = &mut Fat { f1: 5, f2: "some str", ptr: Bar1 {f :42} };
let z: Box<ToBar> = Box::new(Bar1 {f: 36});
f5.ptr = *z;
//~^ ERROR `ToBar: std::marker::Sized` is not satisfied
//~^ ERROR the size for value values of type

}
2 changes: 1 addition & 1 deletion src/test/compile-fail/dst-bad-assign-3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,5 @@ pub fn main() {
//~| expected type `ToBar`
//~| found type `Bar1`
//~| expected trait ToBar, found struct `Bar1`
//~| ERROR `ToBar: std::marker::Sized` is not satisfied
//~| ERROR the size for value values of type
}
2 changes: 1 addition & 1 deletion src/test/compile-fail/dst-bad-assign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,5 @@ pub fn main() {
//~| expected type `ToBar`
//~| found type `Bar1`
//~| expected trait ToBar, found struct `Bar1`
//~| ERROR `ToBar: std::marker::Sized` is not satisfied
//~| ERROR the size for value values of type
}
2 changes: 1 addition & 1 deletion src/test/compile-fail/dst-bad-deep-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ pub fn main() {
let f: ([isize; 3],) = ([5, 6, 7],);
let g: &([isize],) = &f;
let h: &(([isize],),) = &(*g,);
//~^ ERROR `[isize]: std::marker::Sized` is not satisfied
//~^ ERROR the size for value values of type
}
2 changes: 1 addition & 1 deletion src/test/compile-fail/dst-bad-deep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ pub fn main() {
let f: Fat<[isize; 3]> = Fat { ptr: [5, 6, 7] };
let g: &Fat<[isize]> = &f;
let h: &Fat<Fat<[isize]>> = &Fat { ptr: *g };
//~^ ERROR `[isize]: std::marker::Sized` is not satisfied
//~^ ERROR the size for value values of type
}
8 changes: 4 additions & 4 deletions src/test/compile-fail/dst-object-from-unsized-type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,22 @@ impl Foo for [u8] {}

fn test1<T: ?Sized + Foo>(t: &T) {
let u: &Foo = t;
//~^ ERROR `T: std::marker::Sized` is not satisfied
//~^ ERROR the size for value values of type
}

fn test2<T: ?Sized + Foo>(t: &T) {
let v: &Foo = t as &Foo;
//~^ ERROR `T: std::marker::Sized` is not satisfied
//~^ ERROR the size for value values of type
}

fn test3() {
let _: &[&Foo] = &["hi"];
//~^ ERROR `str: std::marker::Sized` is not satisfied
//~^ ERROR the size for value values of type
}

fn test4(x: &[u8]) {
let _: &Foo = x as &Foo;
//~^ ERROR `[u8]: std::marker::Sized` is not satisfied
//~^ ERROR the size for value values of type
}

fn main() { }
4 changes: 2 additions & 2 deletions src/test/compile-fail/dst-sized-trait-param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
trait Foo<T> : Sized { fn take(self, x: &T) { } } // Note: T is sized

impl Foo<[isize]> for usize { }
//~^ ERROR `[isize]: std::marker::Sized` is not satisfied
//~^ ERROR the size for value values of type

impl Foo<isize> for [usize] { }
//~^ ERROR `[usize]: std::marker::Sized` is not satisfied
//~^ ERROR the size for value values of type

pub fn main() { }
2 changes: 1 addition & 1 deletion src/test/compile-fail/extern-types-not-sync-send.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@ fn main() {
//~^ ERROR `A` cannot be shared between threads safely [E0277]

assert_send::<A>();
//~^ ERROR the trait bound `A: std::marker::Send` is not satisfied
//~^ ERROR `A` cannot be sent between threads safely [E0277]
}
8 changes: 4 additions & 4 deletions src/test/compile-fail/extern-types-unsized.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ fn assert_sized<T>() { }

fn main() {
assert_sized::<A>();
//~^ ERROR the trait bound `A: std::marker::Sized` is not satisfied
//~^ ERROR the size for value values of type

assert_sized::<Foo>();
//~^ ERROR the trait bound `A: std::marker::Sized` is not satisfied
//~^ ERROR the size for value values of type

assert_sized::<Bar<A>>();
//~^ ERROR the trait bound `A: std::marker::Sized` is not satisfied
//~^ ERROR the size for value values of type

assert_sized::<Bar<Bar<A>>>();
//~^ ERROR the trait bound `A: std::marker::Sized` is not satisfied
//~^ ERROR the size for value values of type
}

0 comments on commit 4b17d31

Please sign in to comment.