@@ -12,8 +12,7 @@ use std::{fmt, env};
12
12
13
13
use mir;
14
14
use ty:: { Ty , layout} ;
15
- use ty:: layout:: { Size , Align } ;
16
- use rustc_data_structures:: sync:: Lrc ;
15
+ use ty:: layout:: { Size , Align , LayoutError } ;
17
16
use rustc_target:: spec:: abi:: Abi ;
18
17
19
18
use super :: {
@@ -30,7 +29,26 @@ use syntax_pos::Span;
30
29
use syntax:: ast;
31
30
use syntax:: symbol:: Symbol ;
32
31
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 > ;
34
52
35
53
#[ derive( Clone , Debug , RustcEncodable , RustcDecodable ) ]
36
54
pub struct ConstEvalErr < ' tcx > {
@@ -50,33 +68,41 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
50
68
pub fn struct_error ( & self ,
51
69
tcx : TyCtxtAt < ' a , ' gcx , ' tcx > ,
52
70
message : & str )
53
- -> Option < DiagnosticBuilder < ' tcx > >
71
+ -> Result < DiagnosticBuilder < ' tcx > , ErrorHandled >
54
72
{
55
73
self . struct_generic ( tcx, message, None )
56
74
}
57
75
58
76
pub fn report_as_error ( & self ,
59
77
tcx : TyCtxtAt < ' a , ' gcx , ' tcx > ,
60
78
message : & str
61
- ) {
79
+ ) -> ErrorHandled {
62
80
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,
65
87
}
66
88
}
67
89
68
90
pub fn report_as_lint ( & self ,
69
91
tcx : TyCtxtAt < ' a , ' gcx , ' tcx > ,
70
92
message : & str ,
71
93
lint_root : ast:: NodeId ,
72
- ) {
94
+ ) -> ErrorHandled {
73
95
let lint = self . struct_generic (
74
96
tcx,
75
97
message,
76
98
Some ( lint_root) ,
77
99
) ;
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,
80
106
}
81
107
}
82
108
@@ -85,15 +111,12 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
85
111
tcx : TyCtxtAt < ' a , ' gcx , ' tcx > ,
86
112
message : & str ,
87
113
lint_root : Option < ast:: NodeId > ,
88
- ) -> Option < DiagnosticBuilder < ' tcx > > {
114
+ ) -> Result < DiagnosticBuilder < ' tcx > , ErrorHandled > {
89
115
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 ) ,
97
120
_ => { } ,
98
121
}
99
122
trace ! ( "reporting const eval failure at {:?}" , self . span) ;
@@ -117,7 +140,7 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
117
140
for FrameInfo { span, location, .. } in & self . stacktrace {
118
141
err. span_label ( * span, format ! ( "inside call to `{}`" , location) ) ;
119
142
}
120
- Some ( err)
143
+ Ok ( err)
121
144
}
122
145
}
123
146
@@ -279,10 +302,9 @@ pub enum EvalErrorKind<'tcx, O> {
279
302
TypeckError ,
280
303
/// Resolution can fail if we are in a too generic context
281
304
TooGeneric ,
282
- CheckMatchError ,
283
305
/// Cannot compute this constant because it depends on another one
284
306
/// which already produced an error
285
- ReferencedConstant ( Lrc < ConstEvalErr < ' tcx > > ) ,
307
+ ReferencedConstant ,
286
308
GeneratorResumedAfterReturn ,
287
309
GeneratorResumedAfterPanic ,
288
310
InfiniteLoop ,
@@ -407,9 +429,7 @@ impl<'tcx, O> EvalErrorKind<'tcx, O> {
407
429
"encountered constants with type errors, stopping evaluation" ,
408
430
TooGeneric =>
409
431
"encountered overly generic constant" ,
410
- CheckMatchError =>
411
- "match checking failed" ,
412
- ReferencedConstant ( _) =>
432
+ ReferencedConstant =>
413
433
"referenced constant has errors" ,
414
434
Overflow ( mir:: BinOp :: Add ) => "attempt to add with overflow" ,
415
435
Overflow ( mir:: BinOp :: Sub ) => "attempt to subtract with overflow" ,
0 commit comments