@@ -86,6 +86,59 @@ impl<'tcx> ConstEvalErr<'tcx> {
86
86
self . report_decorated ( tcx, message, |_| { } )
87
87
}
88
88
89
+ #[ instrument( level = "trace" , skip( self , decorate) ) ]
90
+ pub ( super ) fn decorate ( & self , err : & mut Diagnostic , decorate : impl FnOnce ( & mut Diagnostic ) ) {
91
+ trace ! ( "reporting const eval failure at {:?}" , self . span) ;
92
+ // Add some more context for select error types.
93
+ match self . error {
94
+ InterpError :: Unsupported (
95
+ UnsupportedOpInfo :: ReadPointerAsBytes
96
+ | UnsupportedOpInfo :: PartialPointerOverwrite ( _)
97
+ | UnsupportedOpInfo :: PartialPointerCopy ( _) ,
98
+ ) => {
99
+ err. help ( "this code performed an operation that depends on the underlying bytes representing a pointer" ) ;
100
+ err. help ( "the absolute address of a pointer is not known at compile-time, so such operations are not supported" ) ;
101
+ }
102
+ _ => { }
103
+ }
104
+ // Add spans for the stacktrace. Don't print a single-line backtrace though.
105
+ if self . stacktrace . len ( ) > 1 {
106
+ // Helper closure to print duplicated lines.
107
+ let mut flush_last_line = |last_frame, times| {
108
+ if let Some ( ( line, span) ) = last_frame {
109
+ err. span_note ( span, & line) ;
110
+ // Don't print [... additional calls ...] if the number of lines is small
111
+ if times < 3 {
112
+ for _ in 0 ..times {
113
+ err. span_note ( span, & line) ;
114
+ }
115
+ } else {
116
+ err. span_note (
117
+ span,
118
+ format ! ( "[... {} additional calls {} ...]" , times, & line) ,
119
+ ) ;
120
+ }
121
+ }
122
+ } ;
123
+
124
+ let mut last_frame = None ;
125
+ let mut times = 0 ;
126
+ for frame_info in & self . stacktrace {
127
+ let frame = ( frame_info. to_string ( ) , frame_info. span ) ;
128
+ if last_frame. as_ref ( ) == Some ( & frame) {
129
+ times += 1 ;
130
+ } else {
131
+ flush_last_line ( last_frame, times) ;
132
+ last_frame = Some ( frame) ;
133
+ times = 0 ;
134
+ }
135
+ }
136
+ flush_last_line ( last_frame, times) ;
137
+ }
138
+ // Let the caller attach any additional information it wants.
139
+ decorate ( err) ;
140
+ }
141
+
89
142
/// Create a diagnostic for this const eval error.
90
143
///
91
144
/// Sets the message passed in via `message` and adds span labels with detailed error
@@ -101,88 +154,30 @@ impl<'tcx> ConstEvalErr<'tcx> {
101
154
message : & str ,
102
155
decorate : impl FnOnce ( & mut Diagnostic ) ,
103
156
) -> ErrorHandled {
104
- let finish = |err : & mut Diagnostic , span_msg : Option < String > | {
105
- trace ! ( "reporting const eval failure at {:?}" , self . span) ;
106
- if let Some ( span_msg) = span_msg {
107
- err. span_label ( self . span , span_msg) ;
108
- }
109
- // Add some more context for select error types.
110
- match self . error {
111
- InterpError :: Unsupported (
112
- UnsupportedOpInfo :: ReadPointerAsBytes
113
- | UnsupportedOpInfo :: PartialPointerOverwrite ( _)
114
- | UnsupportedOpInfo :: PartialPointerCopy ( _) ,
115
- ) => {
116
- err. help ( "this code performed an operation that depends on the underlying bytes representing a pointer" ) ;
117
- err. help ( "the absolute address of a pointer is not known at compile-time, so such operations are not supported" ) ;
118
- }
119
- _ => { }
120
- }
121
- // Add spans for the stacktrace. Don't print a single-line backtrace though.
122
- if self . stacktrace . len ( ) > 1 {
123
- // Helper closure to print duplicated lines.
124
- let mut flush_last_line = |last_frame, times| {
125
- if let Some ( ( line, span) ) = last_frame {
126
- err. span_note ( span, & line) ;
127
- // Don't print [... additional calls ...] if the number of lines is small
128
- if times < 3 {
129
- for _ in 0 ..times {
130
- err. span_note ( span, & line) ;
131
- }
132
- } else {
133
- err. span_note (
134
- span,
135
- format ! ( "[... {} additional calls {} ...]" , times, & line) ,
136
- ) ;
137
- }
138
- }
139
- } ;
140
-
141
- let mut last_frame = None ;
142
- let mut times = 0 ;
143
- for frame_info in & self . stacktrace {
144
- let frame = ( frame_info. to_string ( ) , frame_info. span ) ;
145
- if last_frame. as_ref ( ) == Some ( & frame) {
146
- times += 1 ;
147
- } else {
148
- flush_last_line ( last_frame, times) ;
149
- last_frame = Some ( frame) ;
150
- times = 0 ;
151
- }
152
- }
153
- flush_last_line ( last_frame, times) ;
154
- }
155
- // Let the caller attach any additional information it wants.
156
- decorate ( err) ;
157
- } ;
158
-
159
157
debug ! ( "self.error: {:?}" , self . error) ;
160
158
// Special handling for certain errors
161
159
match & self . error {
162
160
// Don't emit a new diagnostic for these errors
163
161
err_inval ! ( Layout ( LayoutError :: Unknown ( _) ) ) | err_inval ! ( TooGeneric ) => {
164
- return ErrorHandled :: TooGeneric ;
165
- }
166
- err_inval ! ( AlreadyReported ( error_reported) ) => {
167
- return ErrorHandled :: Reported ( * error_reported) ;
162
+ ErrorHandled :: TooGeneric
168
163
}
164
+ err_inval ! ( AlreadyReported ( error_reported) ) => ErrorHandled :: Reported ( * error_reported) ,
169
165
err_inval ! ( Layout ( LayoutError :: SizeOverflow ( _) ) ) => {
170
166
// We must *always* hard error on these, even if the caller wants just a lint.
171
167
// The `message` makes little sense here, this is a more serious error than the
172
168
// caller thinks anyway.
173
169
// See <https://github.com/rust-lang/rust/pull/63152>.
174
170
let mut err = struct_error ( tcx, & self . error . to_string ( ) ) ;
175
- finish ( & mut err, None ) ;
176
- return ErrorHandled :: Reported ( err. emit ( ) ) ;
171
+ self . decorate ( & mut err, decorate ) ;
172
+ ErrorHandled :: Reported ( err. emit ( ) )
177
173
}
178
- _ => { }
179
- } ;
180
-
181
- let err_msg = self . error . to_string ( ) ;
182
-
183
- // Report as hard error.
184
- let mut err = struct_error ( tcx, message) ;
185
- finish ( & mut err, Some ( err_msg) ) ;
186
- ErrorHandled :: Reported ( err. emit ( ) )
174
+ _ => {
175
+ // Report as hard error.
176
+ let mut err = struct_error ( tcx, message) ;
177
+ err. span_label ( self . span , self . error . to_string ( ) ) ;
178
+ self . decorate ( & mut err, decorate) ;
179
+ ErrorHandled :: Reported ( err. emit ( ) )
180
+ }
181
+ }
187
182
}
188
183
}
0 commit comments