From 3ba27e7dfa69b5a9e1b8c5ff8868ed822dcff344 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 19 Nov 2021 15:22:44 -0800 Subject: [PATCH 1/2] Use same_type_modulo_infer in more places --- .../rustc_infer/src/infer/error_reporting/mod.rs | 4 ++-- .../exclusive_range_pattern_syntax_collision.stderr | 4 ++++ .../exclusive_range_pattern_syntax_collision2.stderr | 4 ++++ .../exclusive_range_pattern_syntax_collision3.stderr | 12 ++++++++++++ src/test/ui/issues/issue-5358-1.stderr | 4 ++++ 5 files changed, 26 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 3c2f990008062..640300c2d4554 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1879,7 +1879,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { .iter() .filter(|field| field.vis.is_accessible_from(field.did, self.tcx)) .map(|field| (field.ident.name, field.ty(self.tcx, expected_substs))) - .find(|(_, ty)| ty::TyS::same_type(ty, exp_found.found)) + .find(|(_, ty)| same_type_modulo_infer(ty, exp_found.found)) { if let ObligationCauseCode::Pattern { span: Some(span), .. } = cause.code { if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { @@ -1944,7 +1944,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { | (_, ty::Infer(_)) | (ty::Param(_), _) | (ty::Infer(_), _) => {} - _ if ty::TyS::same_type(exp_ty, found_ty) => {} + _ if same_type_modulo_infer(exp_ty, found_ty) => {} _ => show_suggestion = false, }; } diff --git a/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr index a6f8563a04785..1df7fd59f57b2 100644 --- a/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr +++ b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr @@ -8,6 +8,10 @@ LL | [_, 99.., _] => {}, | = note: expected struct `std::ops::Range<{integer}>` found type `{integer}` +help: you might have meant to use field `start` whose type is `{integer}` + | +LL | match [5..4, 99..105, 43..44].start { + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to previous error diff --git a/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr index 4e0102c930da8..87484c1072dd0 100644 --- a/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr +++ b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr @@ -14,6 +14,10 @@ LL | [_, 99..] => {}, | = note: expected struct `std::ops::Range<{integer}>` found type `{integer}` +help: you might have meant to use field `start` whose type is `{integer}` + | +LL | match [5..4, 99..105, 43..44].start { + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to 2 previous errors diff --git a/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr index 665eef2fcb96c..c48f6cce93c2f 100644 --- a/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr +++ b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr @@ -8,6 +8,10 @@ LL | [..9, 99..100, _] => {}, | = note: expected struct `std::ops::Range<{integer}>` found type `{integer}` +help: you might have meant to use field `start` whose type is `{integer}` + | +LL | match [5..4, 99..105, 43..44].start { + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0308]: mismatched types --> $DIR/exclusive_range_pattern_syntax_collision3.rs:6:15 @@ -21,6 +25,10 @@ LL | [..9, 99..100, _] => {}, | = note: expected struct `std::ops::Range<{integer}>` found type `{integer}` +help: you might have meant to use field `start` whose type is `{integer}` + | +LL | match [5..4, 99..105, 43..44].start { + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0308]: mismatched types --> $DIR/exclusive_range_pattern_syntax_collision3.rs:6:19 @@ -34,6 +42,10 @@ LL | [..9, 99..100, _] => {}, | = note: expected struct `std::ops::Range<{integer}>` found type `{integer}` +help: you might have meant to use field `start` whose type is `{integer}` + | +LL | match [5..4, 99..105, 43..44].start { + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to 3 previous errors diff --git a/src/test/ui/issues/issue-5358-1.stderr b/src/test/ui/issues/issue-5358-1.stderr index 314d1fddbd76a..d1bc279c7589a 100644 --- a/src/test/ui/issues/issue-5358-1.stderr +++ b/src/test/ui/issues/issue-5358-1.stderr @@ -8,6 +8,10 @@ LL | Either::Right(_) => {} | = note: expected struct `S` found enum `Either<_, _>` +help: you might have meant to use field `0` whose type is `Either` + | +LL | match S(Either::Left(5)).0 { + | ~~~~~~~~~~~~~~~~~~~~ error: aborting due to previous error From 01b24045faebc1d0d9f42f355e536df6fc693e49 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 19 Nov 2021 14:57:33 -0800 Subject: [PATCH 2/2] Fix for issue 91058 --- .../src/infer/error_reporting/mod.rs | 20 +++++++++++++++---- ...sive_range_pattern_syntax_collision.stderr | 4 ---- ...ive_range_pattern_syntax_collision2.stderr | 4 ---- ...ive_range_pattern_syntax_collision3.stderr | 12 ----------- src/test/ui/match/issue-91058.rs | 11 ++++++++++ src/test/ui/match/issue-91058.stderr | 11 ++++++++++ 6 files changed, 38 insertions(+), 24 deletions(-) create mode 100644 src/test/ui/match/issue-91058.rs create mode 100644 src/test/ui/match/issue-91058.stderr diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 640300c2d4554..e32906b75338e 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1695,11 +1695,23 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } _ => exp_found, }; - debug!("exp_found {:?} terr {:?}", exp_found, terr); + debug!("exp_found {:?} terr {:?} cause.code {:?}", exp_found, terr, cause.code); if let Some(exp_found) = exp_found { - self.suggest_as_ref_where_appropriate(span, &exp_found, diag); - self.suggest_accessing_field_where_appropriate(cause, &exp_found, diag); - self.suggest_await_on_expect_found(cause, span, &exp_found, diag); + let should_suggest_fixes = if let ObligationCauseCode::Pattern { root_ty, .. } = + &cause.code + { + // Skip if the root_ty of the pattern is not the same as the expected_ty. + // If these types aren't equal then we've probably peeled off a layer of arrays. + same_type_modulo_infer(self.resolve_vars_if_possible(*root_ty), exp_found.expected) + } else { + true + }; + + if should_suggest_fixes { + self.suggest_as_ref_where_appropriate(span, &exp_found, diag); + self.suggest_accessing_field_where_appropriate(cause, &exp_found, diag); + self.suggest_await_on_expect_found(cause, span, &exp_found, diag); + } } // In some (most?) cases cause.body_id points to actual body, but in some cases diff --git a/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr index 1df7fd59f57b2..a6f8563a04785 100644 --- a/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr +++ b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr @@ -8,10 +8,6 @@ LL | [_, 99.., _] => {}, | = note: expected struct `std::ops::Range<{integer}>` found type `{integer}` -help: you might have meant to use field `start` whose type is `{integer}` - | -LL | match [5..4, 99..105, 43..44].start { - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to previous error diff --git a/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr index 87484c1072dd0..4e0102c930da8 100644 --- a/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr +++ b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr @@ -14,10 +14,6 @@ LL | [_, 99..] => {}, | = note: expected struct `std::ops::Range<{integer}>` found type `{integer}` -help: you might have meant to use field `start` whose type is `{integer}` - | -LL | match [5..4, 99..105, 43..44].start { - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to 2 previous errors diff --git a/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr index c48f6cce93c2f..665eef2fcb96c 100644 --- a/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr +++ b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr @@ -8,10 +8,6 @@ LL | [..9, 99..100, _] => {}, | = note: expected struct `std::ops::Range<{integer}>` found type `{integer}` -help: you might have meant to use field `start` whose type is `{integer}` - | -LL | match [5..4, 99..105, 43..44].start { - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0308]: mismatched types --> $DIR/exclusive_range_pattern_syntax_collision3.rs:6:15 @@ -25,10 +21,6 @@ LL | [..9, 99..100, _] => {}, | = note: expected struct `std::ops::Range<{integer}>` found type `{integer}` -help: you might have meant to use field `start` whose type is `{integer}` - | -LL | match [5..4, 99..105, 43..44].start { - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0308]: mismatched types --> $DIR/exclusive_range_pattern_syntax_collision3.rs:6:19 @@ -42,10 +34,6 @@ LL | [..9, 99..100, _] => {}, | = note: expected struct `std::ops::Range<{integer}>` found type `{integer}` -help: you might have meant to use field `start` whose type is `{integer}` - | -LL | match [5..4, 99..105, 43..44].start { - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to 3 previous errors diff --git a/src/test/ui/match/issue-91058.rs b/src/test/ui/match/issue-91058.rs new file mode 100644 index 0000000000000..4845937d54401 --- /dev/null +++ b/src/test/ui/match/issue-91058.rs @@ -0,0 +1,11 @@ +struct S(()); + +fn main() { + let array = [S(())]; + + match array { + [()] => {} + //~^ ERROR mismatched types [E0308] + _ => {} + } +} diff --git a/src/test/ui/match/issue-91058.stderr b/src/test/ui/match/issue-91058.stderr new file mode 100644 index 0000000000000..ec1d7e21fa53c --- /dev/null +++ b/src/test/ui/match/issue-91058.stderr @@ -0,0 +1,11 @@ +error[E0308]: mismatched types + --> $DIR/issue-91058.rs:7:10 + | +LL | match array { + | ----- this expression has type `[S; 1]` +LL | [()] => {} + | ^^ expected struct `S`, found `()` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`.