Report const eval errors at the correct span
This commit is contained in:
parent
13c0dc56df
commit
600fcc7159
@ -38,6 +38,7 @@ use syntax_pos::Span;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum PatternError {
|
||||
AssociatedConstInPattern(Span),
|
||||
StaticInPattern(Span),
|
||||
FloatBug,
|
||||
NonConstPath(Span),
|
||||
@ -150,7 +151,7 @@ impl<'tcx> fmt::Display for Pattern<'tcx> {
|
||||
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 @@ impl<'a, 'tcx> PatternContext<'a, '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 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
|
||||
-> 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 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
|
||||
}
|
||||
},
|
||||
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 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
|
||||
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 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
|
||||
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 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
|
||||
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 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
|
||||
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),
|
||||
};
|
||||
|
@ -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,
|
||||
|
@ -1637,9 +1637,11 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
||||
};
|
||||
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 {
|
||||
|
@ -203,6 +203,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
||||
bx.tcx(),
|
||||
ty::ParamEnv::empty(traits::Reveal::All),
|
||||
self.instance,
|
||||
constant.span,
|
||||
None,
|
||||
mir::Field::new(field as usize),
|
||||
c,
|
||||
|
Loading…
x
Reference in New Issue
Block a user