mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-24 07:44:10 +00:00
added missing implementation hint
This commit is contained in:
parent
4e5a155a93
commit
2f6945c776
@ -280,43 +280,67 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
op.node.as_str()));
|
||||
}
|
||||
}
|
||||
|
||||
let missing_trait = match op.node {
|
||||
hir::BiAdd => Some("std::ops::Add"),
|
||||
hir::BiSub => Some("std::ops::Sub"),
|
||||
hir::BiMul => Some("std::ops::Mul"),
|
||||
hir::BiDiv => Some("std::ops::Div"),
|
||||
hir::BiRem => Some("std::ops::Rem"),
|
||||
hir::BiBitAnd => Some("std::ops::BitAnd"),
|
||||
hir::BiBitOr => Some("std::ops::BitOr"),
|
||||
hir::BiShl => Some("std::ops::Shl"),
|
||||
hir::BiShr => Some("std::ops::Shr"),
|
||||
hir::BiEq | hir::BiNe => Some("std::cmp::PartialEq"),
|
||||
hir::BiLt | hir::BiLe | hir::BiGt | hir::BiGe =>
|
||||
Some("std::cmp::PartialOrd"),
|
||||
_ => None
|
||||
};
|
||||
|
||||
if let Some(missing_trait) = missing_trait {
|
||||
if missing_trait == "std::ops::Add" &&
|
||||
self.check_str_addition(expr, lhs_expr, rhs_expr, lhs_ty,
|
||||
rhs_ty, &mut err) {
|
||||
// This has nothing here because it means we did string
|
||||
// concatenation (e.g. "Hello " + "World!"). This means
|
||||
// we don't want the note in the else clause to be emitted
|
||||
} else if let ty::TyParam(_) = lhs_ty.sty {
|
||||
// FIXME: point to span of param
|
||||
err.note(
|
||||
&format!("`{}` might need a bound for `{}`",
|
||||
lhs_ty, missing_trait));
|
||||
} else {
|
||||
err.note(
|
||||
&format!("an implementation of `{}` might be missing for `{}`",
|
||||
missing_trait, lhs_ty));
|
||||
IsAssign::No => {
|
||||
let mut err = struct_span_err!(self.tcx.sess, expr.span, E0369,
|
||||
"binary operation `{}` cannot be applied to type `{}`",
|
||||
op.node.as_str(),
|
||||
lhs_ty);
|
||||
let missing_trait = match op.node {
|
||||
hir::BiAdd => Some("std::ops::Add"),
|
||||
hir::BiSub => Some("std::ops::Sub"),
|
||||
hir::BiMul => Some("std::ops::Mul"),
|
||||
hir::BiDiv => Some("std::ops::Div"),
|
||||
hir::BiRem => Some("std::ops::Rem"),
|
||||
hir::BiBitAnd => Some("std::ops::BitAnd"),
|
||||
hir::BiBitXor => Some("std::ops::BitXor"),
|
||||
hir::BiBitOr => Some("std::ops::BitOr"),
|
||||
hir::BiShl => Some("std::ops::Shl"),
|
||||
hir::BiShr => Some("std::ops::Shr"),
|
||||
hir::BiEq | hir::BiNe => Some("std::cmp::PartialEq"),
|
||||
hir::BiLt | hir::BiLe | hir::BiGt | hir::BiGe =>
|
||||
Some("std::cmp::PartialOrd"),
|
||||
_ => None
|
||||
};
|
||||
if let TypeVariants::TyRef(_, ref ty_mut) = lhs_ty.sty {
|
||||
if {
|
||||
!self.infcx.type_moves_by_default(self.param_env,
|
||||
ty_mut.ty,
|
||||
lhs_expr.span) &&
|
||||
self.lookup_op_method(ty_mut.ty,
|
||||
&[rhs_ty],
|
||||
Op::Binary(op, is_assign))
|
||||
.is_ok()
|
||||
} {
|
||||
err.note(
|
||||
&format!(
|
||||
"this is a reference to a type that `{}` can be \
|
||||
applied to; you need to dereference this variable \
|
||||
once for this operation to work",
|
||||
op.node.as_str()));
|
||||
}
|
||||
}
|
||||
(err, missing_trait)
|
||||
}
|
||||
};
|
||||
if let Some(missing_trait) = missing_trait {
|
||||
if missing_trait == "std::ops::Add" &&
|
||||
self.check_str_addition(expr, lhs_expr, rhs_expr, lhs_ty,
|
||||
rhs_ty, &mut err) {
|
||||
// This has nothing here because it means we did string
|
||||
// concatenation (e.g. "Hello " + "World!"). This means
|
||||
// we don't want the note in the else clause to be emitted
|
||||
} else if let ty::TyParam(_) = lhs_ty.sty {
|
||||
// FIXME: point to span of param
|
||||
err.note(
|
||||
&format!("`{}` might need a bound for `{}`",
|
||||
lhs_ty, missing_trait));
|
||||
} else {
|
||||
err.note(
|
||||
&format!("an implementation of `{}` might be missing for `{}`",
|
||||
missing_trait, lhs_ty));
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
self.tcx.types.err
|
||||
}
|
||||
@ -393,9 +417,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
Err(()) => {
|
||||
let actual = self.resolve_type_vars_if_possible(&operand_ty);
|
||||
if !actual.references_error() {
|
||||
struct_span_err!(self.tcx.sess, ex.span, E0600,
|
||||
let mut err = struct_span_err!(self.tcx.sess, ex.span, E0600,
|
||||
"cannot apply unary operator `{}` to type `{}`",
|
||||
op.as_str(), actual).emit();
|
||||
op.as_str(), actual);
|
||||
let missing_trait = match op {
|
||||
hir::UnNeg => "std::ops::Neg",
|
||||
hir::UnNot => "std::ops::Not",
|
||||
hir::UnDeref => "std::ops::UnDerf"
|
||||
};
|
||||
err.note(&format!("an implementation of `{}` might be missing for `{}`",
|
||||
missing_trait, operand_ty));
|
||||
err.emit();
|
||||
}
|
||||
self.tcx.types.err
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ error[E0600]: cannot apply unary operator `!` to type `&'static str`
|
||||
|
|
||||
LL | assert!("foo");
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: an implementation of `std::ops::Not` might be missing for `&'static str`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -5,6 +5,8 @@ LL | LinkedList::new() += 1; //~ ERROR E0368
|
||||
| -----------------^^^^^
|
||||
| |
|
||||
| cannot use `+=` on type `std::collections::LinkedList<_>`
|
||||
|
|
||||
= note: an implementation of `std::ops::AddAssign` might be missing for `std::collections::LinkedList<_>`
|
||||
|
||||
error[E0067]: invalid left-hand side expression
|
||||
--> $DIR/E0067.rs:14:5
|
||||
|
@ -3,6 +3,8 @@ error[E0600]: cannot apply unary operator `!` to type `&'static str`
|
||||
|
|
||||
LL | !"a"; //~ ERROR E0600
|
||||
| ^^^^
|
||||
|
|
||||
= note: an implementation of `std::ops::Not` might be missing for `&'static str`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -17,6 +17,8 @@ LL | x += 2;
|
||||
| -^^^^^
|
||||
| |
|
||||
| cannot use `+=` on type `&str`
|
||||
|
|
||||
= note: an implementation of `std::ops::AddAssign` might be missing for `&str`
|
||||
|
||||
error[E0599]: no method named `z` found for type `&str` in the current scope
|
||||
--> $DIR/error-festival.rs:26:7
|
||||
@ -29,6 +31,8 @@ error[E0600]: cannot apply unary operator `!` to type `Question`
|
||||
|
|
||||
LL | !Question::Yes;
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: an implementation of `std::ops::Not` might be missing for `Question`
|
||||
|
||||
error[E0604]: only `u8` can be cast as `char`, not `u32`
|
||||
--> $DIR/error-festival.rs:35:5
|
||||
|
@ -3,12 +3,16 @@ error[E0600]: cannot apply unary operator `-` to type `usize`
|
||||
|
|
||||
LL | let _max: usize = -1;
|
||||
| ^^
|
||||
|
|
||||
= note: an implementation of `std::ops::Neg` might be missing for `usize`
|
||||
|
||||
error[E0600]: cannot apply unary operator `-` to type `u8`
|
||||
--> $DIR/feature-gate-negate-unsigned.rs:24:14
|
||||
|
|
||||
LL | let _y = -x;
|
||||
| ^^
|
||||
|
|
||||
= note: an implementation of `std::ops::Neg` might be missing for `u8`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -5,6 +5,8 @@ LL | let x = |ref x: isize| { x += 1; };
|
||||
| -^^^^^
|
||||
| |
|
||||
| cannot use `+=` on type `&isize`
|
||||
|
|
||||
= note: an implementation of `std::ops::AddAssign` might be missing for `&isize`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -3,6 +3,8 @@ error[E0600]: cannot apply unary operator `!` to type `!`
|
||||
|
|
||||
LL | let x: ! = ! { return; }; //~ ERROR unreachable
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= note: an implementation of `std::ops::Not` might be missing for `!`
|
||||
|
||||
error: unreachable expression
|
||||
--> $DIR/expr_unary.rs:17:16
|
||||
|
Loading…
Reference in New Issue
Block a user