Skip to content

Commit 7fdf06c

Browse files
committed
Report const eval error inside the query
1 parent 3476ac0 commit 7fdf06c

File tree

135 files changed

+1470
-1088
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

135 files changed

+1470
-1088
lines changed

src/librustc/dep_graph/dep_node.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,7 @@ define_dep_nodes!( <'tcx>
530530
[] UsedTraitImports(DefId),
531531
[] HasTypeckTables(DefId),
532532
[] ConstEval { param_env: ParamEnvAnd<'tcx, GlobalId<'tcx>> },
533+
[] ConstEvalRaw { param_env: ParamEnvAnd<'tcx, GlobalId<'tcx>> },
533534
[] CheckMatch(DefId),
534535
[] SymbolName(DefId),
535536
[] InstanceSymbolName { instance: Instance<'tcx> },

src/librustc/hir/def.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ pub enum Def {
7474
SelfCtor(DefId /* impl */), // DefId refers to the impl
7575
Method(DefId),
7676
AssociatedConst(DefId),
77+
Closure(hir::BodyId),
7778

7879
Local(ast::NodeId),
7980
Upvar(ast::NodeId, // node id of closed over local
@@ -281,6 +282,7 @@ impl Def {
281282
id
282283
}
283284

285+
Def::Closure(_) |
284286
Def::Local(..) |
285287
Def::Upvar(..) |
286288
Def::Label(..) |
@@ -319,6 +321,7 @@ impl Def {
319321
Def::Trait(..) => "trait",
320322
Def::ForeignTy(..) => "foreign type",
321323
Def::Method(..) => "method",
324+
Def::Closure(_) => "closure",
322325
Def::Const(..) => "constant",
323326
Def::AssociatedConst(..) => "associated constant",
324327
Def::TyParam(..) => "type parameter",

src/librustc/hir/map/mod.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,9 +340,14 @@ impl<'hir> Map<'hir> {
340340
let def_id = self.local_def_id(variant.node.data.id());
341341
Some(Def::Variant(def_id))
342342
}
343+
Node::Expr(expr) => {
344+
match expr.node {
345+
ExprKind::Closure(_, _, body_id, _, _) => Some(Def::Closure(body_id)),
346+
_ => None,
347+
}
348+
}
343349
Node::Field(_) |
344350
Node::AnonConst(_) |
345-
Node::Expr(_) |
346351
Node::Stmt(_) |
347352
Node::Ty(_) |
348353
Node::TraitRef(_) |

src/librustc/ich/impls_hir.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,7 @@ impl_stable_hash_for!(enum hir::def::Def {
10441044
SelfCtor(impl_def_id),
10451045
VariantCtor(def_id, ctor_kind),
10461046
Method(def_id),
1047+
Closure(body_id),
10471048
AssociatedConst(def_id),
10481049
Local(def_id),
10491050
Upvar(def_id, index, expr_id),

src/librustc/ich/impls_ty.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -483,10 +483,9 @@ impl_stable_hash_for!(struct ty::Const<'tcx> {
483483
val
484484
});
485485

486-
impl_stable_hash_for!(struct ::mir::interpret::ConstEvalErr<'tcx> {
487-
span,
488-
stacktrace,
489-
error
486+
impl_stable_hash_for!(enum mir::interpret::ErrorHandled {
487+
Reported,
488+
TooGeneric
490489
});
491490

492491
impl_stable_hash_for!(struct ::mir::interpret::FrameInfo {
@@ -503,8 +502,6 @@ impl_stable_hash_for!(struct ty::GenericPredicates<'tcx> {
503502
predicates
504503
});
505504

506-
impl_stable_hash_for!(struct ::mir::interpret::EvalError<'tcx> { kind });
507-
508505
impl<'a, 'gcx, O: HashStable<StableHashingContext<'a>>> HashStable<StableHashingContext<'a>>
509506
for ::mir::interpret::EvalErrorKind<'gcx, O> {
510507
fn hash_stable<W: StableHasherResult>(&self,
@@ -543,14 +540,14 @@ for ::mir::interpret::EvalErrorKind<'gcx, O> {
543540
UnimplementedTraitSelection |
544541
TypeckError |
545542
TooGeneric |
546-
CheckMatchError |
547543
DerefFunctionPointer |
548544
ExecuteMemory |
549545
OverflowNeg |
550546
RemainderByZero |
551547
DivisionByZero |
552548
GeneratorResumedAfterReturn |
553549
GeneratorResumedAfterPanic |
550+
ReferencedConstant |
554551
InfiniteLoop => {}
555552
ReadUndefBytes(offset) => offset.hash_stable(hcx, hasher),
556553
InvalidDiscriminant(val) => val.hash_stable(hcx, hasher),
@@ -560,7 +557,6 @@ for ::mir::interpret::EvalErrorKind<'gcx, O> {
560557
line.hash_stable(hcx, hasher);
561558
col.hash_stable(hcx, hasher);
562559
},
563-
ReferencedConstant(ref err) => err.hash_stable(hcx, hasher),
564560
MachineError(ref err) => err.hash_stable(hcx, hasher),
565561
FunctionAbiMismatch(a, b) => {
566562
a.hash_stable(hcx, hasher);

src/librustc/mir/interpret/error.rs

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ use std::{fmt, env};
1313
use mir;
1414
use ty::{Ty, layout};
1515
use ty::layout::{Size, Align};
16-
use rustc_data_structures::sync::Lrc;
1716
use rustc_target::spec::abi::Abi;
1817

1918
use super::{
@@ -30,7 +29,26 @@ use syntax_pos::Span;
3029
use syntax::ast;
3130
use syntax::symbol::Symbol;
3231

33-
pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>>;
32+
#[derive(Debug, Clone, PartialEq, Eq)]
33+
pub enum ErrorHandled {
34+
/// Already reported a lint or an error for this evaluation
35+
Reported,
36+
/// Don't emit an error, the evaluation failed because the MIR was generic
37+
/// and the substs didn't fully monomorphize it.
38+
TooGeneric,
39+
}
40+
41+
impl ErrorHandled {
42+
pub fn assert_reported(self) {
43+
match self {
44+
ErrorHandled::Reported => {},
45+
ErrorHandled::TooGeneric => bug!("MIR interpretation failed without reporting an error \
46+
even though it was fully monomorphized"),
47+
}
48+
}
49+
}
50+
51+
pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ErrorHandled>;
3452

3553
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
3654
pub struct ConstEvalErr<'tcx> {
@@ -50,33 +68,41 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
5068
pub fn struct_error(&self,
5169
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
5270
message: &str)
53-
-> Option<DiagnosticBuilder<'tcx>>
71+
-> Result<DiagnosticBuilder<'tcx>, ErrorHandled>
5472
{
5573
self.struct_generic(tcx, message, None)
5674
}
5775

5876
pub fn report_as_error(&self,
5977
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
6078
message: &str
61-
) {
79+
) -> ErrorHandled {
6280
let err = self.struct_error(tcx, message);
63-
if let Some(mut err) = err {
64-
err.emit();
81+
match err {
82+
Ok(mut err) => {
83+
err.emit();
84+
ErrorHandled::Reported
85+
},
86+
Err(err) => err,
6587
}
6688
}
6789

6890
pub fn report_as_lint(&self,
6991
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
7092
message: &str,
7193
lint_root: ast::NodeId,
72-
) {
94+
) -> ErrorHandled {
7395
let lint = self.struct_generic(
7496
tcx,
7597
message,
7698
Some(lint_root),
7799
);
78-
if let Some(mut lint) = lint {
79-
lint.emit();
100+
match lint {
101+
Ok(mut lint) => {
102+
lint.emit();
103+
ErrorHandled::Reported
104+
},
105+
Err(err) => err,
80106
}
81107
}
82108

@@ -85,15 +111,11 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
85111
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
86112
message: &str,
87113
lint_root: Option<ast::NodeId>,
88-
) -> Option<DiagnosticBuilder<'tcx>> {
114+
) -> Result<DiagnosticBuilder<'tcx>, ErrorHandled> {
89115
match self.error.kind {
90-
::mir::interpret::EvalErrorKind::TypeckError |
91-
::mir::interpret::EvalErrorKind::TooGeneric |
92-
::mir::interpret::EvalErrorKind::CheckMatchError |
93-
::mir::interpret::EvalErrorKind::Layout(_) => return None,
94-
::mir::interpret::EvalErrorKind::ReferencedConstant(ref inner) => {
95-
inner.struct_generic(tcx, "referenced constant has errors", lint_root)?.emit();
96-
},
116+
EvalErrorKind::TooGeneric => return Err(ErrorHandled::TooGeneric),
117+
EvalErrorKind::TypeckError |
118+
EvalErrorKind::Layout(_) => return Err(ErrorHandled::Reported),
97119
_ => {},
98120
}
99121
trace!("reporting const eval failure at {:?}", self.span);
@@ -117,7 +139,7 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
117139
for FrameInfo { span, location, .. } in &self.stacktrace {
118140
err.span_label(*span, format!("inside call to `{}`", location));
119141
}
120-
Some(err)
142+
Ok(err)
121143
}
122144
}
123145

@@ -279,10 +301,9 @@ pub enum EvalErrorKind<'tcx, O> {
279301
TypeckError,
280302
/// Resolution can fail if we are in a too generic context
281303
TooGeneric,
282-
CheckMatchError,
283304
/// Cannot compute this constant because it depends on another one
284305
/// which already produced an error
285-
ReferencedConstant(Lrc<ConstEvalErr<'tcx>>),
306+
ReferencedConstant,
286307
GeneratorResumedAfterReturn,
287308
GeneratorResumedAfterPanic,
288309
InfiniteLoop,
@@ -407,9 +428,7 @@ impl<'tcx, O> EvalErrorKind<'tcx, O> {
407428
"encountered constants with type errors, stopping evaluation",
408429
TooGeneric =>
409430
"encountered overly generic constant",
410-
CheckMatchError =>
411-
"match checking failed",
412-
ReferencedConstant(_) =>
431+
ReferencedConstant =>
413432
"referenced constant has errors",
414433
Overflow(mir::BinOp::Add) => "attempt to add with overflow",
415434
Overflow(mir::BinOp::Sub) => "attempt to subtract with overflow",

src/librustc/mir/interpret/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ mod value;
2020

2121
pub use self::error::{
2222
EvalError, EvalResult, EvalErrorKind, AssertMessage, ConstEvalErr, struct_error,
23-
FrameInfo, ConstEvalResult,
23+
FrameInfo, ConstEvalResult, ErrorHandled,
2424
};
2525

2626
pub use self::value::{Scalar, ConstValue};

src/librustc/traits/error_reporting.rs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -880,18 +880,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
880880
self.tcx.report_object_safety_error(span, did, violations)
881881
}
882882

883-
ConstEvalFailure(ref err) => {
884-
match err.struct_error(
885-
self.tcx.at(span),
886-
"could not evaluate constant expression",
887-
) {
888-
Some(err) => err,
889-
None => {
890-
self.tcx.sess.delay_span_bug(span,
891-
&format!("constant in type had an ignored error: {:?}", err));
892-
return;
893-
}
894-
}
883+
// already reported in the query
884+
ConstEvalFailure => {
885+
self.tcx.sess.delay_span_bug(span, "constant in type had an ignored error");
886+
return;
895887
}
896888

897889
Overflow => {

src/librustc/traits/fulfill.rs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ use rustc_data_structures::obligation_forest::{Error, ForestObligation, Obligati
1616
use rustc_data_structures::obligation_forest::{ObligationProcessor, ProcessResult};
1717
use std::marker::PhantomData;
1818
use hir::def_id::DefId;
19-
use mir::interpret::ConstEvalErr;
20-
use mir::interpret::EvalErrorKind;
2119

2220
use super::CodeAmbiguity;
2321
use super::CodeProjectionError;
@@ -491,17 +489,11 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx,
491489
match self.selcx.tcx().at(obligation.cause.span)
492490
.const_eval(param_env.and(cid)) {
493491
Ok(_) => ProcessResult::Changed(vec![]),
494-
Err(err) => ProcessResult::Error(
495-
CodeSelectionError(ConstEvalFailure(err)))
492+
Err(_) => ProcessResult::Error(
493+
CodeSelectionError(ConstEvalFailure))
496494
}
497495
} else {
498-
ProcessResult::Error(
499-
CodeSelectionError(ConstEvalFailure(ConstEvalErr {
500-
span: obligation.cause.span,
501-
error: EvalErrorKind::TooGeneric.into(),
502-
stacktrace: vec![],
503-
}.into()))
504-
)
496+
ProcessResult::Error(CodeSelectionError(ConstEvalFailure))
505497
}
506498
},
507499
None => {

src/librustc/traits/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ use hir::def_id::DefId;
2323
use infer::SuppressRegionErrors;
2424
use infer::outlives::env::OutlivesEnvironment;
2525
use middle::region;
26-
use mir::interpret::ConstEvalErr;
2726
use ty::subst::Substs;
2827
use ty::{self, AdtKind, List, Ty, TyCtxt, GenericParamDefKind, ToPredicate};
2928
use ty::error::{ExpectedFound, TypeError};
@@ -438,7 +437,7 @@ pub enum SelectionError<'tcx> {
438437
ty::PolyTraitRef<'tcx>,
439438
ty::error::TypeError<'tcx>),
440439
TraitNotObjectSafe(DefId),
441-
ConstEvalFailure(Lrc<ConstEvalErr<'tcx>>),
440+
ConstEvalFailure,
442441
Overflow,
443442
}
444443

0 commit comments

Comments
 (0)