@@ -126,9 +126,15 @@ impl<'tcx> ConstEvalErr<'tcx> {
126126 }
127127 }
128128
129- /// Sets the message passed in via `message` and adds span labels before handing control back
130- /// to `emit` to do any final processing. It's the caller's responsibility to call emit(),
131- /// stash(), etc. within the `emit` function to dispose of the diagnostic properly.
129+ /// Create a diagnostic for this const eval error.
130+ ///
131+ /// Sets the message passed in via `message` and adds span labels with detailed error
132+ /// information before handing control back to `emit` to do any final processing.
133+ /// It's the caller's responsibility to call emit(), stash(), etc. within the `emit`
134+ /// function to dispose of the diagnostic properly.
135+ ///
136+ /// If `lint_root.is_some()` report it as a lint, else report it as a hard error.
137+ /// (Except that for some errors, we ignore all that -- see `must_error` below.)
132138 fn struct_generic (
133139 & self ,
134140 tcx : TyCtxtAt < ' tcx > ,
@@ -141,6 +147,7 @@ impl<'tcx> ConstEvalErr<'tcx> {
141147 return Err ( ErrorHandled :: TooGeneric ) ;
142148 }
143149 err_inval ! ( TypeckError ) => return Err ( ErrorHandled :: Reported ) ,
150+ // We must *always* hard error on these, even if the caller wants just a lint.
144151 err_inval ! ( Layout ( LayoutError :: SizeOverflow ( _) ) ) => true ,
145152 _ => false ,
146153 } ;
@@ -155,10 +162,11 @@ impl<'tcx> ConstEvalErr<'tcx> {
155162 err => err. to_string ( ) ,
156163 } ;
157164
158- let add_span_labels = |err : & mut DiagnosticBuilder < ' _ > | {
159- if !must_error {
160- err. span_label ( self . span , err_msg . clone ( ) ) ;
165+ let finish = |mut err : DiagnosticBuilder < ' _ > , span_msg : Option < String > | {
166+ if let Some ( span_msg ) = span_msg {
167+ err. span_label ( self . span , span_msg ) ;
161168 }
169+ // Add spans for the stacktrace.
162170 // Skip the last, which is just the environment of the constant. The stacktrace
163171 // is sometimes empty because we create "fake" eval contexts in CTFE to do work
164172 // on constant values.
@@ -167,35 +175,36 @@ impl<'tcx> ConstEvalErr<'tcx> {
167175 err. span_label ( frame_info. call_site , frame_info. to_string ( ) ) ;
168176 }
169177 }
178+ // Let the caller finish the job.
179+ emit ( err)
170180 } ;
171181
172- if let ( Some ( lint_root) , false ) = ( lint_root, must_error) {
173- let hir_id = self
174- . stacktrace
175- . iter ( )
176- . rev ( )
177- . filter_map ( |frame| frame. lint_root )
178- . next ( )
179- . unwrap_or ( lint_root) ;
180- tcx. struct_span_lint_hir (
181- rustc_session:: lint:: builtin:: CONST_ERR ,
182- hir_id,
183- tcx. span ,
184- |lint| {
185- let mut err = lint. build ( message) ;
186- add_span_labels ( & mut err) ;
187- emit ( err) ;
188- } ,
189- ) ;
182+ if must_error {
183+ // The `message` makes little sense here, this is a more serious error than the
184+ // caller thinks anyway.
185+ finish ( struct_error ( tcx, & err_msg) , None ) ;
190186 } else {
191- let mut err = if must_error {
192- struct_error ( tcx, & err_msg)
187+ // Regular case.
188+ if let Some ( lint_root) = lint_root {
189+ // Report as lint.
190+ let hir_id = self
191+ . stacktrace
192+ . iter ( )
193+ . rev ( )
194+ . filter_map ( |frame| frame. lint_root )
195+ . next ( )
196+ . unwrap_or ( lint_root) ;
197+ tcx. struct_span_lint_hir (
198+ rustc_session:: lint:: builtin:: CONST_ERR ,
199+ hir_id,
200+ tcx. span ,
201+ |lint| finish ( lint. build ( message) , Some ( err_msg) ) ,
202+ ) ;
193203 } else {
194- struct_error ( tcx, message)
195- } ;
196- add_span_labels ( & mut err) ;
197- emit ( err) ;
198- } ;
204+ // Report as hard error.
205+ finish ( struct_error ( tcx, message) , Some ( err_msg) ) ;
206+ }
207+ }
199208 Ok ( ( ) )
200209 }
201210}
0 commit comments