]> git.lizzy.rs Git - rust.git/commitdiff
Report const eval errors at the correct span
authorOliver Schneider <git-no-reply-9879165716479413131@oli-obk.de>
Mon, 29 Jan 2018 18:53:46 +0000 (19:53 +0100)
committerOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>
Thu, 8 Mar 2018 07:34:14 +0000 (08:34 +0100)
src/librustc_mir/hair/pattern/mod.rs
src/librustc_mir/interpret/const_eval.rs
src/librustc_mir/interpret/eval_context.rs
src/librustc_trans/mir/constant.rs

index 1141425c554a96a564d72fa473b7e148c26959fa..3dba00d1fb1b24d66a0ee54fa58f704584c4c77b 100644 (file)
@@ -38,6 +38,7 @@
 
 #[derive(Clone, Debug)]
 pub enum PatternError {
+    AssociatedConstInPattern(Span),
     StaticInPattern(Span),
     FloatBug,
     NonConstPath(Span),
@@ -150,7 +151,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                     BindingMode::ByValue => mutability == Mutability::Mut,
                     BindingMode::ByRef(_, bk) => {
                         write!(f, "ref ")?;
-                        bk == BorrowKind::Mut
+                        match bk { BorrowKind::Mut { .. } => true, _ => false }
                     }
                 };
                 if is_mut {
@@ -462,7 +463,7 @@ fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat) -> Pattern<'tcx> {
                         (Mutability::Not, BindingMode::ByValue),
                     ty::BindByReference(hir::MutMutable) =>
                         (Mutability::Not, BindingMode::ByRef(
-                            region.unwrap(), BorrowKind::Mut)),
+                            region.unwrap(), BorrowKind::Mut { allow_two_phase_borrow: false })),
                     ty::BindByReference(hir::MutImmutable) =>
                         (Mutability::Not, BindingMode::ByRef(
                             region.unwrap(), BorrowKind::Shared)),
@@ -672,6 +673,10 @@ fn lower_path(&mut self,
                   -> Pattern<'tcx> {
         let ty = self.tables.node_id_to_type(id);
         let def = self.tables.qpath_def(qpath, id);
+        let is_associated_const = match def {
+            Def::AssociatedConst(_) => true,
+            _ => false,
+        };
         let kind = match def {
             Def::Const(def_id) | Def::AssociatedConst(def_id) => {
                 let substs = self.tables.node_substs(id);
@@ -697,7 +702,11 @@ fn lower_path(&mut self,
                         }
                     },
                     None => {
-                        self.errors.push(PatternError::StaticInPattern(span));
+                        self.errors.push(if is_associated_const {
+                            PatternError::AssociatedConstInPattern(span)
+                        } else {
+                            PatternError::StaticInPattern(span)
+                        });
                         PatternKind::Wild
                     },
                 }
@@ -814,7 +823,7 @@ fn const_to_pat(
                                 let field = Field::new(i);
                                 let val = match cv.val {
                                     ConstVal::Value(miri) => const_val_field(
-                                        self.tcx, self.param_env, instance,
+                                        self.tcx, self.param_env, instance, span,
                                         Some(variant_index), field, miri, cv.ty,
                                     ).unwrap(),
                                     _ => bug!("{:#?} is not a valid tuple", cv),
@@ -842,7 +851,8 @@ fn const_to_pat(
                         let field = Field::new(i);
                         let val = match cv.val {
                             ConstVal::Value(miri) => const_val_field(
-                                self.tcx, self.param_env, instance, None, field, miri, cv.ty,
+                                self.tcx, self.param_env, instance, span,
+                                None, field, miri, cv.ty,
                             ).unwrap(),
                             _ => bug!("{:#?} is not a valid tuple", cv),
                         };
@@ -859,7 +869,8 @@ fn const_to_pat(
                         let field = Field::new(i);
                         let val = match cv.val {
                             ConstVal::Value(miri) => const_val_field(
-                                self.tcx, self.param_env, instance, None, field, miri, cv.ty,
+                                self.tcx, self.param_env, instance, span,
+                                None, field, miri, cv.ty,
                             ).unwrap(),
                             _ => bug!("{:#?} is not a valid tuple", cv),
                         };
@@ -877,7 +888,8 @@ fn const_to_pat(
                         let field = Field::new(i);
                         let val = match cv.val {
                             ConstVal::Value(miri) => const_val_field(
-                                self.tcx, self.param_env, instance, None, field, miri, cv.ty,
+                                self.tcx, self.param_env, instance, span,
+                                None, field, miri, cv.ty,
                             ).unwrap(),
                             _ => bug!("{:#?} is not a valid tuple", cv),
                         };
index 6c1d762c912cf7cdd797f9c254c96aabbbbca7f1..c2f9690b9f19604094a064e82e1697a5951001a7 100644 (file)
@@ -374,6 +374,7 @@ pub fn const_val_field<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     instance: ty::Instance<'tcx>,
+    span: Span,
     variant: Option<usize>,
     field: mir::Field,
     val: Value,
@@ -385,7 +386,7 @@ pub fn const_val_field<'a, 'tcx>(
             ty,
         })),
         Err(err) => Err(ConstEvalErr {
-            span: tcx.def_span(instance.def_id()),
+            span,
             kind: err.into(),
         }),
     }
@@ -455,7 +456,6 @@ pub fn const_eval_provider<'a, 'tcx>(
     trace!("const eval: {:?}", key);
     let cid = key.value;
     let def_id = cid.instance.def.def_id();
-    let span = tcx.def_span(def_id);
 
     if tcx.is_foreign_item(def_id) {
         let id = tcx.interpret_interner.get_cached(def_id);
@@ -479,6 +479,7 @@ pub fn const_eval_provider<'a, 'tcx>(
 
     if let Some(id) = tcx.hir.as_local_node_id(def_id) {
         let tables = tcx.typeck_tables_of(def_id);
+        let span = tcx.def_span(def_id);
 
         // Do match-check before building MIR
         if tcx.check_match(def_id).is_err() {
@@ -511,6 +512,7 @@ pub fn const_eval_provider<'a, 'tcx>(
         if tcx.is_static(def_id).is_some() {
             ecx.report(&mut err, true, None);
         }
+        let span = ecx.frame().span;
         ConstEvalErr {
             kind: err.into(),
             span,
index 08152019003f15e6f09d37df617f2257dedb20f1..71450f4266576e82c6adcb62a8b867da0c796e20 100644 (file)
@@ -1637,9 +1637,11 @@ pub fn report(&self, e: &mut EvalError, as_err: bool, explicit_span: Option<Span
             };
             err.span_label(span, e.to_string());
             let mut last_span = None;
-            for &Frame { instance, span, .. } in self.stack().iter().rev() {
+            // skip 1 because the last frame is just the environment of the constant
+            for &Frame { instance, span, .. } in self.stack().iter().skip(1).rev() {
                 // make sure we don't emit frames that are duplicates of the previous
                 if explicit_span == Some(span) {
+                    last_span = Some(span);
                     continue;
                 }
                 if let Some(last) = last_span {
index 6aa8b7e5449fd1e6037d0e0ef7cfa2b41ee762df..8018073883fcc1a4126894dea000e633bc8bc71d 100644 (file)
@@ -203,6 +203,7 @@ pub fn simd_shuffle_indices(
                         bx.tcx(),
                         ty::ParamEnv::empty(traits::Reveal::All),
                         self.instance,
+                        constant.span,
                         None,
                         mir::Field::new(field as usize),
                         c,