diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 6c8a1c3062b00..8ad5a9861a02f 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -530,9 +530,12 @@ impl<'a> Display for Arguments<'a> { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "`{Self}` cannot be formatted using `:?`; if it is \ - defined in your crate, add `#[derive(Debug)]` or \ - manually implement it"] +#[rustc_on_unimplemented( + on(crate_local, label="`{Self}` cannot be formatted using `:?`; \ + add `#[derive(Debug)]` or manually implement `{Debug}`"), + message="`{Self}` doesn't implement `{Debug}`", + label="`{Self}` cannot be formatted using `:?` because it doesn't implement `{Debug}`", +)] #[lang = "debug_trait"] pub trait Debug { /// Formats the value using the given formatter. @@ -593,9 +596,11 @@ pub trait Debug { /// /// println!("The origin is: {}", origin); /// ``` -#[rustc_on_unimplemented = "`{Self}` cannot be formatted with the default \ - formatter; try using `:?` instead if you are using \ - a format string"] +#[rustc_on_unimplemented( + message="`{Self}` doesn't implement `{Display}`", + label="`{Self}` cannot be formatted with the default formatter; \ + try using `:?` instead if you are using a format string", +)] #[stable(feature = "rust1", since = "1.0.0")] pub trait Display { /// Formats the value using the given formatter. diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 35cd7441c66bc..296fb8733ba6c 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -28,8 +28,13 @@ fn _assert_is_object_safe(_: &Iterator) {} /// [module-level documentation]: index.html /// [impl]: index.html#implementing-iterator #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "`{Self}` is not an iterator; maybe try calling \ - `.iter()` or a similar method"] +#[rustc_on_unimplemented( + on( + _Self="&str", + label="`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`" + ), + label="`{Self}` is not an iterator; maybe try calling `.iter()` or a similar method" +)] #[doc(spotlight)] pub trait Iterator { /// The type of the elements being iterated over. diff --git a/src/libcore/ops/arith.rs b/src/libcore/ops/arith.rs index 8b3d662a6db77..d0d0c09869e9d 100644 --- a/src/libcore/ops/arith.rs +++ b/src/libcore/ops/arith.rs @@ -75,7 +75,18 @@ /// ``` #[lang = "add"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} + {RHS}`"] +#[rustc_on_unimplemented( + on( + all(_Self="{integer}", RHS="{float}"), + message="cannot add a float to an integer", + ), + on( + all(_Self="{float}", RHS="{integer}"), + message="cannot add an integer to a float", + ), + message="cannot add `{RHS}` to `{Self}`", + label="no implementation for `{Self} + {RHS}`", +)] pub trait Add { /// The resulting type after applying the `+` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -170,7 +181,8 @@ add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } /// ``` #[lang = "sub"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} - {RHS}`"] +#[rustc_on_unimplemented(message="cannot substract `{RHS}` from `{Self}`", + label="no implementation for `{Self} - {RHS}`")] pub trait Sub { /// The resulting type after applying the `-` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -287,7 +299,8 @@ sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } /// ``` #[lang = "mul"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} * {RHS}`"] +#[rustc_on_unimplemented(message="cannot multiply `{RHS}` to `{Self}`", + label="no implementation for `{Self} * {RHS}`")] pub trait Mul { /// The resulting type after applying the `*` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -408,7 +421,8 @@ mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } /// ``` #[lang = "div"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} / {RHS}`"] +#[rustc_on_unimplemented(message="cannot divide `{Self}` by `{RHS}`", + label="no implementation for `{Self} / {RHS}`")] pub trait Div { /// The resulting type after applying the `/` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -490,7 +504,8 @@ div_impl_float! { f32 f64 } /// ``` #[lang = "rem"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} % {RHS}`"] +#[rustc_on_unimplemented(message="cannot mod `{Self}` by `{RHS}`", + label="no implementation for `{Self} % {RHS}`")] pub trait Rem { /// The resulting type after applying the `%` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -647,7 +662,8 @@ neg_impl_numeric! { isize i8 i16 i32 i64 i128 f32 f64 } /// ``` #[lang = "add_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} += {Rhs}`"] +#[rustc_on_unimplemented(message="cannot add-assign `{Rhs}` to `{Self}`", + label="no implementation for `{Self} += {Rhs}`")] pub trait AddAssign { /// Performs the `+=` operation. #[stable(feature = "op_assign_traits", since = "1.8.0")] @@ -700,7 +716,8 @@ add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } /// ``` #[lang = "sub_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} -= {Rhs}`"] +#[rustc_on_unimplemented(message="cannot substract-assign `{Rhs}` from `{Self}`", + label="no implementation for `{Self} -= {Rhs}`")] pub trait SubAssign { /// Performs the `-=` operation. #[stable(feature = "op_assign_traits", since = "1.8.0")] @@ -744,7 +761,8 @@ sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } /// ``` #[lang = "mul_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} *= {Rhs}`"] +#[rustc_on_unimplemented(message="cannot multiply-assign `{Rhs}` to `{Self}`", + label="no implementation for `{Self} *= {Rhs}`")] pub trait MulAssign { /// Performs the `*=` operation. #[stable(feature = "op_assign_traits", since = "1.8.0")] @@ -788,7 +806,8 @@ mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } /// ``` #[lang = "div_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} /= {Rhs}`"] +#[rustc_on_unimplemented(message="cannot divide-assign `{Self}` by `{Rhs}`", + label="no implementation for `{Self} /= {Rhs}`")] pub trait DivAssign { /// Performs the `/=` operation. #[stable(feature = "op_assign_traits", since = "1.8.0")] @@ -835,7 +854,8 @@ div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } /// ``` #[lang = "rem_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} %= {Rhs}`"] +#[rustc_on_unimplemented(message="cannot mod-assign `{Self}` by `{Rhs}``", + label="no implementation for `{Self} %= {Rhs}`")] pub trait RemAssign { /// Performs the `%=` operation. #[stable(feature = "op_assign_traits", since = "1.8.0")] diff --git a/src/libcore/ops/bit.rs b/src/libcore/ops/bit.rs index 7ac5fc4debf14..a0ecd6cf75ce9 100644 --- a/src/libcore/ops/bit.rs +++ b/src/libcore/ops/bit.rs @@ -120,7 +120,8 @@ not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// ``` #[lang = "bitand"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} & {RHS}`"] +#[rustc_on_unimplemented(message="no implementation for `{Self} & {RHS}`", + label="no implementation for `{Self} & {RHS}`")] pub trait BitAnd { /// The resulting type after applying the `&` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -201,7 +202,8 @@ bitand_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// ``` #[lang = "bitor"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} | {RHS}`"] +#[rustc_on_unimplemented(message="no implementation for `{Self} | {RHS}`", + label="no implementation for `{Self} | {RHS}`")] pub trait BitOr { /// The resulting type after applying the `|` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -285,7 +287,8 @@ bitor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// ``` #[lang = "bitxor"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} ^ {RHS}`"] +#[rustc_on_unimplemented(message="no implementation for `{Self} ^ {RHS}`", + label="no implementation for `{Self} ^ {RHS}`")] pub trait BitXor { /// The resulting type after applying the `^` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -365,7 +368,8 @@ bitxor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// ``` #[lang = "shl"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} << {RHS}`"] +#[rustc_on_unimplemented(message="no implementation for `{Self} << {RHS}`", + label="no implementation for `{Self} << {RHS}`")] pub trait Shl { /// The resulting type after applying the `<<` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -466,7 +470,8 @@ shl_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 isize i128 } /// ``` #[lang = "shr"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} >> {RHS}`"] +#[rustc_on_unimplemented(message="no implementation for `{Self} >> {RHS}`", + label="no implementation for `{Self} >> {RHS}`")] pub trait Shr { /// The resulting type after applying the `>>` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -579,7 +584,8 @@ shr_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize } /// ``` #[lang = "bitand_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} &= {Rhs}`"] +#[rustc_on_unimplemented(message="no implementation for `{Self} &= {Rhs}`", + label="no implementation for `{Self} &= {Rhs}`")] pub trait BitAndAssign { /// Performs the `&=` operation. #[stable(feature = "op_assign_traits", since = "1.8.0")] @@ -626,7 +632,8 @@ bitand_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// ``` #[lang = "bitor_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} |= {Rhs}`"] +#[rustc_on_unimplemented(message="no implementation for `{Self} |= {Rhs}`", + label="no implementation for `{Self} |= {Rhs}`")] pub trait BitOrAssign { /// Performs the `|=` operation. #[stable(feature = "op_assign_traits", since = "1.8.0")] @@ -673,7 +680,8 @@ bitor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// ``` #[lang = "bitxor_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} ^= {Rhs}`"] +#[rustc_on_unimplemented(message="no implementation for `{Self} ^= {Rhs}`", + label="no implementation for `{Self} ^= {Rhs}`")] pub trait BitXorAssign { /// Performs the `^=` operation. #[stable(feature = "op_assign_traits", since = "1.8.0")] @@ -718,7 +726,8 @@ bitxor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// ``` #[lang = "shl_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} <<= {Rhs}`"] +#[rustc_on_unimplemented(message="no implementation for `{Self} <<= {Rhs}`", + label="no implementation for `{Self} <<= {Rhs}`")] pub trait ShlAssign { /// Performs the `<<=` operation. #[stable(feature = "op_assign_traits", since = "1.8.0")] @@ -784,7 +793,8 @@ shl_assign_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize } /// ``` #[lang = "shr_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} >>= {Rhs}`"] +#[rustc_on_unimplemented(message="no implementation for `{Self} >>= {Rhs}`", + label="no implementation for `{Self} >>= {Rhs}`")] pub trait ShrAssign { /// Performs the `>>=` operation. #[stable(feature = "op_assign_traits", since = "1.8.0")] diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 7b86791026b41..d4bcf00be8089 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -348,7 +348,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { if direct { // this is a "direct", user-specified, rather than derived, // obligation. - flags.push(("direct", None)); + flags.push(("direct".to_string(), None)); } if let ObligationCauseCode::ItemObligation(item) = obligation.cause.code { @@ -359,21 +359,37 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // Currently I'm leaving it for what I need for `try`. if self.tcx.trait_of_item(item) == Some(trait_ref.def_id) { method = self.tcx.item_name(item); - flags.push(("from_method", None)); - flags.push(("from_method", Some(&*method))); + flags.push(("from_method".to_string(), None)); + flags.push(("from_method".to_string(), Some(method.to_string()))); } } if let Some(k) = obligation.cause.span.compiler_desugaring_kind() { desugaring = k.as_symbol().as_str(); - flags.push(("from_desugaring", None)); - flags.push(("from_desugaring", Some(&*desugaring))); + flags.push(("from_desugaring".to_string(), None)); + flags.push(("from_desugaring".to_string(), Some(desugaring.to_string()))); + } + let generics = self.tcx.generics_of(def_id); + let self_ty = trait_ref.self_ty(); + let self_ty_str = self_ty.to_string(); + flags.push(("_Self".to_string(), Some(self_ty_str.clone()))); + + for param in generics.types.iter() { + let name = param.name.as_str().to_string(); + let ty = trait_ref.substs.type_for_def(param); + let ty_str = ty.to_string(); + flags.push((name.clone(), + Some(ty_str.clone()))); + } + + if let Some(true) = self_ty.ty_to_def_id().map(|def_id| def_id.is_local()) { + flags.push(("crate_local".to_string(), None)); } if let Ok(Some(command)) = OnUnimplementedDirective::of_item( self.tcx, trait_ref.def_id, def_id ) { - command.evaluate(self.tcx, trait_ref, &flags) + command.evaluate(self.tcx, trait_ref, &flags[..]) } else { OnUnimplementedNote::empty() } @@ -549,7 +565,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { .map(|t| (format!(" in `{}`", t), format!("within `{}`, ", t))) .unwrap_or((String::new(), String::new())); - let OnUnimplementedNote { message, label } + let OnUnimplementedNote { message, label, note } = self.on_unimplemented_note(trait_ref, obligation); let have_alt_message = message.is_some() || label.is_some(); @@ -578,6 +594,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { trait_ref, trait_ref.self_ty())); } + if let Some(ref s) = note { + // If it has a custom "#[rustc_on_unimplemented]" note, let's display it + err.note(s.as_str()); + } self.suggest_borrow_on_unsized_slice(&obligation.cause.code, &mut err); diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs index 757b078086d9c..8c2c1cfa45472 100644 --- a/src/librustc/traits/on_unimplemented.rs +++ b/src/librustc/traits/on_unimplemented.rs @@ -29,16 +29,18 @@ pub struct OnUnimplementedDirective { pub subcommands: Vec, pub message: Option, pub label: Option, + pub note: Option, } pub struct OnUnimplementedNote { pub message: Option, pub label: Option, + pub note: Option, } impl OnUnimplementedNote { pub fn empty() -> Self { - OnUnimplementedNote { message: None, label: None } + OnUnimplementedNote { message: None, label: None, note: None } } } @@ -89,6 +91,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective { let mut message = None; let mut label = None; + let mut note = None; let mut subcommands = vec![]; for item in item_iter { if item.check_name("message") && message.is_none() { @@ -103,8 +106,14 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective { tcx, trait_def_id, label_.as_str(), span)?); continue; } + } else if item.check_name("note") && note.is_none() { + if let Some(note_) = item.value_str() { + note = Some(OnUnimplementedFormatString::try_parse( + tcx, trait_def_id, note_.as_str(), span)?); + continue; + } } else if item.check_name("on") && is_root && - message.is_none() && label.is_none() + message.is_none() && label.is_none() && note.is_none() { if let Some(items) = item.meta_item_list() { if let Ok(subcommand) = @@ -128,7 +137,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective { if errored { Err(ErrorReported) } else { - Ok(OnUnimplementedDirective { condition, message, label, subcommands }) + Ok(OnUnimplementedDirective { condition, message, label, subcommands, note }) } } @@ -154,7 +163,8 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective { message: None, subcommands: vec![], label: Some(OnUnimplementedFormatString::try_parse( - tcx, trait_def_id, value.as_str(), attr.span)?) + tcx, trait_def_id, value.as_str(), attr.span)?), + note: None, })) } else { return Err(parse_error(tcx, attr.span, @@ -169,20 +179,20 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective { pub fn evaluate(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, trait_ref: ty::TraitRef<'tcx>, - options: &[(&str, Option<&str>)]) + options: &[(String, Option)]) -> OnUnimplementedNote { let mut message = None; let mut label = None; - info!("evaluate({:?}, trait_ref={:?}, options={:?})", - self, trait_ref, options); + let mut note = None; + info!("evaluate({:?}, trait_ref={:?}, options={:?})", self, trait_ref, options); for command in self.subcommands.iter().chain(Some(self)).rev() { if let Some(ref condition) = command.condition { if !attr::eval_condition(condition, &tcx.sess.parse_sess, &mut |c| { - options.contains(&(&c.name().as_str(), - match c.value_str().map(|s| s.as_str()) { - Some(ref s) => Some(s), + options.contains(&(c.name().as_str().to_string(), + match c.value_str().map(|s| s.as_str().to_string()) { + Some(s) => Some(s), None => None })) }) { @@ -198,11 +208,16 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective { if let Some(ref label_) = command.label { label = Some(label_.clone()); } + + if let Some(ref note_) = command.note { + note = Some(note_.clone()); + } } OnUnimplementedNote { label: label.map(|l| l.format(tcx, trait_ref)), - message: message.map(|m| m.format(tcx, trait_ref)) + message: message.map(|m| m.format(tcx, trait_ref)), + note: note.map(|n| n.format(tcx, trait_ref)), } } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 764b3d0a848ee..dc3745fc4a3ee 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -761,6 +761,18 @@ impl<'a> Parser<'a> { }) } + fn expected_ident_found(&self) -> DiagnosticBuilder<'a> { + let mut err = self.struct_span_err(self.span, + &format!("expected identifier, found {}", + self.this_token_descr())); + if let Some(token_descr) = self.token_descr() { + err.span_label(self.span, format!("expected identifier, found {}", token_descr)); + } else { + err.span_label(self.span, "expected identifier"); + } + err + } + pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> { self.parse_ident_common(true) } @@ -769,15 +781,7 @@ impl<'a> Parser<'a> { match self.token { token::Ident(i) => { if self.token.is_reserved_ident() { - let mut err = self.struct_span_err(self.span, - &format!("expected identifier, found {}", - self.this_token_descr())); - if let Some(token_descr) = self.token_descr() { - err.span_label(self.span, format!("expected identifier, found {}", - token_descr)); - } else { - err.span_label(self.span, "expected identifier"); - } + let mut err = self.expected_ident_found(); if recover { err.emit(); } else { @@ -791,14 +795,7 @@ impl<'a> Parser<'a> { Err(if self.prev_token_kind == PrevTokenKind::DocComment { self.span_fatal_err(self.prev_span, Error::UselessDocComment) } else { - let mut err = self.fatal(&format!("expected identifier, found `{}`", - self.this_token_to_string())); - if let Some(token_descr) = self.token_descr() { - err.span_label(self.span, format!("expected identifier, found {}", - token_descr)); - } else { - err.span_label(self.span, "expected identifier"); - } + let mut err = self.expected_ident_found(); if self.token == token::Underscore { err.note("`_` is a wildcard pattern, not an identifier"); } diff --git a/src/test/compile-fail/const-eval-overflow-4b.rs b/src/test/compile-fail/const-eval-overflow-4b.rs index 02072e9a1a1f6..6028df1883967 100644 --- a/src/test/compile-fail/const-eval-overflow-4b.rs +++ b/src/test/compile-fail/const-eval-overflow-4b.rs @@ -22,7 +22,7 @@ const A_I8_T : [u32; (i8::MAX as i8 + 1u8) as usize] //~^ ERROR mismatched types //~| expected i8, found u8 - //~| ERROR the trait bound `i8: std::ops::Add` is not satisfied + //~| ERROR cannot add `u8` to `i8` = [0; (i8::MAX as usize) + 1]; diff --git a/src/test/compile-fail/ufcs-qpath-self-mismatch.rs b/src/test/compile-fail/ufcs-qpath-self-mismatch.rs index 94a98b1582af1..caf510071bd68 100644 --- a/src/test/compile-fail/ufcs-qpath-self-mismatch.rs +++ b/src/test/compile-fail/ufcs-qpath-self-mismatch.rs @@ -12,7 +12,7 @@ use std::ops::Add; fn main() { >::add(1, 2); - //~^ ERROR `i32: std::ops::Add` is not satisfied + //~^ ERROR cannot add `u32` to `i32` >::add(1u32, 2); //~^ ERROR mismatched types >::add(1, 2u32); diff --git a/src/test/ui/impl-trait/equality.rs b/src/test/ui/impl-trait/equality.rs index 36df4f0eb4d46..9d9d4cef3119a 100644 --- a/src/test/ui/impl-trait/equality.rs +++ b/src/test/ui/impl-trait/equality.rs @@ -32,7 +32,7 @@ fn sum_to(n: u32) -> impl Foo { 0 } else { n + sum_to(n - 1) - //~^ ERROR the trait bound `u32: std::ops::Add` is not satisfied + //~^ ERROR cannot add `impl Foo` to `u32` } } diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr index 3fc08a0900fb9..8ec819038031b 100644 --- a/src/test/ui/impl-trait/equality.stderr +++ b/src/test/ui/impl-trait/equality.stderr @@ -7,7 +7,7 @@ error[E0308]: mismatched types = note: expected type `i32` found type `u32` -error[E0277]: the trait bound `u32: std::ops::Add` is not satisfied +error[E0277]: cannot add `impl Foo` to `u32` --> $DIR/equality.rs:34:11 | 34 | n + sum_to(n - 1) diff --git a/src/test/ui/mismatched_types/binops.rs b/src/test/ui/mismatched_types/binops.rs index e45616cd67a81..5144b59955cc9 100644 --- a/src/test/ui/mismatched_types/binops.rs +++ b/src/test/ui/mismatched_types/binops.rs @@ -9,10 +9,10 @@ // except according to those terms. fn main() { - 1 + Some(1); //~ ERROR is not satisfied - 2 as usize - Some(1); //~ ERROR is not satisfied - 3 * (); //~ ERROR is not satisfied - 4 / ""; //~ ERROR is not satisfied + 1 + Some(1); //~ ERROR cannot add `std::option::Option<{integer}>` to `{integer}` + 2 as usize - Some(1); //~ ERROR cannot substract `std::option::Option<{integer}>` from `usize` + 3 * (); //~ ERROR cannot multiply `()` to `{integer}` + 4 / ""; //~ ERROR cannot divide `{integer}` by `&str` 5 < String::new(); //~ ERROR is not satisfied 6 == Ok(1); //~ ERROR is not satisfied } diff --git a/src/test/ui/mismatched_types/binops.stderr b/src/test/ui/mismatched_types/binops.stderr index 8541ad52e0177..1b7fba050636f 100644 --- a/src/test/ui/mismatched_types/binops.stderr +++ b/src/test/ui/mismatched_types/binops.stderr @@ -1,31 +1,31 @@ -error[E0277]: the trait bound `{integer}: std::ops::Add>` is not satisfied +error[E0277]: cannot add `std::option::Option<{integer}>` to `{integer}` --> $DIR/binops.rs:12:7 | -12 | 1 + Some(1); //~ ERROR is not satisfied +12 | 1 + Some(1); //~ ERROR cannot add `std::option::Option<{integer}>` to `{integer}` | ^ no implementation for `{integer} + std::option::Option<{integer}>` | = help: the trait `std::ops::Add>` is not implemented for `{integer}` -error[E0277]: the trait bound `usize: std::ops::Sub>` is not satisfied +error[E0277]: cannot substract `std::option::Option<{integer}>` from `usize` --> $DIR/binops.rs:13:16 | -13 | 2 as usize - Some(1); //~ ERROR is not satisfied +13 | 2 as usize - Some(1); //~ ERROR cannot substract `std::option::Option<{integer}>` from `usize` | ^ no implementation for `usize - std::option::Option<{integer}>` | = help: the trait `std::ops::Sub>` is not implemented for `usize` -error[E0277]: the trait bound `{integer}: std::ops::Mul<()>` is not satisfied +error[E0277]: cannot multiply `()` to `{integer}` --> $DIR/binops.rs:14:7 | -14 | 3 * (); //~ ERROR is not satisfied +14 | 3 * (); //~ ERROR cannot multiply `()` to `{integer}` | ^ no implementation for `{integer} * ()` | = help: the trait `std::ops::Mul<()>` is not implemented for `{integer}` -error[E0277]: the trait bound `{integer}: std::ops::Div<&str>` is not satisfied +error[E0277]: cannot divide `{integer}` by `&str` --> $DIR/binops.rs:15:7 | -15 | 4 / ""; //~ ERROR is not satisfied +15 | 4 / ""; //~ ERROR cannot divide `{integer}` by `&str` | ^ no implementation for `{integer} / &str` | = help: the trait `std::ops::Div<&str>` is not implemented for `{integer}` diff --git a/src/test/ui/on-unimplemented/auxiliary/no_debug.rs b/src/test/ui/on-unimplemented/auxiliary/no_debug.rs new file mode 100644 index 0000000000000..0f833c6263722 --- /dev/null +++ b/src/test/ui/on-unimplemented/auxiliary/no_debug.rs @@ -0,0 +1,14 @@ +// Copyright 2018 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. +// ignore-tidy-linelength + +#![crate_type = "lib"] + +pub struct Bar; diff --git a/src/test/ui/on-unimplemented/no-debug.rs b/src/test/ui/on-unimplemented/no-debug.rs new file mode 100644 index 0000000000000..fff6122c6b34b --- /dev/null +++ b/src/test/ui/on-unimplemented/no-debug.rs @@ -0,0 +1,27 @@ +// Copyright 2018 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. + +// aux-build:no_debug.rs + +extern crate no_debug; + +use no_debug::Bar; + +struct Foo; + +fn main() { + println!("{:?} {:?}", Foo, Bar); + println!("{} {}", Foo, Bar); +} +//~^^^ ERROR `Foo` doesn't implement `std::fmt::Debug` +//~| ERROR `no_debug::Bar` doesn't implement `std::fmt::Debug` +//~^^^^ ERROR `Foo` doesn't implement `std::fmt::Display` +//~| ERROR `no_debug::Bar` doesn't implement `std::fmt::Display` + diff --git a/src/test/ui/on-unimplemented/no-debug.stderr b/src/test/ui/on-unimplemented/no-debug.stderr new file mode 100644 index 0000000000000..af5b1e91211fb --- /dev/null +++ b/src/test/ui/on-unimplemented/no-debug.stderr @@ -0,0 +1,38 @@ +error[E0277]: `Foo` doesn't implement `std::fmt::Debug` + --> $DIR/no-debug.rs:20:27 + | +20 | println!("{:?} {:?}", Foo, Bar); + | ^^^ `Foo` cannot be formatted using `:?`; add `#[derive(Debug)]` or manually implement `std::fmt::Debug` + | + = help: the trait `std::fmt::Debug` is not implemented for `Foo` + = note: required by `std::fmt::Debug::fmt` + +error[E0277]: `no_debug::Bar` doesn't implement `std::fmt::Debug` + --> $DIR/no-debug.rs:20:32 + | +20 | println!("{:?} {:?}", Foo, Bar); + | ^^^ `no_debug::Bar` cannot be formatted using `:?` because it doesn't implement `std::fmt::Debug` + | + = help: the trait `std::fmt::Debug` is not implemented for `no_debug::Bar` + = note: required by `std::fmt::Debug::fmt` + +error[E0277]: `Foo` doesn't implement `std::fmt::Display` + --> $DIR/no-debug.rs:21:23 + | +21 | println!("{} {}", Foo, Bar); + | ^^^ `Foo` cannot be formatted with the default formatter; try using `:?` instead if you are using a format string + | + = help: the trait `std::fmt::Display` is not implemented for `Foo` + = note: required by `std::fmt::Display::fmt` + +error[E0277]: `no_debug::Bar` doesn't implement `std::fmt::Display` + --> $DIR/no-debug.rs:21:28 + | +21 | println!("{} {}", Foo, Bar); + | ^^^ `no_debug::Bar` cannot be formatted with the default formatter; try using `:?` instead if you are using a format string + | + = help: the trait `std::fmt::Display` is not implemented for `no_debug::Bar` + = note: required by `std::fmt::Display::fmt` + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/span/multiline-span-simple.rs b/src/test/ui/span/multiline-span-simple.rs index f8e4cbcbf191f..dd09534480e10 100644 --- a/src/test/ui/span/multiline-span-simple.rs +++ b/src/test/ui/span/multiline-span-simple.rs @@ -20,7 +20,7 @@ fn main() { let x = 1; let y = 2; let z = 3; - foo(1 as u32 + //~ ERROR not satisfied + foo(1 as u32 + //~ ERROR cannot add `()` to `u32` bar(x, diff --git a/src/test/ui/span/multiline-span-simple.stderr b/src/test/ui/span/multiline-span-simple.stderr index b068798630ed8..a18dfeb31d9ef 100644 --- a/src/test/ui/span/multiline-span-simple.stderr +++ b/src/test/ui/span/multiline-span-simple.stderr @@ -1,7 +1,7 @@ -error[E0277]: the trait bound `u32: std::ops::Add<()>` is not satisfied +error[E0277]: cannot add `()` to `u32` --> $DIR/multiline-span-simple.rs:23:18 | -23 | foo(1 as u32 + //~ ERROR not satisfied +23 | foo(1 as u32 + //~ ERROR cannot add `()` to `u32` | ^ no implementation for `u32 + ()` | = help: the trait `std::ops::Add<()>` is not implemented for `u32` diff --git a/src/test/ui/suggestions/for-c-in-str.stderr b/src/test/ui/suggestions/for-c-in-str.stderr index 7a6dc9a504029..88a7b1b49d62d 100644 --- a/src/test/ui/suggestions/for-c-in-str.stderr +++ b/src/test/ui/suggestions/for-c-in-str.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `&str: std::iter::Iterator` is not satisfied --> $DIR/for-c-in-str.rs:14:14 | 14 | for c in "asdf" { - | ^^^^^^ `&str` is not an iterator; maybe try calling `.iter()` or a similar method + | ^^^^^^ `&str` is not an iterator; try calling `.chars()` or `.bytes()` | = help: the trait `std::iter::Iterator` is not implemented for `&str` = note: required by `std::iter::IntoIterator::into_iter`