11use super :: { AllocId , Pointer , RawConst , Scalar } ;
22
33use crate :: mir:: interpret:: ConstValue ;
4- use crate :: ty:: layout:: LayoutError ;
5- use crate :: ty:: query:: TyCtxtAt ;
6- use crate :: ty:: { self , layout, tls, FnSig , Ty } ;
4+ use crate :: ty:: { layout, query:: TyCtxtAt , tls, FnSig , Ty } ;
75
86use rustc_data_structures:: sync:: Lock ;
97use rustc_errors:: { pluralize, struct_span_err, DiagnosticBuilder , ErrorReported } ;
10- use rustc_hir as hir;
11- use rustc_hir:: definitions:: DefPathData ;
128use rustc_macros:: HashStable ;
139use rustc_session:: CtfeBacktrace ;
14- use rustc_span:: { def_id:: DefId , Pos , Span } ;
10+ use rustc_span:: def_id:: DefId ;
1511use rustc_target:: abi:: { Align , Size } ;
1612use std:: { any:: Any , backtrace:: Backtrace , fmt, mem} ;
1713
@@ -34,167 +30,6 @@ CloneTypeFoldableAndLiftImpls! {
3430pub type ConstEvalRawResult < ' tcx > = Result < RawConst < ' tcx > , ErrorHandled > ;
3531pub type ConstEvalResult < ' tcx > = Result < ConstValue < ' tcx > , ErrorHandled > ;
3632
37- #[ derive( Debug ) ]
38- pub struct ConstEvalErr < ' tcx > {
39- pub span : Span ,
40- pub error : crate :: mir:: interpret:: InterpError < ' tcx > ,
41- pub stacktrace : Vec < FrameInfo < ' tcx > > ,
42- }
43-
44- #[ derive( Debug ) ]
45- pub struct FrameInfo < ' tcx > {
46- pub instance : ty:: Instance < ' tcx > ,
47- pub span : Span ,
48- pub lint_root : Option < hir:: HirId > ,
49- }
50-
51- impl < ' tcx > fmt:: Display for FrameInfo < ' tcx > {
52- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
53- ty:: tls:: with ( |tcx| {
54- if tcx. def_key ( self . instance . def_id ( ) ) . disambiguated_data . data
55- == DefPathData :: ClosureExpr
56- {
57- write ! ( f, "inside closure" ) ?;
58- } else {
59- write ! ( f, "inside `{}`" , self . instance) ?;
60- }
61- if !self . span . is_dummy ( ) {
62- let lo = tcx. sess . source_map ( ) . lookup_char_pos ( self . span . lo ( ) ) ;
63- write ! ( f, " at {}:{}:{}" , lo. file. name, lo. line, lo. col. to_usize( ) + 1 ) ?;
64- }
65- Ok ( ( ) )
66- } )
67- }
68- }
69-
70- impl < ' tcx > ConstEvalErr < ' tcx > {
71- pub fn struct_error (
72- & self ,
73- tcx : TyCtxtAt < ' tcx > ,
74- message : & str ,
75- emit : impl FnOnce ( DiagnosticBuilder < ' _ > ) ,
76- ) -> ErrorHandled {
77- self . struct_generic ( tcx, message, emit, None )
78- }
79-
80- pub fn report_as_error ( & self , tcx : TyCtxtAt < ' tcx > , message : & str ) -> ErrorHandled {
81- self . struct_error ( tcx, message, |mut e| e. emit ( ) )
82- }
83-
84- pub fn report_as_lint (
85- & self ,
86- tcx : TyCtxtAt < ' tcx > ,
87- message : & str ,
88- lint_root : hir:: HirId ,
89- span : Option < Span > ,
90- ) -> ErrorHandled {
91- self . struct_generic (
92- tcx,
93- message,
94- |mut lint : DiagnosticBuilder < ' _ > | {
95- // Apply the span.
96- if let Some ( span) = span {
97- let primary_spans = lint. span . primary_spans ( ) . to_vec ( ) ;
98- // point at the actual error as the primary span
99- lint. replace_span_with ( span) ;
100- // point to the `const` statement as a secondary span
101- // they don't have any label
102- for sp in primary_spans {
103- if sp != span {
104- lint. span_label ( sp, "" ) ;
105- }
106- }
107- }
108- lint. emit ( ) ;
109- } ,
110- Some ( lint_root) ,
111- )
112- }
113-
114- /// Create a diagnostic for this const eval error.
115- ///
116- /// Sets the message passed in via `message` and adds span labels with detailed error
117- /// information before handing control back to `emit` to do any final processing.
118- /// It's the caller's responsibility to call emit(), stash(), etc. within the `emit`
119- /// function to dispose of the diagnostic properly.
120- ///
121- /// If `lint_root.is_some()` report it as a lint, else report it as a hard error.
122- /// (Except that for some errors, we ignore all that -- see `must_error` below.)
123- fn struct_generic (
124- & self ,
125- tcx : TyCtxtAt < ' tcx > ,
126- message : & str ,
127- emit : impl FnOnce ( DiagnosticBuilder < ' _ > ) ,
128- lint_root : Option < hir:: HirId > ,
129- ) -> ErrorHandled {
130- let must_error = match self . error {
131- err_inval ! ( Layout ( LayoutError :: Unknown ( _) ) ) | err_inval ! ( TooGeneric ) => {
132- return ErrorHandled :: TooGeneric ;
133- }
134- err_inval ! ( TypeckError ( error_reported) ) => {
135- return ErrorHandled :: Reported ( error_reported) ;
136- }
137- // We must *always* hard error on these, even if the caller wants just a lint.
138- err_inval ! ( Layout ( LayoutError :: SizeOverflow ( _) ) ) => true ,
139- _ => false ,
140- } ;
141- trace ! ( "reporting const eval failure at {:?}" , self . span) ;
142-
143- let err_msg = match & self . error {
144- InterpError :: MachineStop ( msg) => {
145- // A custom error (`ConstEvalErrKind` in `librustc_mir/interp/const_eval/error.rs`).
146- // Should be turned into a string by now.
147- msg. downcast_ref :: < String > ( ) . expect ( "invalid MachineStop payload" ) . clone ( )
148- }
149- err => err. to_string ( ) ,
150- } ;
151-
152- let finish = |mut err : DiagnosticBuilder < ' _ > , span_msg : Option < String > | {
153- if let Some ( span_msg) = span_msg {
154- err. span_label ( self . span , span_msg) ;
155- }
156- // Add spans for the stacktrace. Don't print a single-line backtrace though.
157- if self . stacktrace . len ( ) > 1 {
158- for frame_info in & self . stacktrace {
159- err. span_label ( frame_info. span , frame_info. to_string ( ) ) ;
160- }
161- }
162- // Let the caller finish the job.
163- emit ( err)
164- } ;
165-
166- if must_error {
167- // The `message` makes little sense here, this is a more serious error than the
168- // caller thinks anyway.
169- // See <https://github.com/rust-lang/rust/pull/63152>.
170- finish ( struct_error ( tcx, & err_msg) , None ) ;
171- ErrorHandled :: Reported ( ErrorReported )
172- } else {
173- // Regular case.
174- if let Some ( lint_root) = lint_root {
175- // Report as lint.
176- let hir_id = self
177- . stacktrace
178- . iter ( )
179- . rev ( )
180- . find_map ( |frame| frame. lint_root )
181- . unwrap_or ( lint_root) ;
182- tcx. struct_span_lint_hir (
183- rustc_session:: lint:: builtin:: CONST_ERR ,
184- hir_id,
185- tcx. span ,
186- |lint| finish ( lint. build ( message) , Some ( err_msg) ) ,
187- ) ;
188- ErrorHandled :: Linted
189- } else {
190- // Report as hard error.
191- finish ( struct_error ( tcx, message) , Some ( err_msg) ) ;
192- ErrorHandled :: Reported ( ErrorReported )
193- }
194- }
195- }
196- }
197-
19833pub fn struct_error < ' tcx > ( tcx : TyCtxtAt < ' tcx > , msg : & str ) -> DiagnosticBuilder < ' tcx > {
19934 struct_span_err ! ( tcx. sess, tcx. span, E0080 , "{}" , msg)
20035}
0 commit comments