]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_typeck/astconv.rs
Rollup merge of #68153 - petrochenkov:privdiag, r=estebank
[rust.git] / src / librustc_typeck / astconv.rs
index 851c2f76adab7f310d126ac62a7e32cd2925dd55..a3be264ddc12837e222c0287fe6c0c9698e5d147 100644 (file)
@@ -1,3 +1,4 @@
+// ignore-tidy-filelength FIXME(#67418) Split up this file.
 //! Conversion from AST representation of types to the `ty.rs` representation.
 //! The main routine here is `ast_ty_to_ty()`; each use is parameterized by an
 //! instance of `AstConv`.
@@ -10,6 +11,7 @@
 use crate::require_c_abi_if_c_variadic;
 use crate::util::common::ErrorReported;
 use rustc::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
+use rustc::session::parse::feature_err;
 use rustc::traits;
 use rustc::traits::astconv_object_safety_violations;
 use rustc::traits::error_reporting::report_object_safety_error;
 use rustc_target::spec::abi;
 use smallvec::SmallVec;
 use syntax::ast;
-use syntax::feature_gate::feature_err;
 use syntax::util::lev_distance::find_best_match_for_name;
 
 use std::collections::BTreeSet;
 use std::iter;
 use std::slice;
 
+use rustc::mir::interpret::LitToConstInput;
 use rustc_error_codes::*;
 
 #[derive(Debug)]
@@ -2699,13 +2701,28 @@ pub fn ast_const_to_const(
         let tcx = self.tcx();
         let def_id = tcx.hir().local_def_id(ast_const.hir_id);
 
-        let mut const_ = ty::Const {
-            val: ty::ConstKind::Unevaluated(def_id, InternalSubsts::identity_for_item(tcx, def_id)),
-            ty,
+        let expr = &tcx.hir().body(ast_const.body).value;
+
+        let lit_input = match expr.kind {
+            hir::ExprKind::Lit(ref lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
+            hir::ExprKind::Unary(hir::UnOp::UnNeg, ref expr) => match expr.kind {
+                hir::ExprKind::Lit(ref lit) => {
+                    Some(LitToConstInput { lit: &lit.node, ty, neg: true })
+                }
+                _ => None,
+            },
+            _ => None,
         };
 
-        let expr = &tcx.hir().body(ast_const.body).value;
-        if let Some(def_id) = self.const_param_def_id(expr) {
+        if let Some(lit_input) = lit_input {
+            // If an error occurred, ignore that it's a literal and leave reporting the error up to
+            // mir.
+            if let Ok(c) = tcx.at(expr.span).lit_to_const(lit_input) {
+                return c;
+            }
+        }
+
+        let kind = if let Some(def_id) = self.const_param_def_id(expr) {
             // Find the name and index of the const parameter by indexing the generics of the
             // parent item and construct a `ParamConst`.
             let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
@@ -2714,10 +2731,11 @@ pub fn ast_const_to_const(
             let generics = tcx.generics_of(item_def_id);
             let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(hir_id)];
             let name = tcx.hir().name(hir_id);
-            const_.val = ty::ConstKind::Param(ty::ParamConst::new(index, name));
-        }
-
-        tcx.mk_const(const_)
+            ty::ConstKind::Param(ty::ParamConst::new(index, name))
+        } else {
+            ty::ConstKind::Unevaluated(def_id, InternalSubsts::identity_for_item(tcx, def_id), None)
+        };
+        tcx.mk_const(ty::Const { val: kind, ty })
     }
 
     pub fn impl_trait_ty_to_ty(