Skip to content

Commit 694cf75

Browse files
committed
Auto merge of #53821 - oli-obk:sanity_query, r=RalfJung
Report const eval error inside the query Functional changes: We no longer warn about bad constants embedded in unused types. This relied on being able to report just a warning, not a hard error on that case, which we cannot do any more now that error reporting is consistently centralized. r? @RalfJung fixes #53561
2 parents 82239b0 + 13d94ee commit 694cf75

File tree

148 files changed

+1130
-1229
lines changed

Some content is hidden

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

148 files changed

+1130
-1229
lines changed

src/librustc/dep_graph/dep_node.rs

+1
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/map/blocks.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ pub struct FnLikeNode<'a> { node: Node<'a> }
4343

4444
/// MaybeFnLike wraps a method that indicates if an object
4545
/// corresponds to some FnLikeNode.
46-
pub trait MaybeFnLike { fn is_fn_like(&self) -> bool; }
46+
trait MaybeFnLike { fn is_fn_like(&self) -> bool; }
4747

4848
impl MaybeFnLike for ast::Item {
4949
fn is_fn_like(&self) -> bool {

src/librustc/ich/impls_ty.rs

+4-8
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

+44-24
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ use std::{fmt, env};
1212

1313
use mir;
1414
use ty::{Ty, layout};
15-
use ty::layout::{Size, Align};
16-
use rustc_data_structures::sync::Lrc;
15+
use ty::layout::{Size, Align, LayoutError};
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, Copy, 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,12 @@ 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::Layout(LayoutError::Unknown(_)) |
117+
EvalErrorKind::TooGeneric => return Err(ErrorHandled::TooGeneric),
118+
EvalErrorKind::Layout(LayoutError::SizeOverflow(_)) |
119+
EvalErrorKind::TypeckError => return Err(ErrorHandled::Reported),
97120
_ => {},
98121
}
99122
trace!("reporting const eval failure at {:?}", self.span);
@@ -117,7 +140,7 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
117140
for FrameInfo { span, location, .. } in &self.stacktrace {
118141
err.span_label(*span, format!("inside call to `{}`", location));
119142
}
120-
Some(err)
143+
Ok(err)
121144
}
122145
}
123146

@@ -279,10 +302,9 @@ pub enum EvalErrorKind<'tcx, O> {
279302
TypeckError,
280303
/// Resolution can fail if we are in a too generic context
281304
TooGeneric,
282-
CheckMatchError,
283305
/// Cannot compute this constant because it depends on another one
284306
/// which already produced an error
285-
ReferencedConstant(Lrc<ConstEvalErr<'tcx>>),
307+
ReferencedConstant,
286308
GeneratorResumedAfterReturn,
287309
GeneratorResumedAfterPanic,
288310
InfiniteLoop,
@@ -407,9 +429,7 @@ impl<'tcx, O> EvalErrorKind<'tcx, O> {
407429
"encountered constants with type errors, stopping evaluation",
408430
TooGeneric =>
409431
"encountered overly generic constant",
410-
CheckMatchError =>
411-
"match checking failed",
412-
ReferencedConstant(_) =>
432+
ReferencedConstant =>
413433
"referenced constant has errors",
414434
Overflow(mir::BinOp::Add) => "attempt to add with overflow",
415435
Overflow(mir::BinOp::Sub) => "attempt to subtract with overflow",

src/librustc/mir/interpret/mod.rs

+6-6
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};
@@ -176,33 +176,33 @@ impl<'tcx, Tag> Pointer<Tag> {
176176
Pointer { alloc_id, offset, tag }
177177
}
178178

179-
pub fn wrapping_signed_offset<C: HasDataLayout>(self, i: i64, cx: C) -> Self {
179+
pub fn wrapping_signed_offset(self, i: i64, cx: impl HasDataLayout) -> Self {
180180
Pointer::new_with_tag(
181181
self.alloc_id,
182182
Size::from_bytes(cx.data_layout().wrapping_signed_offset(self.offset.bytes(), i)),
183183
self.tag,
184184
)
185185
}
186186

187-
pub fn overflowing_signed_offset<C: HasDataLayout>(self, i: i128, cx: C) -> (Self, bool) {
187+
pub fn overflowing_signed_offset(self, i: i128, cx: impl HasDataLayout) -> (Self, bool) {
188188
let (res, over) = cx.data_layout().overflowing_signed_offset(self.offset.bytes(), i);
189189
(Pointer::new_with_tag(self.alloc_id, Size::from_bytes(res), self.tag), over)
190190
}
191191

192-
pub fn signed_offset<C: HasDataLayout>(self, i: i64, cx: C) -> EvalResult<'tcx, Self> {
192+
pub fn signed_offset(self, i: i64, cx: impl HasDataLayout) -> EvalResult<'tcx, Self> {
193193
Ok(Pointer::new_with_tag(
194194
self.alloc_id,
195195
Size::from_bytes(cx.data_layout().signed_offset(self.offset.bytes(), i)?),
196196
self.tag,
197197
))
198198
}
199199

200-
pub fn overflowing_offset<C: HasDataLayout>(self, i: Size, cx: C) -> (Self, bool) {
200+
pub fn overflowing_offset(self, i: Size, cx: impl HasDataLayout) -> (Self, bool) {
201201
let (res, over) = cx.data_layout().overflowing_offset(self.offset.bytes(), i.bytes());
202202
(Pointer::new_with_tag(self.alloc_id, Size::from_bytes(res), self.tag), over)
203203
}
204204

205-
pub fn offset<C: HasDataLayout>(self, i: Size, cx: C) -> EvalResult<'tcx, Self> {
205+
pub fn offset(self, i: Size, cx: impl HasDataLayout) -> EvalResult<'tcx, Self> {
206206
Ok(Pointer::new_with_tag(
207207
self.alloc_id,
208208
Size::from_bytes(cx.data_layout().offset(self.offset.bytes(), i.bytes())?),

src/librustc/traits/error_reporting.rs

+4-12
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

+4-10
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,13 @@
99
// except according to those terms.
1010

1111
use infer::InferCtxt;
12-
use mir::interpret::GlobalId;
12+
use mir::interpret::{GlobalId, ErrorHandled};
1313
use ty::{self, Ty, TypeFoldable, ToPolyTraitRef, ToPredicate};
1414
use ty::error::ExpectedFound;
1515
use rustc_data_structures::obligation_forest::{Error, ForestObligation, ObligationForest};
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;
@@ -495,13 +493,9 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx,
495493
CodeSelectionError(ConstEvalFailure(err)))
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(
497+
ConstEvalFailure(ErrorHandled::TooGeneric)
498+
))
505499
}
506500
},
507501
None => {

src/librustc/traits/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use hir::def_id::DefId;
2323
use infer::SuppressRegionErrors;
2424
use infer::outlives::env::OutlivesEnvironment;
2525
use middle::region;
26-
use mir::interpret::ConstEvalErr;
26+
use mir::interpret::ErrorHandled;
2727
use ty::subst::Substs;
2828
use ty::{self, AdtKind, List, Ty, TyCtxt, GenericParamDefKind, ToPredicate};
2929
use ty::error::{ExpectedFound, TypeError};
@@ -438,7 +438,7 @@ pub enum SelectionError<'tcx> {
438438
ty::PolyTraitRef<'tcx>,
439439
ty::error::TypeError<'tcx>),
440440
TraitNotObjectSafe(DefId),
441-
ConstEvalFailure(Lrc<ConstEvalErr<'tcx>>),
441+
ConstEvalFailure(ErrorHandled),
442442
Overflow,
443443
}
444444

src/librustc/traits/structural_impls.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::SelectionError<'a> {
172172
)
173173
}
174174
super::TraitNotObjectSafe(def_id) => Some(super::TraitNotObjectSafe(def_id)),
175-
super::ConstEvalFailure(ref err) => tcx.lift(&**err).map(|err| super::ConstEvalFailure(
176-
err.into(),
177-
)),
175+
super::ConstEvalFailure(err) => Some(super::ConstEvalFailure(err)),
178176
super::Overflow => Some(super::Overflow),
179177
}
180178
}

src/librustc/ty/mod.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangIte
2727
use middle::privacy::AccessLevels;
2828
use middle::resolve_lifetime::ObjectLifetimeDefault;
2929
use mir::Mir;
30-
use mir::interpret::GlobalId;
30+
use mir::interpret::{GlobalId, ErrorHandled};
3131
use mir::GeneratorLayout;
3232
use session::CrateDisambiguator;
3333
use traits::{self, Reveal};
@@ -2191,18 +2191,18 @@ impl<'a, 'gcx, 'tcx> AdtDef {
21912191
None
21922192
}
21932193
}
2194-
Err(err) => {
2195-
err.report_as_error(
2196-
tcx.at(tcx.def_span(expr_did)),
2197-
"could not evaluate enum discriminant",
2198-
);
2194+
Err(ErrorHandled::Reported) => {
21992195
if !expr_did.is_local() {
22002196
span_bug!(tcx.def_span(expr_did),
22012197
"variant discriminant evaluation succeeded \
22022198
in its crate but failed locally");
22032199
}
22042200
None
22052201
}
2202+
Err(ErrorHandled::TooGeneric) => span_bug!(
2203+
tcx.def_span(expr_did),
2204+
"enum discriminant depends on generic arguments",
2205+
),
22062206
}
22072207
}
22082208

0 commit comments

Comments
 (0)