Auto merge of #112476 - chenyukang:yukang-fix-109991, r=compiler-errors
Do not emit coerce_suggestions for expr from destructuring assignment desugaring Fixes #109991
This commit is contained in:
commit
3c5d71a99d
4 changed files with 139 additions and 19 deletions
|
@ -83,6 +83,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.annotate_expected_due_to_let_ty(err, expr, error);
|
self.annotate_expected_due_to_let_ty(err, expr, error);
|
||||||
|
|
||||||
|
if self.is_destruct_assignment_desugaring(expr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
self.emit_type_mismatch_suggestions(err, expr, expr_ty, expected, expected_ty_expr, error);
|
self.emit_type_mismatch_suggestions(err, expr, expr_ty, expected, expected_ty_expr, error);
|
||||||
self.note_type_is_not_clone(err, expected, expr_ty, expr);
|
self.note_type_is_not_clone(err, expected, expr_ty, expr);
|
||||||
self.note_internal_mutation_in_method(err, expr, Some(expected), expr_ty);
|
self.note_internal_mutation_in_method(err, expr, Some(expected), expr_ty);
|
||||||
|
@ -1253,6 +1257,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns whether the given expression is a destruct assignment desugaring.
|
||||||
|
// For example, `(a, b) = (1, &2);`
|
||||||
|
// Here we try to find the pattern binding of the expression,
|
||||||
|
// `default_binding_modes` is false only for destruct assignment desugaring.
|
||||||
|
pub(crate) fn is_destruct_assignment_desugaring(&self, expr: &hir::Expr<'_>) -> bool {
|
||||||
|
if let hir::ExprKind::Path(hir::QPath::Resolved(
|
||||||
|
_,
|
||||||
|
hir::Path { res: hir::def::Res::Local(bind_hir_id), .. },
|
||||||
|
)) = expr.kind
|
||||||
|
{
|
||||||
|
let bind = self.tcx.hir().find(*bind_hir_id);
|
||||||
|
let parent = self.tcx.hir().find(self.tcx.hir().parent_id(*bind_hir_id));
|
||||||
|
if let Some(hir::Node::Pat(hir::Pat { kind: hir::PatKind::Binding(_, _hir_id, _, _), .. })) = bind &&
|
||||||
|
let Some(hir::Node::Pat(hir::Pat { default_binding_modes: false, .. })) = parent {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// This function is used to determine potential "simple" improvements or users' errors and
|
/// This function is used to determine potential "simple" improvements or users' errors and
|
||||||
/// provide them useful help. For example:
|
/// provide them useful help. For example:
|
||||||
///
|
///
|
||||||
|
@ -1443,6 +1467,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
_,
|
_,
|
||||||
&ty::Ref(_, checked, _),
|
&ty::Ref(_, checked, _),
|
||||||
) if self.can_sub(self.param_env, checked, expected) => {
|
) if self.can_sub(self.param_env, checked, expected) => {
|
||||||
|
let make_sugg = |start: Span, end: BytePos| {
|
||||||
|
// skip `(` for tuples such as `(c) = (&123)`.
|
||||||
|
// make sure we won't suggest like `(c) = 123)` which is incorrect.
|
||||||
|
let sp = sm.span_extend_while(start.shrink_to_lo(), |c| c == '(' || c.is_whitespace())
|
||||||
|
.map_or(start, |s| s.shrink_to_hi());
|
||||||
|
Some((
|
||||||
|
vec![(sp.with_hi(end), String::new())],
|
||||||
|
"consider removing the borrow".to_string(),
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
))
|
||||||
|
};
|
||||||
|
|
||||||
// We have `&T`, check if what was expected was `T`. If so,
|
// We have `&T`, check if what was expected was `T`. If so,
|
||||||
// we may want to suggest removing a `&`.
|
// we may want to suggest removing a `&`.
|
||||||
if sm.is_imported(expr.span) {
|
if sm.is_imported(expr.span) {
|
||||||
|
@ -1456,24 +1494,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
.find(|&s| sp.contains(s))
|
.find(|&s| sp.contains(s))
|
||||||
&& sm.is_span_accessible(call_span)
|
&& sm.is_span_accessible(call_span)
|
||||||
{
|
{
|
||||||
return Some((
|
return make_sugg(sp, call_span.lo())
|
||||||
vec![(sp.with_hi(call_span.lo()), String::new())],
|
|
||||||
"consider removing the borrow".to_string(),
|
|
||||||
Applicability::MachineApplicable,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if sp.contains(expr.span) && sm.is_span_accessible(expr.span) {
|
if sp.contains(expr.span) && sm.is_span_accessible(expr.span) {
|
||||||
return Some((
|
return make_sugg(sp, expr.span.lo())
|
||||||
vec![(sp.with_hi(expr.span.lo()), String::new())],
|
|
||||||
"consider removing the borrow".to_string(),
|
|
||||||
Applicability::MachineApplicable,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(
|
(
|
||||||
|
|
|
@ -12,11 +12,6 @@ LL | for reference in vec![1, 2, 3] {
|
||||||
...
|
...
|
||||||
LL | Some(reference) = cache.data.get(key) {
|
LL | Some(reference) = cache.data.get(key) {
|
||||||
| ^^^^^^^^^ expected integer, found `&i32`
|
| ^^^^^^^^^ expected integer, found `&i32`
|
||||||
|
|
|
||||||
help: consider dereferencing the borrow
|
|
||||||
|
|
|
||||||
LL | Some(*reference) = cache.data.get(key) {
|
|
||||||
| +
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/ice-6250.rs:12:9
|
--> $DIR/ice-6250.rs:12:9
|
||||||
|
|
27
tests/ui/suggestions/issue-109991.rs
Normal file
27
tests/ui/suggestions/issue-109991.rs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
struct S {
|
||||||
|
a: usize,
|
||||||
|
b: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let a: usize;
|
||||||
|
let b: usize;
|
||||||
|
let c: usize;
|
||||||
|
|
||||||
|
(c) = (&123); //~ ERROR mismatched types
|
||||||
|
(a, b) = (123, &mut 123); //~ ERROR mismatched types
|
||||||
|
|
||||||
|
let x: String;
|
||||||
|
(x,) = (1,); //~ ERROR mismatched types
|
||||||
|
|
||||||
|
let x: i32;
|
||||||
|
[x] = [&1]; //~ ERROR mismatched types
|
||||||
|
|
||||||
|
let x: &i32;
|
||||||
|
[x] = [1]; //~ ERROR mismatched types
|
||||||
|
|
||||||
|
let x = (1, &mut 2);
|
||||||
|
(a, b) = x; //~ ERROR mismatched types
|
||||||
|
|
||||||
|
S { a, b } = S { a: 1, b: &mut 2 }; //~ ERROR mismatched types
|
||||||
|
}
|
72
tests/ui/suggestions/issue-109991.stderr
Normal file
72
tests/ui/suggestions/issue-109991.stderr
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/issue-109991.rs:11:11
|
||||||
|
|
|
||||||
|
LL | let c: usize;
|
||||||
|
| ----- expected due to this type
|
||||||
|
LL |
|
||||||
|
LL | (c) = (&123);
|
||||||
|
| ^^^^^^ expected `usize`, found `&{integer}`
|
||||||
|
|
|
||||||
|
help: consider removing the borrow
|
||||||
|
|
|
||||||
|
LL - (c) = (&123);
|
||||||
|
LL + (c) = (123);
|
||||||
|
|
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/issue-109991.rs:12:9
|
||||||
|
|
|
||||||
|
LL | let b: usize;
|
||||||
|
| ----- expected due to this type
|
||||||
|
...
|
||||||
|
LL | (a, b) = (123, &mut 123);
|
||||||
|
| ^ expected `usize`, found `&mut {integer}`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/issue-109991.rs:15:6
|
||||||
|
|
|
||||||
|
LL | let x: String;
|
||||||
|
| ------ expected due to this type
|
||||||
|
LL | (x,) = (1,);
|
||||||
|
| ^ expected `String`, found integer
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/issue-109991.rs:18:6
|
||||||
|
|
|
||||||
|
LL | let x: i32;
|
||||||
|
| --- expected due to this type
|
||||||
|
LL | [x] = [&1];
|
||||||
|
| ^ expected `i32`, found `&{integer}`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/issue-109991.rs:21:6
|
||||||
|
|
|
||||||
|
LL | let x: &i32;
|
||||||
|
| ---- expected due to this type
|
||||||
|
LL | [x] = [1];
|
||||||
|
| ^ expected `&i32`, found integer
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/issue-109991.rs:24:9
|
||||||
|
|
|
||||||
|
LL | let b: usize;
|
||||||
|
| ----- expected due to this type
|
||||||
|
...
|
||||||
|
LL | (a, b) = x;
|
||||||
|
| ^ expected `usize`, found `&mut {integer}`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/issue-109991.rs:26:31
|
||||||
|
|
|
||||||
|
LL | S { a, b } = S { a: 1, b: &mut 2 };
|
||||||
|
| ^^^^^^ expected `usize`, found `&mut {integer}`
|
||||||
|
|
|
||||||
|
help: consider removing the borrow
|
||||||
|
|
|
||||||
|
LL - S { a, b } = S { a: 1, b: &mut 2 };
|
||||||
|
LL + S { a, b } = S { a: 1, b: 2 };
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to 7 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Add table
Add a link
Reference in a new issue