fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>>(
    ecx: &'rt mut InterpCx<'mir, 'tcx, M>,
    leftover_allocations: &'rt mut FxHashSet<AllocId>,
    mode: InternMode,
    alloc_id: AllocId,
    mutability: Mutability,
    ty: Option<Ty<'tcx>>,
) -> InterpResult<'tcx, Option<IsStaticOrFn>> {
    trace!("InternVisitor::intern {:?} with {:?}", alloc_id, mutability,);
    // remove allocation
    let tcx = ecx.tcx;
    let (kind, mut alloc) = match ecx.memory.alloc_map.remove(&alloc_id) {
        Some(entry) => entry,
        None => {
            // Pointer not found in local memory map. It is either a pointer to the global
            // map, or dangling.
            // If the pointer is dangling (neither in local nor global memory), we leave it
            // to validation to error. The `delay_span_bug` ensures that we don't forget such
            // a check in validation.
            if tcx.alloc_map.lock().get(alloc_id).is_none() {
                tcx.sess.delay_span_bug(ecx.tcx.span, "tried to intern dangling pointer");
            }
            // treat dangling pointers like other statics
            // just to stop trying to recurse into them
            return Ok(Some(IsStaticOrFn));
        },
    };
    // This match is just a canary for future changes to `MemoryKind`, which most likely need
    // changes in this function.
    match kind {
        MemoryKind::Stack | MemoryKind::Vtable | MemoryKind::CallerLocation => {},
    }
    // Set allocation mutability as appropriate. This is used by LLVM to put things into
    // read-only memory, and also by Miri when evluating other constants/statics that
    // access this one.
    if mode == InternMode::Static {
        // When `ty` is `None`, we assume no interior mutability.
        let frozen = ty.map_or(true, |ty| ty.is_freeze(
            ecx.tcx.tcx,
            ecx.param_env,
            ecx.tcx.span,
        ));
        // For statics, allocation mutability is the combination of the place mutability and
        // the type mutability.
        // The entire allocation needs to be mutable if it contains an `UnsafeCell` anywhere.
        if mutability == Mutability::Not && frozen {
            alloc.mutability = Mutability::Not;
        } else {
            // Just making sure we are not "upgrading" an immutable allocation to mutable.
            assert_eq!(alloc.mutability, Mutability::Mut);
        }
    } else {
        // We *could* be non-frozen at `ConstBase`, for constants like `Cell::new(0)`.
        // But we still intern that as immutable as the memory cannot be changed once the
        // initial value was computed.
        // Constants are never mutable.
        assert_eq!(
            mutability, Mutability::Not,
            "Something went very wrong: mutability requested for a constant"
        );
        alloc.mutability = Mutability::Not;
    };
    // link the alloc id to the actual allocation
    let alloc = tcx.intern_const_alloc(alloc);
    leftover_allocations.extend(alloc.relocations().iter().map(|&(_, ((), reloc))| reloc));
    tcx.alloc_map.lock().set_alloc_id_memory(alloc_id, alloc);
    Ok(None)
}
/// Intern an allocation without looking at its children.
/// `mode` is the mode of the environment where we found this pointer.
/// `mutablity` is the mutability of the place to be interned; even if that says
/// `immutable` things might become mutable if `ty` is not frozen.
/// `ty` can be `None` if there is no potential interior mutability
/// to account for (e.g. for vtables).
Intern an allocation without looking at its children.
`mode` is the mode of the environment where we found this pointer.
Intern an allocation without looking at its children . ` mode ` is the mode of the environment where we found this pointer .
fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>>(
    ecx: &'rt mut InterpCx<'mir, 'tcx, M>,
    leftover_allocations: &'rt mut FxHashSet<AllocId>,
    mode: InternMode,
    alloc_id: AllocId,
    mutability: Mutability,
    ty: Option<Ty<'tcx>>,
) -> InterpResult<'tcx, Option<IsStaticOrFn>> {
    trace!("InternVisitor::intern {:?} with {:?}", alloc_id, mutability,);
    // remove allocation
    let tcx = ecx.tcx;
    let (kind, mut alloc) = match ecx.memory.alloc_map.remove(&alloc_id) {
        Some(entry) => entry,
        None => {
            // Pointer not found in local memory map. It is either a pointer to the global
            // map, or dangling.
            // If the pointer is dangling (neither in local nor global memory), we leave it
            // to validation to error. The `delay_span_bug` ensures that we don't forget such
            // a check in validation.
            if tcx.alloc_map.lock().get(alloc_id).is_none() {
                tcx.sess.delay_span_bug(ecx.tcx.span, "tried to intern dangling pointer");
            }
            // treat dangling pointers like other statics
            // just to stop trying to recurse into them
            return Ok(Some(IsStaticOrFn));
        },
    };
    // This match is just a canary for future changes to `MemoryKind`, which most likely need
    // changes in this function.
    match kind {
        MemoryKind::Stack | MemoryKind::Vtable | MemoryKind::CallerLocation => {},
    }
    // Set allocation mutability as appropriate. This is used by LLVM to put things into
    // read-only memory, and also by Miri when evluating other constants/statics that
    // access this one.
    if mode == InternMode::Static {
        // When `ty` is `None`, we assume no interior mutability.
        let frozen = ty.map_or(true, |ty| ty.is_freeze(
            ecx.tcx.tcx,
            ecx.param_env,
            ecx.tcx.span,
        ));
        // For statics, allocation mutability is the combination of the place mutability and
        // the type mutability.
        // The entire allocation needs to be mutable if it contains an `UnsafeCell` anywhere.
        if mutability == Mutability::Not && frozen {
            alloc.mutability = Mutability::Not;
        } else {
            // Just making sure we are not "upgrading" an immutable allocation to mutable.
            assert_eq!(alloc.mutability, Mutability::Mut);
        }
    } else {
        // We *could* be non-frozen at `ConstBase`, for constants like `Cell::new(0)`.
        // But we still intern that as immutable as the memory cannot be changed once the
        // initial value was computed.
        // Constants are never mutable.
        assert_eq!(
            mutability, Mutability::Not,
            "Something went very wrong: mutability requested for a constant"
        );
        alloc.mutability = Mutability::Not;
    };
    // link the alloc id to the actual allocation
    let alloc = tcx.intern_const_alloc(alloc);
    leftover_allocations.extend(alloc.relocations().iter().map(|&(_, ((), reloc))| reloc));
    tcx.alloc_map.lock().set_alloc_id_memory(alloc_id, alloc);
    Ok(None)
}
fn intern_shallow < ' rt , ' mir , ' tcx , M : CompileTimeMachine < ' mir , ' tcx > > ( ecx : & ' rt mut InterpCx < ' mir , ' tcx , M > , leftover_allocations : & ' rt mut FxHashSet < AllocId > , mode : InternMode , alloc_id : AllocId , mutability : Mutability , ty : Option < Ty < ' tcx > > , ) -> InterpResult < ' tcx , Option < IsStaticOrFn > > { trace ! ( " " alloc_id mutability ) ; // remove allocation let tcx = ecx . tcx ; let ( kind , mut alloc ) = match ecx . memory . alloc_map . remove ( & alloc_id ) { Some ( entry ) => entry , None => { // Pointer not found in local memory map. It is either a pointer to the global // map, or dangling. // If the pointer is dangling (neither in local nor global memory), we leave it // to validation to error. The `delay_span_bug` ensures that we don't forget such // a check in validation. if tcx . alloc_map . lock ( ) . get ( alloc_id ) . is_none ( ) { tcx . sess . delay_span_bug ( ecx . tcx . span , " " ) ; } // treat dangling pointers like other statics // just to stop trying to recurse into them return Ok ( Some ( IsStaticOrFn ) ) ; } , } ; // This match is just a canary for future changes to `MemoryKind`, which most likely need // changes in this function. match kind { MemoryKind :: Stack | MemoryKind :: Vtable | MemoryKind :: CallerLocation => { } , } // Set allocation mutability as appropriate. This is used by LLVM to put things into // read-only memory, and also by Miri when evluating other constants/statics that // access this one. if mode == InternMode :: Static { // When `ty` is `None`, we assume no interior mutability. let frozen = ty . map_or ( true , | ty | ty . is_freeze ( ecx . tcx . tcx , ecx . param_env , ecx . tcx . span , ) ) ; // For statics, allocation mutability is the combination of the place mutability and // the type mutability. // The entire allocation needs to be mutable if it contains an `UnsafeCell` anywhere. if mutability == Mutability :: Not && frozen { alloc . mutability = Mutability :: Not ; } else { // Just making sure we are not "upgrading" an immutable allocation to mutable. assert_eq ! ( alloc mutability Mutability Mut ) ; } } else { // We *could* be non-frozen at `ConstBase`, for constants like `Cell::new(0)`. // But we still intern that as immutable as the memory cannot be changed once the // initial value was computed. // Constants are never mutable. assert_eq ! ( mutability Mutability Not " " ) ; alloc . mutability = Mutability :: Not ; } ; // link the alloc id to the actual allocation let alloc = tcx . intern_const_alloc ( alloc ) ; leftover_allocations . extend ( alloc . relocations ( ) . iter ( ) . map ( | & ( _ , ( ( ) , reloc ) ) | reloc ) ) ; tcx . alloc_map . lock ( ) . set_alloc_id_memory ( alloc_id , alloc ) ; Ok ( None ) }
Intern an allocation without looking at its children.
Intern an allocation without looking at its children .
ecx
&'rt mut InterpCx<'mir, 'tcx, M>
leftover_allocations
&'rt mut FxHashSet<AllocId>
mode
InternMode
alloc_id
AllocId
mutability
Mutability
ty
Option<Ty<'tcx>>