Rollup merge of #136315 - estebank:long-ty-binop, r=SparrowLii
Use short ty string for binop and unop errors ``` error[E0369]: cannot add `(..., ..., ..., ...)` to `(..., ..., ..., ...)` --> $DIR/binop.rs:10:7 | LL | x + x; | - ^ - (..., ..., ..., ...) | | | (..., ..., ..., ...) | = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' = note: consider using `--verbose` to print the full type name to the console ``` ``` error[E0600]: cannot apply unary operator `!` to type `(..., ..., ..., ...)` --> $DIR/binop.rs:14:5 | LL | !x; | ^^ cannot apply unary operator `!` | = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' = note: consider using `--verbose` to print the full type name to the console ``` CC #135919.
This commit is contained in:
commit
c2c4d5ebfb
3 changed files with 85 additions and 27 deletions
|
@ -306,6 +306,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
lang_item_for_op(self.tcx, Op::Binary(op, is_assign), op.span);
|
lang_item_for_op(self.tcx, Op::Binary(op, is_assign), op.span);
|
||||||
let missing_trait = trait_def_id
|
let missing_trait = trait_def_id
|
||||||
.map(|def_id| with_no_trimmed_paths!(self.tcx.def_path_str(def_id)));
|
.map(|def_id| with_no_trimmed_paths!(self.tcx.def_path_str(def_id)));
|
||||||
|
let mut path = None;
|
||||||
|
let lhs_ty_str = self.tcx.short_string(lhs_ty, &mut path);
|
||||||
|
let rhs_ty_str = self.tcx.short_string(rhs_ty, &mut path);
|
||||||
let (mut err, output_def_id) = match is_assign {
|
let (mut err, output_def_id) = match is_assign {
|
||||||
IsAssign::Yes => {
|
IsAssign::Yes => {
|
||||||
let mut err = struct_span_code_err!(
|
let mut err = struct_span_code_err!(
|
||||||
|
@ -314,11 +317,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
E0368,
|
E0368,
|
||||||
"binary assignment operation `{}=` cannot be applied to type `{}`",
|
"binary assignment operation `{}=` cannot be applied to type `{}`",
|
||||||
op.node.as_str(),
|
op.node.as_str(),
|
||||||
lhs_ty,
|
lhs_ty_str,
|
||||||
);
|
);
|
||||||
err.span_label(
|
err.span_label(
|
||||||
lhs_expr.span,
|
lhs_expr.span,
|
||||||
format!("cannot use `{}=` on type `{}`", op.node.as_str(), lhs_ty),
|
format!("cannot use `{}=` on type `{}`", op.node.as_str(), lhs_ty_str),
|
||||||
);
|
);
|
||||||
self.note_unmet_impls_on_type(&mut err, errors, false);
|
self.note_unmet_impls_on_type(&mut err, errors, false);
|
||||||
(err, None)
|
(err, None)
|
||||||
|
@ -326,41 +329,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
IsAssign::No => {
|
IsAssign::No => {
|
||||||
let message = match op.node {
|
let message = match op.node {
|
||||||
hir::BinOpKind::Add => {
|
hir::BinOpKind::Add => {
|
||||||
format!("cannot add `{rhs_ty}` to `{lhs_ty}`")
|
format!("cannot add `{rhs_ty_str}` to `{lhs_ty_str}`")
|
||||||
}
|
}
|
||||||
hir::BinOpKind::Sub => {
|
hir::BinOpKind::Sub => {
|
||||||
format!("cannot subtract `{rhs_ty}` from `{lhs_ty}`")
|
format!("cannot subtract `{rhs_ty_str}` from `{lhs_ty_str}`")
|
||||||
}
|
}
|
||||||
hir::BinOpKind::Mul => {
|
hir::BinOpKind::Mul => {
|
||||||
format!("cannot multiply `{lhs_ty}` by `{rhs_ty}`")
|
format!("cannot multiply `{lhs_ty_str}` by `{rhs_ty_str}`")
|
||||||
}
|
}
|
||||||
hir::BinOpKind::Div => {
|
hir::BinOpKind::Div => {
|
||||||
format!("cannot divide `{lhs_ty}` by `{rhs_ty}`")
|
format!("cannot divide `{lhs_ty_str}` by `{rhs_ty_str}`")
|
||||||
}
|
}
|
||||||
hir::BinOpKind::Rem => {
|
hir::BinOpKind::Rem => {
|
||||||
format!(
|
format!(
|
||||||
"cannot calculate the remainder of `{lhs_ty}` divided by `{rhs_ty}`"
|
"cannot calculate the remainder of `{lhs_ty_str}` divided by \
|
||||||
|
`{rhs_ty_str}`"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
hir::BinOpKind::BitAnd => {
|
hir::BinOpKind::BitAnd => {
|
||||||
format!("no implementation for `{lhs_ty} & {rhs_ty}`")
|
format!("no implementation for `{lhs_ty_str} & {rhs_ty_str}`")
|
||||||
}
|
}
|
||||||
hir::BinOpKind::BitXor => {
|
hir::BinOpKind::BitXor => {
|
||||||
format!("no implementation for `{lhs_ty} ^ {rhs_ty}`")
|
format!("no implementation for `{lhs_ty_str} ^ {rhs_ty_str}`")
|
||||||
}
|
}
|
||||||
hir::BinOpKind::BitOr => {
|
hir::BinOpKind::BitOr => {
|
||||||
format!("no implementation for `{lhs_ty} | {rhs_ty}`")
|
format!("no implementation for `{lhs_ty_str} | {rhs_ty_str}`")
|
||||||
}
|
}
|
||||||
hir::BinOpKind::Shl => {
|
hir::BinOpKind::Shl => {
|
||||||
format!("no implementation for `{lhs_ty} << {rhs_ty}`")
|
format!("no implementation for `{lhs_ty_str} << {rhs_ty_str}`")
|
||||||
}
|
}
|
||||||
hir::BinOpKind::Shr => {
|
hir::BinOpKind::Shr => {
|
||||||
format!("no implementation for `{lhs_ty} >> {rhs_ty}`")
|
format!("no implementation for `{lhs_ty_str} >> {rhs_ty_str}`")
|
||||||
}
|
}
|
||||||
_ => format!(
|
_ => format!(
|
||||||
"binary operation `{}` cannot be applied to type `{}`",
|
"binary operation `{}` cannot be applied to type `{}`",
|
||||||
op.node.as_str(),
|
op.node.as_str(),
|
||||||
lhs_ty
|
lhs_ty_str,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
let output_def_id = trait_def_id.and_then(|def_id| {
|
let output_def_id = trait_def_id.and_then(|def_id| {
|
||||||
|
@ -375,14 +379,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let mut err =
|
let mut err =
|
||||||
struct_span_code_err!(self.dcx(), op.span, E0369, "{message}");
|
struct_span_code_err!(self.dcx(), op.span, E0369, "{message}");
|
||||||
if !lhs_expr.span.eq(&rhs_expr.span) {
|
if !lhs_expr.span.eq(&rhs_expr.span) {
|
||||||
err.span_label(lhs_expr.span, lhs_ty.to_string());
|
err.span_label(lhs_expr.span, lhs_ty_str.clone());
|
||||||
err.span_label(rhs_expr.span, rhs_ty.to_string());
|
err.span_label(rhs_expr.span, rhs_ty_str);
|
||||||
}
|
}
|
||||||
let suggest_derive = self.can_eq(self.param_env, lhs_ty, rhs_ty);
|
let suggest_derive = self.can_eq(self.param_env, lhs_ty, rhs_ty);
|
||||||
self.note_unmet_impls_on_type(&mut err, errors, suggest_derive);
|
self.note_unmet_impls_on_type(&mut err, errors, suggest_derive);
|
||||||
(err, output_def_id)
|
(err, output_def_id)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
*err.long_ty_path() = path;
|
||||||
|
|
||||||
// Try to suggest a semicolon if it's `A \n *B` where `B` is a place expr
|
// Try to suggest a semicolon if it's `A \n *B` where `B` is a place expr
|
||||||
let maybe_missing_semi = self.check_for_missing_semi(expr, &mut err);
|
let maybe_missing_semi = self.check_for_missing_semi(expr, &mut err);
|
||||||
|
@ -417,7 +422,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
IsAssign::Yes => "=",
|
IsAssign::Yes => "=",
|
||||||
IsAssign::No => "",
|
IsAssign::No => "",
|
||||||
},
|
},
|
||||||
lhs_deref_ty,
|
self.tcx.short_string(lhs_deref_ty, err.long_ty_path()),
|
||||||
);
|
);
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
lhs_expr.span.shrink_to_lo(),
|
lhs_expr.span.shrink_to_lo(),
|
||||||
|
@ -443,8 +448,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
)
|
)
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
let op_str = op.node.as_str();
|
let lhs = self.tcx.short_string(lhs_adjusted_ty, err.long_ty_path());
|
||||||
err.note(format!("an implementation for `{lhs_adjusted_ty} {op_str} {rhs_adjusted_ty}` exists"));
|
let rhs = self.tcx.short_string(rhs_adjusted_ty, err.long_ty_path());
|
||||||
|
let op = op.node.as_str();
|
||||||
|
err.note(format!("an implementation for `{lhs} {op} {rhs}` exists"));
|
||||||
|
|
||||||
if let Some(lhs_new_mutbl) = lhs_new_mutbl
|
if let Some(lhs_new_mutbl) = lhs_new_mutbl
|
||||||
&& let Some(rhs_new_mutbl) = rhs_new_mutbl
|
&& let Some(rhs_new_mutbl) = rhs_new_mutbl
|
||||||
|
@ -628,7 +635,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// When we know that a missing bound is responsible, we don't show
|
// When we know that a missing bound is responsible, we don't show
|
||||||
// this note as it is redundant.
|
// this note as it is redundant.
|
||||||
err.note(format!(
|
err.note(format!(
|
||||||
"the trait `{missing_trait}` is not implemented for `{lhs_ty}`"
|
"the trait `{missing_trait}` is not implemented for `{lhs_ty_str}`"
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -654,24 +661,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
hir::BinOpKind::Sub => {
|
hir::BinOpKind::Sub => {
|
||||||
if lhs_ty.is_unsafe_ptr() && rhs_ty.is_integral() {
|
if lhs_ty.is_unsafe_ptr() && rhs_ty.is_integral() {
|
||||||
err.multipart_suggestion(
|
err.multipart_suggestion(
|
||||||
"consider using `wrapping_sub` or `sub` for pointer - {integer}",
|
"consider using `wrapping_sub` or `sub` for \
|
||||||
|
pointer - {integer}",
|
||||||
vec![
|
vec![
|
||||||
(lhs_expr.span.between(rhs_expr.span), ".wrapping_sub(".to_owned()),
|
(
|
||||||
|
lhs_expr.span.between(rhs_expr.span),
|
||||||
|
".wrapping_sub(".to_owned(),
|
||||||
|
),
|
||||||
(rhs_expr.span.shrink_to_hi(), ")".to_owned()),
|
(rhs_expr.span.shrink_to_hi(), ")".to_owned()),
|
||||||
],
|
],
|
||||||
Applicability::MaybeIncorrect
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if lhs_ty.is_unsafe_ptr() && rhs_ty.is_unsafe_ptr() {
|
if lhs_ty.is_unsafe_ptr() && rhs_ty.is_unsafe_ptr() {
|
||||||
err.multipart_suggestion(
|
err.multipart_suggestion(
|
||||||
"consider using `offset_from` for pointer - pointer if the pointers point to the same allocation",
|
"consider using `offset_from` for pointer - pointer if the \
|
||||||
|
pointers point to the same allocation",
|
||||||
vec![
|
vec![
|
||||||
(lhs_expr.span.shrink_to_lo(), "unsafe { ".to_owned()),
|
(lhs_expr.span.shrink_to_lo(), "unsafe { ".to_owned()),
|
||||||
(lhs_expr.span.between(rhs_expr.span), ".offset_from(".to_owned()),
|
(
|
||||||
|
lhs_expr.span.between(rhs_expr.span),
|
||||||
|
".offset_from(".to_owned(),
|
||||||
|
),
|
||||||
(rhs_expr.span.shrink_to_hi(), ") }".to_owned()),
|
(rhs_expr.span.shrink_to_hi(), ") }".to_owned()),
|
||||||
],
|
],
|
||||||
Applicability::MaybeIncorrect
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -793,14 +808,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
Err(errors) => {
|
Err(errors) => {
|
||||||
let actual = self.resolve_vars_if_possible(operand_ty);
|
let actual = self.resolve_vars_if_possible(operand_ty);
|
||||||
let guar = actual.error_reported().err().unwrap_or_else(|| {
|
let guar = actual.error_reported().err().unwrap_or_else(|| {
|
||||||
|
let mut file = None;
|
||||||
|
let ty_str = self.tcx.short_string(actual, &mut file);
|
||||||
let mut err = struct_span_code_err!(
|
let mut err = struct_span_code_err!(
|
||||||
self.dcx(),
|
self.dcx(),
|
||||||
ex.span,
|
ex.span,
|
||||||
E0600,
|
E0600,
|
||||||
"cannot apply unary operator `{}` to type `{}`",
|
"cannot apply unary operator `{}` to type `{ty_str}`",
|
||||||
op.as_str(),
|
op.as_str(),
|
||||||
actual
|
|
||||||
);
|
);
|
||||||
|
*err.long_ty_path() = file;
|
||||||
err.span_label(
|
err.span_label(
|
||||||
ex.span,
|
ex.span,
|
||||||
format!("cannot apply unary operator `{}`", op.as_str()),
|
format!("cannot apply unary operator `{}`", op.as_str()),
|
||||||
|
|
17
tests/ui/diagnostic-width/binop.rs
Normal file
17
tests/ui/diagnostic-width/binop.rs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
//@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes
|
||||||
|
// The regex below normalizes the long type file name to make it suitable for compare-modes.
|
||||||
|
//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'"
|
||||||
|
type A = (i32, i32, i32, i32);
|
||||||
|
type B = (A, A, A, A);
|
||||||
|
type C = (B, B, B, B);
|
||||||
|
type D = (C, C, C, C);
|
||||||
|
|
||||||
|
fn foo(x: D) {
|
||||||
|
x + x; //~ ERROR cannot add `(...
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar(x: D) {
|
||||||
|
!x; //~ ERROR cannot apply unary operator `!` to type `(...
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
24
tests/ui/diagnostic-width/binop.stderr
Normal file
24
tests/ui/diagnostic-width/binop.stderr
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
error[E0369]: cannot add `(..., ..., ..., ...)` to `(..., ..., ..., ...)`
|
||||||
|
--> $DIR/binop.rs:10:7
|
||||||
|
|
|
||||||
|
LL | x + x;
|
||||||
|
| - ^ - (..., ..., ..., ...)
|
||||||
|
| |
|
||||||
|
| (..., ..., ..., ...)
|
||||||
|
|
|
||||||
|
= note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
|
||||||
|
= note: consider using `--verbose` to print the full type name to the console
|
||||||
|
|
||||||
|
error[E0600]: cannot apply unary operator `!` to type `(..., ..., ..., ...)`
|
||||||
|
--> $DIR/binop.rs:14:5
|
||||||
|
|
|
||||||
|
LL | !x;
|
||||||
|
| ^^ cannot apply unary operator `!`
|
||||||
|
|
|
||||||
|
= note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
|
||||||
|
= note: consider using `--verbose` to print the full type name to the console
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0369, E0600.
|
||||||
|
For more information about an error, try `rustc --explain E0369`.
|
Loading…
Add table
Add a link
Reference in a new issue