]> git.lizzy.rs Git - rust.git/commitdiff
Account for const fns to avoid incorrect suggestions
authorEsteban Küber <esteban@kuber.com.ar>
Tue, 30 Apr 2019 00:14:31 +0000 (17:14 -0700)
committerEsteban Küber <esteban@kuber.com.ar>
Tue, 30 Apr 2019 00:14:31 +0000 (17:14 -0700)
src/librustc/hir/map/mod.rs
src/librustc/hir/mod.rs
src/librustc_typeck/check/demand.rs
src/test/ui/numeric/const-scope.rs [new file with mode: 0644]
src/test/ui/numeric/const-scope.stderr [new file with mode: 0644]

index 9e95f0acfeb794a7d59aa4da9765e31676111b5a..826ae836a906e77e8bb4817ca056ddd4e1140da5 100644 (file)
@@ -734,6 +734,14 @@ pub fn is_argument(&self, id: NodeId) -> bool {
         }
     }
 
+    pub fn is_const_scope(&self, hir_id: HirId) -> bool {
+        self.walk_parent_nodes(hir_id, |node| match *node {
+            Node::Item(Item { node: ItemKind::Const(_, _), .. }) => true,
+            Node::Item(Item { node: ItemKind::Fn(_, header, _, _), .. }) => header.is_const(),
+            _ => false,
+        }, |_| false).map(|id| id != CRATE_HIR_ID).unwrap_or(false)
+    }
+
     /// If there is some error when walking the parents (e.g., a node does not
     /// have a parent in the map or a node can't be found), then we return the
     /// last good `NodeId` we found. Note that reaching the crate root (`id == 0`),
index 2e10300dced0ef273add3e875fe1a51dbe4b55a1..8418658ab6878ecc843c064721d9f6077d883388 100644 (file)
@@ -2288,6 +2288,15 @@ pub struct FnHeader {
     pub abi: Abi,
 }
 
+impl FnHeader {
+    pub fn is_const(&self) -> bool {
+        match &self.constness {
+            Constness::Const => true,
+            _ => false,
+        }
+    }
+}
+
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum ItemKind {
     /// An `extern crate` item, with optional *original* crate name if the crate was renamed.
index 6249d6e56af684e32cbfa0de4f128ce6c8d26598..689996ccb25a9304049c9cb27065078a9232eaca 100644 (file)
@@ -7,7 +7,7 @@
 use rustc::hir;
 use rustc::hir::def::Def;
 use rustc::hir::Node;
-use rustc::hir::{Item, ItemKind, print};
+use rustc::hir::print;
 use rustc::ty::{self, Ty, AssociatedItem};
 use rustc::ty::adjustment::AllowTwoPhase;
 use errors::{Applicability, DiagnosticBuilder};
@@ -550,14 +550,11 @@ pub fn check_for_cast(
         checked_ty: Ty<'tcx>,
         expected_ty: Ty<'tcx>,
     ) -> bool {
-        let parent_id = self.tcx.hir().get_parent_node_by_hir_id(expr.hir_id);
-        if let Some(parent) = self.tcx.hir().find_by_hir_id(parent_id) {
+        if self.tcx.hir().is_const_scope(expr.hir_id) {
             // Shouldn't suggest `.into()` on `const`s.
-            if let Node::Item(Item { node: ItemKind::Const(_, _), .. }) = parent {
-                // FIXME(estebank): modify once we decide to suggest `as` casts
-                return false;
-            }
-        };
+            // FIXME(estebank): modify once we decide to suggest `as` casts
+            return false;
+        }
 
         // If casting this expression to a given numeric type would be appropriate in case of a type
         // mismatch.
diff --git a/src/test/ui/numeric/const-scope.rs b/src/test/ui/numeric/const-scope.rs
new file mode 100644 (file)
index 0000000..053599a
--- /dev/null
@@ -0,0 +1,12 @@
+const C: i32 = 1i8; //~ ERROR mismatched types
+const D: i8 = C; //~ ERROR mismatched types
+
+const fn foo() {
+    let c: i32 = 1i8; //~ ERROR mismatched types
+    let d: i8 = c; //~ ERROR mismatched types
+}
+
+fn main() {
+    let c: i32 = 1i8; //~ ERROR mismatched types
+    let d: i8 = c; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/numeric/const-scope.stderr b/src/test/ui/numeric/const-scope.stderr
new file mode 100644 (file)
index 0000000..ead3a79
--- /dev/null
@@ -0,0 +1,47 @@
+error[E0308]: mismatched types
+  --> $DIR/const-scope.rs:1:16
+   |
+LL | const C: i32 = 1i8;
+   |                ^^^ expected i32, found i8
+
+error[E0308]: mismatched types
+  --> $DIR/const-scope.rs:2:15
+   |
+LL | const D: i8 = C;
+   |               ^ expected i8, found i32
+
+error[E0308]: mismatched types
+  --> $DIR/const-scope.rs:5:18
+   |
+LL |     let c: i32 = 1i8;
+   |                  ^^^ expected i32, found i8
+
+error[E0308]: mismatched types
+  --> $DIR/const-scope.rs:6:17
+   |
+LL |     let d: i8 = c;
+   |                 ^ expected i8, found i32
+
+error[E0308]: mismatched types
+  --> $DIR/const-scope.rs:10:18
+   |
+LL |     let c: i32 = 1i8;
+   |                  ^^^ expected i32, found i8
+help: change the type of the numeric literal from `i8` to `i32`
+   |
+LL |     let c: i32 = 1i32;
+   |                  ^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/const-scope.rs:11:17
+   |
+LL |     let d: i8 = c;
+   |                 ^ expected i8, found i32
+help: you can convert an `i32` to `i8` or panic if it the converted value wouldn't fit
+   |
+LL |     let d: i8 = c.try_into().unwrap();
+   |                 ^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0308`.