about summary refs log tree commit diff
diff options
context:
space:
mode:
authorHirochika Matsumoto <matsujika@gmail.com>2021-01-30 14:18:50 +0900
committerHirochika Matsumoto <matsujika@gmail.com>2021-01-30 14:18:50 +0900
commit2ce2d145c2cbcb93389dbea429d7e034ff367f48 (patch)
tree346a1ae112aef60652cfcafa4adcf8ea54367f11
parent08d31e0f09f79a41e0cfc26247d41fea1489adf9 (diff)
downloadrust-2ce2d145c2cbcb93389dbea429d7e034ff367f48.tar.gz
rust-2ce2d145c2cbcb93389dbea429d7e034ff367f48.zip
Account for union
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs9
-rw-r--r--src/test/ui/suggestions/field-access.fixed12
-rw-r--r--src/test/ui/suggestions/field-access.rs12
-rw-r--r--src/test/ui/suggestions/field-access.stderr22
4 files changed, 50 insertions, 5 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 268819d3094..447b4f6d1e5 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -1842,13 +1842,20 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             {
                 if let ObligationCauseCode::Pattern { span: Some(span), .. } = cause.code {
                     if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
+                        let suggestion = if expected_def.is_struct() {
+                            format!("{}.{}", snippet, name)
+                        } else if expected_def.is_union() {
+                            format!("unsafe {{ {}.{} }}", snippet, name)
+                        } else {
+                            return;
+                        };
                         diag.span_suggestion(
                             span,
                             &format!(
                                 "you might have meant to use field `{}` of type `{}`",
                                 name, ty
                             ),
-                            format!("{}.{}", snippet, name),
+                            suggestion,
                             Applicability::MaybeIncorrect,
                         );
                     }
diff --git a/src/test/ui/suggestions/field-access.fixed b/src/test/ui/suggestions/field-access.fixed
index 72b29d7656a..05a4a0eb126 100644
--- a/src/test/ui/suggestions/field-access.fixed
+++ b/src/test/ui/suggestions/field-access.fixed
@@ -10,6 +10,11 @@ enum B {
     Snd,
 }
 
+union Foo {
+    bar: u32,
+    qux: f32,
+}
+
 fn main() {
     let a = A { b: B::Fst };
     if let B::Fst = a.b {}; //~ ERROR mismatched types [E0308]
@@ -20,4 +25,11 @@ fn main() {
         B::Fst => (), //~ ERROR mismatched types [E0308]
         B::Snd => (), //~ ERROR mismatched types [E0308]
     }
+
+    let foo = Foo { bar: 42 };
+    match unsafe { foo.bar } {
+        //~^ HELP you might have meant to use field `bar` of type `u32`
+        1u32 => (), //~ ERROR mismatched types [E0308]
+        _ => (),
+    }
 }
diff --git a/src/test/ui/suggestions/field-access.rs b/src/test/ui/suggestions/field-access.rs
index 2710ead4dfb..ad23c0ffa2e 100644
--- a/src/test/ui/suggestions/field-access.rs
+++ b/src/test/ui/suggestions/field-access.rs
@@ -10,6 +10,11 @@ enum B {
     Snd,
 }
 
+union Foo {
+    bar: u32,
+    qux: f32,
+}
+
 fn main() {
     let a = A { b: B::Fst };
     if let B::Fst = a {}; //~ ERROR mismatched types [E0308]
@@ -20,4 +25,11 @@ fn main() {
         B::Fst => (), //~ ERROR mismatched types [E0308]
         B::Snd => (), //~ ERROR mismatched types [E0308]
     }
+
+    let foo = Foo { bar: 42 };
+    match foo {
+        //~^ HELP you might have meant to use field `bar` of type `u32`
+        1u32 => (), //~ ERROR mismatched types [E0308]
+        _ => (),
+    }
 }
diff --git a/src/test/ui/suggestions/field-access.stderr b/src/test/ui/suggestions/field-access.stderr
index 228510902f5..aad9872032a 100644
--- a/src/test/ui/suggestions/field-access.stderr
+++ b/src/test/ui/suggestions/field-access.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/field-access.rs:15:12
+  --> $DIR/field-access.rs:20:12
    |
 LL |     Fst,
    |     --- unit variant defined here
@@ -15,7 +15,7 @@ LL |     if let B::Fst = a.b {};
    |                     ^^^
 
 error[E0308]: mismatched types
-  --> $DIR/field-access.rs:20:9
+  --> $DIR/field-access.rs:25:9
    |
 LL |     Fst,
    |     --- unit variant defined here
@@ -32,7 +32,7 @@ LL |     match a.b {
    |           ^^^
 
 error[E0308]: mismatched types
-  --> $DIR/field-access.rs:21:9
+  --> $DIR/field-access.rs:26:9
    |
 LL |     Snd,
    |     --- unit variant defined here
@@ -48,6 +48,20 @@ help: you might have meant to use field `b` of type `B`
 LL |     match a.b {
    |           ^^^
 
-error: aborting due to 3 previous errors
+error[E0308]: mismatched types
+  --> $DIR/field-access.rs:32:9
+   |
+LL |     match foo {
+   |           --- this expression has type `Foo`
+LL |
+LL |         1u32 => (),
+   |         ^^^^ expected union `Foo`, found `u32`
+   |
+help: you might have meant to use field `bar` of type `u32`
+   |
+LL |     match unsafe { foo.bar } {
+   |           ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0308`.