about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-04-27 04:46:45 +0000
committerbors <bors@rust-lang.org>2021-04-27 04:46:45 +0000
commit22b686ad9995266b695344fcfb8e14f710b9ea6b (patch)
tree92ade2a0eaf3ae96cb385f241e499c54fe6db1c1
parent6eb956fcbb040d9d4276d97944b5c6df2f84ede8 (diff)
parented903f9b912630f0e5fc92101b3e3bc5c99f558d (diff)
downloadrust-22b686ad9995266b695344fcfb8e14f710b9ea6b.tar.gz
rust-22b686ad9995266b695344fcfb8e14f710b9ea6b.zip
Auto merge of #77246 - yaahc:typeof-errors, r=oli-obk
try enabling typeof for fun error messages
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs4
-rw-r--r--compiler/rustc_typeck/src/check/mod.rs6
-rw-r--r--compiler/rustc_typeck/src/collect/type_of.rs4
-rw-r--r--src/test/ui/typeof/type_mismatch.rs9
-rw-r--r--src/test/ui/typeof/type_mismatch.stderr23
5 files changed, 43 insertions, 3 deletions
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index 62a1584d16b..2f2e90e4bd6 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -2279,9 +2279,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 let array_ty = tcx.mk_ty(ty::Array(self.ast_ty_to_ty(&ty), length));
                 self.normalize_ty(ast_ty.span, array_ty)
             }
-            hir::TyKind::Typeof(ref _e) => {
+            hir::TyKind::Typeof(ref e) => {
                 tcx.sess.emit_err(TypeofReservedKeywordUsed { span: ast_ty.span });
-                tcx.ty_error()
+                tcx.type_of(tcx.hir().local_def_id(e.hir_id))
             }
             hir::TyKind::Infer => {
                 // Infer also appears as the type of arguments or return
diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs
index 80e173de6b6..cb4257e0534 100644
--- a/compiler/rustc_typeck/src/check/mod.rs
+++ b/compiler/rustc_typeck/src/check/mod.rs
@@ -540,6 +540,12 @@ fn typeck_with_fallback<'tcx>(
                             kind: TypeVariableOriginKind::TypeInference,
                             span,
                         }),
+                        Node::Ty(&hir::Ty {
+                            kind: hir::TyKind::Typeof(ref anon_const), ..
+                        }) if anon_const.hir_id == id => fcx.next_ty_var(TypeVariableOrigin {
+                            kind: TypeVariableOriginKind::TypeInference,
+                            span,
+                        }),
                         Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(ia), .. })
                             if ia.operands.iter().any(|(op, _op_sp)| match op {
                                 hir::InlineAsmOperand::Const { anon_const } => {
diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs
index d8eea1ad80b..51d5f4ebe2b 100644
--- a/compiler/rustc_typeck/src/collect/type_of.rs
+++ b/compiler/rustc_typeck/src/collect/type_of.rs
@@ -417,12 +417,14 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
             let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id));
             match parent_node {
                 Node::Ty(&Ty { kind: TyKind::Array(_, ref constant), .. })
-                | Node::Ty(&Ty { kind: TyKind::Typeof(ref constant), .. })
                 | Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
                     if constant.hir_id == hir_id =>
                 {
                     tcx.types.usize
                 }
+                Node::Ty(&Ty { kind: TyKind::Typeof(ref e), .. }) if e.hir_id == hir_id => {
+                    tcx.typeck(def_id).node_type(e.hir_id)
+                }
 
                 Node::Expr(&Expr { kind: ExprKind::ConstBlock(ref anon_const), .. })
                     if anon_const.hir_id == hir_id =>
diff --git a/src/test/ui/typeof/type_mismatch.rs b/src/test/ui/typeof/type_mismatch.rs
new file mode 100644
index 00000000000..3f8339fa5be
--- /dev/null
+++ b/src/test/ui/typeof/type_mismatch.rs
@@ -0,0 +1,9 @@
+// Test that using typeof results in the correct type mismatch errors instead of always assuming
+// `usize`, in addition to the pre-existing "typeof is reserved and unimplemented" error
+fn main() {
+    const a: u8 = 1;
+    let b: typeof(a) = 1i8;
+    //~^ ERROR `typeof` is a reserved keyword but unimplemented
+    //~| ERROR mismatched types
+    //~| expected `u8`, found `i8`
+}
diff --git a/src/test/ui/typeof/type_mismatch.stderr b/src/test/ui/typeof/type_mismatch.stderr
new file mode 100644
index 00000000000..12fd7c9963c
--- /dev/null
+++ b/src/test/ui/typeof/type_mismatch.stderr
@@ -0,0 +1,23 @@
+error[E0516]: `typeof` is a reserved keyword but unimplemented
+  --> $DIR/type_mismatch.rs:5:12
+   |
+LL |     let b: typeof(a) = 1i8;
+   |            ^^^^^^^^^ reserved keyword
+
+error[E0308]: mismatched types
+  --> $DIR/type_mismatch.rs:5:24
+   |
+LL |     let b: typeof(a) = 1i8;
+   |            ---------   ^^^ expected `u8`, found `i8`
+   |            |
+   |            expected due to this
+   |
+help: change the type of the numeric literal from `i8` to `u8`
+   |
+LL |     let b: typeof(a) = 1u8;
+   |                        ^^^
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0308, E0516.
+For more information about an error, try `rustc --explain E0308`.