From 023cc968e1295994ed8039da43b0f2f4ea4e9390 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 19 Nov 2021 19:33:29 -0800 Subject: Make `LLVMRustGetOrInsertGlobal` always return a `GlobalVariable` `Module::getOrInsertGlobal` returns a `Constant*`, which is a super class of `GlobalVariable`, but if the given type doesn't match an existing declaration, it returns a bitcast of that global instead. This causes UB when we pass that to `LLVMGetVisibility` which unconditionally casts the opaque argument to a `GlobalValue*`. Instead, we can do our own get-or-insert without worrying whether existing types match exactly. It's not relevant when we're just trying to get/set the linkage and visibility, and if types are needed we can bitcast or error nicely from `rustc_codegen_llvm` instead. --- src/test/ui/issues/issue-91050.rs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/test/ui/issues/issue-91050.rs (limited to 'src/test') diff --git a/src/test/ui/issues/issue-91050.rs b/src/test/ui/issues/issue-91050.rs new file mode 100644 index 00000000000..50763d30931 --- /dev/null +++ b/src/test/ui/issues/issue-91050.rs @@ -0,0 +1,34 @@ +// build-pass +// compile-flags: --crate-type lib -Ccodegen-units=1 + +// This test declares globals by the same name with different types, which +// caused problems because Module::getOrInsertGlobal would return a Constant* +// bitcast instead of a GlobalVariable* that could access linkage/visibility. +// In alt builds with LLVM assertions this would fail: +// +// rustc: /checkout/src/llvm-project/llvm/include/llvm/Support/Casting.h:269: +// typename cast_retty::ret_type llvm::cast(Y *) [X = llvm::GlobalValue, Y = llvm::Value]: +// Assertion `isa(Val) && "cast() argument of incompatible type!"' failed. +// +// In regular builds, the bad cast was UB, like "Invalid LLVMRustVisibility value!" + +pub mod before { + #[no_mangle] + pub static GLOBAL1: [u8; 1] = [1]; +} + +pub mod inner { + extern "C" { + pub static GLOBAL1: u8; + pub static GLOBAL2: u8; + } + + pub fn call() { + drop(unsafe { (GLOBAL1, GLOBAL2) }); + } +} + +pub mod after { + #[no_mangle] + pub static GLOBAL2: [u8; 1] = [2]; +} -- cgit 1.4.1-3-g733a5 From 3b2cfa574699d3d92c1114837e347dd7ee248fcb Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Sat, 20 Nov 2021 16:29:15 -0800 Subject: Add another test variant of issue-91050 Co-authored-by: Simonas Kazlauskas --- src/test/ui/issues/issue-91050-1.rs | 34 ++++++++++++++++++++++++++++++++++ src/test/ui/issues/issue-91050-2.rs | 24 ++++++++++++++++++++++++ src/test/ui/issues/issue-91050.rs | 34 ---------------------------------- 3 files changed, 58 insertions(+), 34 deletions(-) create mode 100644 src/test/ui/issues/issue-91050-1.rs create mode 100644 src/test/ui/issues/issue-91050-2.rs delete mode 100644 src/test/ui/issues/issue-91050.rs (limited to 'src/test') diff --git a/src/test/ui/issues/issue-91050-1.rs b/src/test/ui/issues/issue-91050-1.rs new file mode 100644 index 00000000000..403a41462ef --- /dev/null +++ b/src/test/ui/issues/issue-91050-1.rs @@ -0,0 +1,34 @@ +// build-pass +// compile-flags: --crate-type=rlib --emit=llvm-ir -Cno-prepopulate-passes + +// This test declares globals by the same name with different types, which +// caused problems because Module::getOrInsertGlobal would return a Constant* +// bitcast instead of a GlobalVariable* that could access linkage/visibility. +// In alt builds with LLVM assertions this would fail: +// +// rustc: /checkout/src/llvm-project/llvm/include/llvm/Support/Casting.h:269: +// typename cast_retty::ret_type llvm::cast(Y *) [X = llvm::GlobalValue, Y = llvm::Value]: +// Assertion `isa(Val) && "cast() argument of incompatible type!"' failed. +// +// In regular builds, the bad cast was UB, like "Invalid LLVMRustVisibility value!" + +pub mod before { + #[no_mangle] + pub static GLOBAL1: [u8; 1] = [1]; +} + +pub mod inner { + extern "C" { + pub static GLOBAL1: u8; + pub static GLOBAL2: u8; + } + + pub fn call() { + drop(unsafe { (GLOBAL1, GLOBAL2) }); + } +} + +pub mod after { + #[no_mangle] + pub static GLOBAL2: [u8; 1] = [2]; +} diff --git a/src/test/ui/issues/issue-91050-2.rs b/src/test/ui/issues/issue-91050-2.rs new file mode 100644 index 00000000000..2ff954d15ca --- /dev/null +++ b/src/test/ui/issues/issue-91050-2.rs @@ -0,0 +1,24 @@ +// build-pass +// compile-flags: --crate-type=rlib --emit=llvm-ir -Cno-prepopulate-passes + +// This is a variant of issue-91050-1.rs -- see there for an explanation. + +pub mod before { + extern "C" { + pub static GLOBAL1: [u8; 1]; + } + + pub unsafe fn do_something_with_array() -> u8 { + GLOBAL1[0] + } +} + +pub mod inner { + extern "C" { + pub static GLOBAL1: u8; + } + + pub unsafe fn call() -> u8 { + GLOBAL1 + 42 + } +} diff --git a/src/test/ui/issues/issue-91050.rs b/src/test/ui/issues/issue-91050.rs deleted file mode 100644 index 50763d30931..00000000000 --- a/src/test/ui/issues/issue-91050.rs +++ /dev/null @@ -1,34 +0,0 @@ -// build-pass -// compile-flags: --crate-type lib -Ccodegen-units=1 - -// This test declares globals by the same name with different types, which -// caused problems because Module::getOrInsertGlobal would return a Constant* -// bitcast instead of a GlobalVariable* that could access linkage/visibility. -// In alt builds with LLVM assertions this would fail: -// -// rustc: /checkout/src/llvm-project/llvm/include/llvm/Support/Casting.h:269: -// typename cast_retty::ret_type llvm::cast(Y *) [X = llvm::GlobalValue, Y = llvm::Value]: -// Assertion `isa(Val) && "cast() argument of incompatible type!"' failed. -// -// In regular builds, the bad cast was UB, like "Invalid LLVMRustVisibility value!" - -pub mod before { - #[no_mangle] - pub static GLOBAL1: [u8; 1] = [1]; -} - -pub mod inner { - extern "C" { - pub static GLOBAL1: u8; - pub static GLOBAL2: u8; - } - - pub fn call() { - drop(unsafe { (GLOBAL1, GLOBAL2) }); - } -} - -pub mod after { - #[no_mangle] - pub static GLOBAL2: [u8; 1] = [2]; -} -- cgit 1.4.1-3-g733a5 From 3aa1954b0bfc3f10917d5ff8fa315ac3cae5c45a Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Sat, 20 Nov 2021 17:02:37 -0800 Subject: Move the issue-91050 tests to appease tidy --- src/test/ui/issues/issue-91050-1.rs | 34 ---------------------------------- src/test/ui/issues/issue-91050-2.rs | 24 ------------------------ src/test/ui/statics/issue-91050-1.rs | 34 ++++++++++++++++++++++++++++++++++ src/test/ui/statics/issue-91050-2.rs | 24 ++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 58 deletions(-) delete mode 100644 src/test/ui/issues/issue-91050-1.rs delete mode 100644 src/test/ui/issues/issue-91050-2.rs create mode 100644 src/test/ui/statics/issue-91050-1.rs create mode 100644 src/test/ui/statics/issue-91050-2.rs (limited to 'src/test') diff --git a/src/test/ui/issues/issue-91050-1.rs b/src/test/ui/issues/issue-91050-1.rs deleted file mode 100644 index 403a41462ef..00000000000 --- a/src/test/ui/issues/issue-91050-1.rs +++ /dev/null @@ -1,34 +0,0 @@ -// build-pass -// compile-flags: --crate-type=rlib --emit=llvm-ir -Cno-prepopulate-passes - -// This test declares globals by the same name with different types, which -// caused problems because Module::getOrInsertGlobal would return a Constant* -// bitcast instead of a GlobalVariable* that could access linkage/visibility. -// In alt builds with LLVM assertions this would fail: -// -// rustc: /checkout/src/llvm-project/llvm/include/llvm/Support/Casting.h:269: -// typename cast_retty::ret_type llvm::cast(Y *) [X = llvm::GlobalValue, Y = llvm::Value]: -// Assertion `isa(Val) && "cast() argument of incompatible type!"' failed. -// -// In regular builds, the bad cast was UB, like "Invalid LLVMRustVisibility value!" - -pub mod before { - #[no_mangle] - pub static GLOBAL1: [u8; 1] = [1]; -} - -pub mod inner { - extern "C" { - pub static GLOBAL1: u8; - pub static GLOBAL2: u8; - } - - pub fn call() { - drop(unsafe { (GLOBAL1, GLOBAL2) }); - } -} - -pub mod after { - #[no_mangle] - pub static GLOBAL2: [u8; 1] = [2]; -} diff --git a/src/test/ui/issues/issue-91050-2.rs b/src/test/ui/issues/issue-91050-2.rs deleted file mode 100644 index 2ff954d15ca..00000000000 --- a/src/test/ui/issues/issue-91050-2.rs +++ /dev/null @@ -1,24 +0,0 @@ -// build-pass -// compile-flags: --crate-type=rlib --emit=llvm-ir -Cno-prepopulate-passes - -// This is a variant of issue-91050-1.rs -- see there for an explanation. - -pub mod before { - extern "C" { - pub static GLOBAL1: [u8; 1]; - } - - pub unsafe fn do_something_with_array() -> u8 { - GLOBAL1[0] - } -} - -pub mod inner { - extern "C" { - pub static GLOBAL1: u8; - } - - pub unsafe fn call() -> u8 { - GLOBAL1 + 42 - } -} diff --git a/src/test/ui/statics/issue-91050-1.rs b/src/test/ui/statics/issue-91050-1.rs new file mode 100644 index 00000000000..403a41462ef --- /dev/null +++ b/src/test/ui/statics/issue-91050-1.rs @@ -0,0 +1,34 @@ +// build-pass +// compile-flags: --crate-type=rlib --emit=llvm-ir -Cno-prepopulate-passes + +// This test declares globals by the same name with different types, which +// caused problems because Module::getOrInsertGlobal would return a Constant* +// bitcast instead of a GlobalVariable* that could access linkage/visibility. +// In alt builds with LLVM assertions this would fail: +// +// rustc: /checkout/src/llvm-project/llvm/include/llvm/Support/Casting.h:269: +// typename cast_retty::ret_type llvm::cast(Y *) [X = llvm::GlobalValue, Y = llvm::Value]: +// Assertion `isa(Val) && "cast() argument of incompatible type!"' failed. +// +// In regular builds, the bad cast was UB, like "Invalid LLVMRustVisibility value!" + +pub mod before { + #[no_mangle] + pub static GLOBAL1: [u8; 1] = [1]; +} + +pub mod inner { + extern "C" { + pub static GLOBAL1: u8; + pub static GLOBAL2: u8; + } + + pub fn call() { + drop(unsafe { (GLOBAL1, GLOBAL2) }); + } +} + +pub mod after { + #[no_mangle] + pub static GLOBAL2: [u8; 1] = [2]; +} diff --git a/src/test/ui/statics/issue-91050-2.rs b/src/test/ui/statics/issue-91050-2.rs new file mode 100644 index 00000000000..2ff954d15ca --- /dev/null +++ b/src/test/ui/statics/issue-91050-2.rs @@ -0,0 +1,24 @@ +// build-pass +// compile-flags: --crate-type=rlib --emit=llvm-ir -Cno-prepopulate-passes + +// This is a variant of issue-91050-1.rs -- see there for an explanation. + +pub mod before { + extern "C" { + pub static GLOBAL1: [u8; 1]; + } + + pub unsafe fn do_something_with_array() -> u8 { + GLOBAL1[0] + } +} + +pub mod inner { + extern "C" { + pub static GLOBAL1: u8; + } + + pub unsafe fn call() -> u8 { + GLOBAL1 + 42 + } +} -- cgit 1.4.1-3-g733a5 From d99b132586435e62423e00f2e0c0eed9106f0ca8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 20 Nov 2021 17:07:42 -0800 Subject: Fixup test outputs --- src/test/ui/associated-types/issue-87261.rs | 8 ++++---- src/test/ui/associated-types/issue-87261.stderr | 24 ++++++++++++------------ src/test/ui/cast/casts-differing-anon.stderr | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) (limited to 'src/test') diff --git a/src/test/ui/associated-types/issue-87261.rs b/src/test/ui/associated-types/issue-87261.rs index a70f771e482..384561f8ccd 100644 --- a/src/test/ui/associated-types/issue-87261.rs +++ b/src/test/ui/associated-types/issue-87261.rs @@ -83,17 +83,17 @@ fn main() { //~^ ERROR type mismatch resolving `::Associated == ()` accepts_trait(returns_opaque_foo()); - //~^ ERROR type mismatch resolving `::Associated == ()` + //~^ ERROR type mismatch resolving `::Associated == ()` accepts_trait(returns_opaque_derived_foo()); - //~^ ERROR type mismatch resolving `::Associated == ()` + //~^ ERROR type mismatch resolving `::Associated == ()` accepts_generic_trait(returns_opaque_generic()); //~^ ERROR type mismatch resolving ` as GenericTrait<()>>::Associated == ()` accepts_generic_trait(returns_opaque_generic_foo()); - //~^ ERROR type mismatch resolving `+Foo as GenericTrait<()>>::Associated == ()` + //~^ ERROR type mismatch resolving ` + Foo as GenericTrait<()>>::Associated == ()` accepts_generic_trait(returns_opaque_generic_duplicate()); - //~^ ERROR type mismatch resolving `+GenericTrait as GenericTrait<()>>::Associated == ()` + //~^ ERROR type mismatch resolving ` + GenericTrait as GenericTrait<()>>::Associated == ()` } diff --git a/src/test/ui/associated-types/issue-87261.stderr b/src/test/ui/associated-types/issue-87261.stderr index b85d64b86ae..8db4a49da3c 100644 --- a/src/test/ui/associated-types/issue-87261.stderr +++ b/src/test/ui/associated-types/issue-87261.stderr @@ -160,7 +160,7 @@ help: consider constraining the associated type `::A LL | fn returns_opaque_derived() -> impl DerivedTrait + 'static { | +++++++++++++++++ -error[E0271]: type mismatch resolving `::Associated == ()` +error[E0271]: type mismatch resolving `::Associated == ()` --> $DIR/issue-87261.rs:85:5 | LL | fn returns_opaque_foo() -> impl Trait + Foo { @@ -170,18 +170,18 @@ LL | accepts_trait(returns_opaque_foo()); | ^^^^^^^^^^^^^ expected `()`, found associated type | = note: expected unit type `()` - found associated type `::Associated` + found associated type `::Associated` note: required by a bound in `accepts_trait` --> $DIR/issue-87261.rs:43:27 | LL | fn accepts_trait>(_: T) {} | ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait` -help: consider constraining the associated type `::Associated` to `()` +help: consider constraining the associated type `::Associated` to `()` | LL | fn returns_opaque_foo() -> impl Trait + Foo { | +++++++++++++++++ -error[E0271]: type mismatch resolving `::Associated == ()` +error[E0271]: type mismatch resolving `::Associated == ()` --> $DIR/issue-87261.rs:88:5 | LL | fn returns_opaque_derived_foo() -> impl DerivedTrait + Foo { @@ -191,8 +191,8 @@ LL | accepts_trait(returns_opaque_derived_foo()); | ^^^^^^^^^^^^^ expected `()`, found associated type | = note: expected unit type `()` - found associated type `::Associated` - = help: consider constraining the associated type `::Associated` to `()` + found associated type `::Associated` + = help: consider constraining the associated type `::Associated` to `()` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html note: required by a bound in `accepts_trait` --> $DIR/issue-87261.rs:43:27 @@ -221,7 +221,7 @@ help: consider constraining the associated type ` as Gener LL | fn returns_opaque_generic() -> impl GenericTrait<(), Associated = ()> + 'static { | +++++++++++++++++ -error[E0271]: type mismatch resolving `+Foo as GenericTrait<()>>::Associated == ()` +error[E0271]: type mismatch resolving ` + Foo as GenericTrait<()>>::Associated == ()` --> $DIR/issue-87261.rs:94:5 | LL | fn returns_opaque_generic_foo() -> impl GenericTrait<()> + Foo { @@ -231,18 +231,18 @@ LL | accepts_generic_trait(returns_opaque_generic_foo()); | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type | = note: expected unit type `()` - found associated type `+Foo as GenericTrait<()>>::Associated` + found associated type ` + Foo as GenericTrait<()>>::Associated` note: required by a bound in `accepts_generic_trait` --> $DIR/issue-87261.rs:44:46 | LL | fn accepts_generic_trait>(_: T) {} | ^^^^^^^^^^^^^^^ required by this bound in `accepts_generic_trait` -help: consider constraining the associated type `+Foo as GenericTrait<()>>::Associated` to `()` +help: consider constraining the associated type ` + Foo as GenericTrait<()>>::Associated` to `()` | LL | fn returns_opaque_generic_foo() -> impl GenericTrait<(), Associated = ()> + Foo { | +++++++++++++++++ -error[E0271]: type mismatch resolving `+GenericTrait as GenericTrait<()>>::Associated == ()` +error[E0271]: type mismatch resolving ` + GenericTrait as GenericTrait<()>>::Associated == ()` --> $DIR/issue-87261.rs:97:5 | LL | fn returns_opaque_generic_duplicate() -> impl GenericTrait<()> + GenericTrait { @@ -252,8 +252,8 @@ LL | accepts_generic_trait(returns_opaque_generic_duplicate()); | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type | = note: expected unit type `()` - found associated type `+GenericTrait as GenericTrait<()>>::Associated` - = help: consider constraining the associated type `+GenericTrait as GenericTrait<()>>::Associated` to `()` + found associated type ` + GenericTrait as GenericTrait<()>>::Associated` + = help: consider constraining the associated type ` + GenericTrait as GenericTrait<()>>::Associated` to `()` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html note: required by a bound in `accepts_generic_trait` --> $DIR/issue-87261.rs:44:46 diff --git a/src/test/ui/cast/casts-differing-anon.stderr b/src/test/ui/cast/casts-differing-anon.stderr index a30e9b35f5c..f9abfb5225f 100644 --- a/src/test/ui/cast/casts-differing-anon.stderr +++ b/src/test/ui/cast/casts-differing-anon.stderr @@ -1,4 +1,4 @@ -error[E0606]: casting `*mut impl Debug+?Sized` as `*mut impl Debug+?Sized` is invalid +error[E0606]: casting `*mut impl Debug + ?Sized` as `*mut impl Debug + ?Sized` is invalid --> $DIR/casts-differing-anon.rs:21:13 | LL | b_raw = f_raw as *mut _; -- cgit 1.4.1-3-g733a5 From 3ba27e7dfa69b5a9e1b8c5ff8868ed822dcff344 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 19 Nov 2021 15:22:44 -0800 Subject: Use same_type_modulo_infer in more places --- compiler/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(-) (limited to 'src/test') diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 3c2f9900080..640300c2d45 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 a6f8563a047..1df7fd59f57 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 4e0102c930d..87484c1072d 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 665eef2fcb9..c48f6cce93c 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 314d1fddbd7..d1bc279c758 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 -- cgit 1.4.1-3-g733a5 From 01b24045faebc1d0d9f42f355e536df6fc693e49 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 19 Nov 2021 14:57:33 -0800 Subject: Fix for issue 91058 --- .../rustc_infer/src/infer/error_reporting/mod.rs | 20 ++++++++++++++++---- .../exclusive_range_pattern_syntax_collision.stderr | 4 ---- .../exclusive_range_pattern_syntax_collision2.stderr | 4 ---- .../exclusive_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 (limited to 'src/test') diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 640300c2d45..e32906b7533 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 1df7fd59f57..a6f8563a047 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 87484c1072d..4e0102c930d 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 c48f6cce93c..665eef2fcb9 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 00000000000..4845937d544 --- /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 00000000000..ec1d7e21fa5 --- /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`. -- cgit 1.4.1-3-g733a5