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. --- compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'compiler') diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index e77d29bed71..f3d8eb2602a 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -124,8 +124,18 @@ extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M, extern "C" LLVMValueRef LLVMRustGetOrInsertGlobal(LLVMModuleRef M, const char *Name, size_t NameLen, LLVMTypeRef Ty) { + Module *Mod = unwrap(M); StringRef NameRef(Name, NameLen); - return wrap(unwrap(M)->getOrInsertGlobal(NameRef, unwrap(Ty))); + + // We don't use Module::getOrInsertGlobal because that returns a Constant*, + // which may either be the real GlobalVariable*, or a constant bitcast of it + // if our type doesn't match the original declaration. We always want the + // GlobalVariable* so we can access linkage, visibility, etc. + GlobalVariable *GV = Mod->getGlobalVariable(NameRef, true); + if (!GV) + GV = new GlobalVariable(*Mod, unwrap(Ty), false, + GlobalValue::ExternalLinkage, nullptr, NameRef); + return wrap(GV); } extern "C" LLVMValueRef -- cgit 1.4.1-3-g733a5 From 8805e934afbcc2549dfa328e328bc7f4350b7059 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 20 Nov 2021 17:01:47 -0800 Subject: Add space in opaque `impl Trait` --- compiler/rustc_middle/src/ty/print/pretty.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'compiler') diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index c8e898c6849..3846cf19d91 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -688,7 +688,7 @@ pub trait PrettyPrinter<'tcx>: } p!( - write("{}", if first { " " } else { "+" }), + write("{}", if first { " " } else { " + " }), print(trait_ref.print_only_trait_path()) ); @@ -699,7 +699,7 @@ pub trait PrettyPrinter<'tcx>: } if is_future { - p!(write("{}Future", if first { " " } else { "+" })); + p!(write("{}Future", if first { " " } else { " + " })); first = false; if let Some(future_output_ty) = future_output_ty { @@ -712,7 +712,7 @@ pub trait PrettyPrinter<'tcx>: } if !is_sized { - p!(write("{}?Sized", if first { " " } else { "+" })); + p!(write("{}?Sized", if first { " " } else { " + " })); } else if first { p!(" Sized"); } -- 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 'compiler') 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 'compiler') 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