55
66use super :: validity:: RefTracking ;
77use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
8- use rustc_errors:: ErrorReported ;
98use rustc_hir as hir;
10- use rustc_middle:: mir:: interpret:: { ErrorHandled , InterpResult } ;
9+ use rustc_middle:: mir:: interpret:: InterpResult ;
1110use rustc_middle:: ty:: { self , query:: TyCtxtAt , Ty } ;
1211
1312use rustc_ast:: ast:: Mutability ;
@@ -64,6 +63,7 @@ enum InternMode {
6463struct IsStaticOrFn ;
6564
6665fn mutable_memory_in_const ( tcx : TyCtxtAt < ' _ > , kind : & str ) {
66+ // FIXME: show this in validation instead so we can point at where in the value the error is?
6767 tcx. sess . span_err ( tcx. span , & format ! ( "mutable memory ({}) is not allowed in constant" , kind) ) ;
6868}
6969
@@ -79,7 +79,7 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>>(
7979 alloc_id : AllocId ,
8080 mode : InternMode ,
8181 ty : Option < Ty < ' tcx > > ,
82- ) -> InterpResult < ' tcx , Option < IsStaticOrFn > > {
82+ ) -> Option < IsStaticOrFn > {
8383 trace ! ( "intern_shallow {:?} with {:?}" , alloc_id, mode) ;
8484 // remove allocation
8585 let tcx = ecx. tcx ;
@@ -97,7 +97,7 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>>(
9797 }
9898 // treat dangling pointers like other statics
9999 // just to stop trying to recurse into them
100- return Ok ( Some ( IsStaticOrFn ) ) ;
100+ return Some ( IsStaticOrFn ) ;
101101 }
102102 } ;
103103 // This match is just a canary for future changes to `MemoryKind`, which most likely need
@@ -136,7 +136,7 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>>(
136136 let alloc = tcx. intern_const_alloc ( alloc) ;
137137 leftover_allocations. extend ( alloc. relocations ( ) . iter ( ) . map ( |& ( _, ( ( ) , reloc) ) | reloc) ) ;
138138 tcx. set_alloc_id_memory ( alloc_id, alloc) ;
139- Ok ( None )
139+ None
140140}
141141
142142impl < ' rt , ' mir , ' tcx , M : CompileTimeMachine < ' mir , ' tcx > > InternVisitor < ' rt , ' mir , ' tcx , M > {
@@ -145,7 +145,7 @@ impl<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>> InternVisitor<'rt, 'mir
145145 alloc_id : AllocId ,
146146 mode : InternMode ,
147147 ty : Option < Ty < ' tcx > > ,
148- ) -> InterpResult < ' tcx , Option < IsStaticOrFn > > {
148+ ) -> Option < IsStaticOrFn > {
149149 intern_shallow (
150150 self . ecx ,
151151 self . leftover_allocations ,
@@ -213,7 +213,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx>> ValueVisitor<'mir
213213 if let Scalar :: Ptr ( vtable) = mplace. meta . unwrap_meta ( ) {
214214 // Explicitly choose const mode here, since vtables are immutable, even
215215 // if the reference of the fat pointer is mutable.
216- self . intern_shallow ( vtable. alloc_id , InternMode :: ConstInner , None ) ? ;
216+ self . intern_shallow ( vtable. alloc_id , InternMode :: ConstInner , None ) ;
217217 } else {
218218 // Let validation show the error message, but make sure it *does* error.
219219 tcx. sess . delay_span_bug (
@@ -277,7 +277,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx>> ValueVisitor<'mir
277277 InternMode :: ConstInner
278278 }
279279 } ;
280- match self . intern_shallow ( ptr. alloc_id , ref_mode, Some ( referenced_ty) ) ? {
280+ match self . intern_shallow ( ptr. alloc_id , ref_mode, Some ( referenced_ty) ) {
281281 // No need to recurse, these are interned already and statics may have
282282 // cycles, so we don't want to recurse there
283283 Some ( IsStaticOrFn ) => { }
@@ -304,12 +304,18 @@ pub enum InternKind {
304304 ConstProp ,
305305}
306306
307+ /// Intern `ret` and everything it references.
308+ ///
309+ /// This *cannot raise an interpreter error*. Doing so is left to validation, which
310+ /// trakcs where in the value we are and thus can show much better error messages.
311+ /// Any errors here would anyway be turned into `const_err` lints, whereas validation failures
312+ /// are hard errors.
307313pub fn intern_const_alloc_recursive < M : CompileTimeMachine < ' mir , ' tcx > > (
308314 ecx : & mut InterpCx < ' mir , ' tcx , M > ,
309315 intern_kind : InternKind ,
310316 ret : MPlaceTy < ' tcx > ,
311317 ignore_interior_mut_in_const : bool ,
312- ) -> InterpResult < ' tcx >
318+ )
313319where
314320 ' tcx : ' mir ,
315321{
@@ -338,7 +344,7 @@ where
338344 ret. ptr . assert_ptr ( ) . alloc_id ,
339345 base_intern_mode,
340346 Some ( ret. layout . ty ) ,
341- ) ? ;
347+ ) ;
342348
343349 ref_tracking. track ( ( ret, base_intern_mode) , || ( ) ) ;
344350
@@ -422,13 +428,16 @@ where
422428 }
423429 }
424430 } else if ecx. memory . dead_alloc_map . contains_key ( & alloc_id) {
425- // dangling pointer
426- throw_ub_format ! ( "encountered dangling pointer in final constant" )
431+ // Codegen does not like dangling pointers, and generally `tcx` assumes that
432+ // all allocations referenced anywhere actually exist. So, make sure we error here.
433+ ecx. tcx . sess . span_err (
434+ ecx. tcx . span ,
435+ "encountered dangling pointer in final constant" ,
436+ ) ;
427437 } else if ecx. tcx . get_global_alloc ( alloc_id) . is_none ( ) {
428- // We have hit an `AllocId` that is neither in local or global memory and isn't marked
429- // as dangling by local memory.
438+ // We have hit an `AllocId` that is neither in local or global memory and isn't
439+ // marked as dangling by local memory. That should be impossible .
430440 span_bug ! ( ecx. tcx. span, "encountered unknown alloc id {:?}" , alloc_id) ;
431441 }
432442 }
433- Ok ( ( ) )
434443}
0 commit comments