Skip to content

Commit abb7aea

Browse files
committed
Auto merge of #115568 - matthiaskrgr:rollup-2igo8rl, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #113510 (Document soundness of Integer -> Pointer -> Integer conversions in `const` contexts.) - #114412 (document our assumptions about symbols provided by the libc) - #114813 (explain why we can mutate the FPU control word) - #115523 (improve `AttrTokenStream`) - #115536 (interpret: make MemPlace, Place, Operand types private to the interpreter) - #115540 (Support debuginfo for custom MIR.) - #115563 (llvm-wrapper: adapt for LLVM API change) r? `@ghost` `@rustbot` modify labels: rollup
2 parents c601579 + 82dad1a commit abb7aea

File tree

23 files changed

+86
-92
lines changed

23 files changed

+86
-92
lines changed

src/borrow_tracker/stacked_borrows/mod.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
615615
) -> InterpResult<'tcx, Option<Provenance>> {
616616
let this = self.eval_context_mut();
617617
// Ensure we bail out if the pointer goes out-of-bounds (see miri#1050).
618-
this.check_ptr_access_align(place.ptr, size, Align::ONE, CheckInAllocMsg::InboundsTest)?;
618+
this.check_ptr_access_align(place.ptr(), size, Align::ONE, CheckInAllocMsg::InboundsTest)?;
619619

620620
// It is crucial that this gets called on all code paths, to ensure we track tag creation.
621621
let log_creation = |this: &MiriInterpCx<'mir, 'tcx>,
@@ -682,7 +682,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
682682
trace!(
683683
"reborrow of size 0: reference {:?} derived from {:?} (pointee {})",
684684
new_tag,
685-
place.ptr,
685+
place.ptr(),
686686
place.layout.ty,
687687
);
688688
// Don't update any stacks for a zero-sized access; borrow stacks are per-byte and this
@@ -692,19 +692,19 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
692692
// attempt to use it for a non-zero-sized access.
693693
// Dangling slices are a common case here; it's valid to get their length but with raw
694694
// pointer tagging for example all calls to get_unchecked on them are invalid.
695-
if let Ok((alloc_id, base_offset, orig_tag)) = this.ptr_try_get_alloc_id(place.ptr) {
695+
if let Ok((alloc_id, base_offset, orig_tag)) = this.ptr_try_get_alloc_id(place.ptr()) {
696696
log_creation(this, Some((alloc_id, base_offset, orig_tag)))?;
697697
// Still give it the new provenance, it got retagged after all.
698698
return Ok(Some(Provenance::Concrete { alloc_id, tag: new_tag }));
699699
} else {
700700
// This pointer doesn't come with an AllocId. :shrug:
701701
log_creation(this, None)?;
702702
// Provenance unchanged.
703-
return Ok(place.ptr.provenance);
703+
return Ok(place.ptr().provenance);
704704
}
705705
}
706706

707-
let (alloc_id, base_offset, orig_tag) = this.ptr_get_alloc_id(place.ptr)?;
707+
let (alloc_id, base_offset, orig_tag) = this.ptr_get_alloc_id(place.ptr())?;
708708
log_creation(this, Some((alloc_id, base_offset, orig_tag)))?;
709709

710710
trace!(

src/borrow_tracker/tree_borrows/mod.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
172172
let this = self.eval_context_mut();
173173
// Ensure we bail out if the pointer goes out-of-bounds (see miri#1050).
174174
this.check_ptr_access_align(
175-
place.ptr,
175+
place.ptr(),
176176
ptr_size,
177177
Align::ONE,
178178
CheckInAllocMsg::InboundsTest,
@@ -197,7 +197,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
197197
};
198198

199199
trace!("Reborrow of size {:?}", ptr_size);
200-
let (alloc_id, base_offset, parent_prov) = match this.ptr_try_get_alloc_id(place.ptr) {
200+
let (alloc_id, base_offset, parent_prov) = match this.ptr_try_get_alloc_id(place.ptr()) {
201201
Ok(data) => {
202202
// Unlike SB, we *do* a proper retag for size 0 if can identify the allocation.
203203
// After all, the pointer may be lazily initialized outside this initial range.
@@ -210,18 +210,18 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
210210
trace!(
211211
"reborrow of size 0: reference {:?} derived from {:?} (pointee {})",
212212
new_tag,
213-
place.ptr,
213+
place.ptr(),
214214
place.layout.ty,
215215
);
216216
log_creation(this, None)?;
217217
// Keep original provenance.
218-
return Ok(place.ptr.provenance);
218+
return Ok(place.ptr().provenance);
219219
}
220220
};
221221
log_creation(this, Some((alloc_id, base_offset, parent_prov)))?;
222222

223223
let orig_tag = match parent_prov {
224-
ProvenanceExtra::Wildcard => return Ok(place.ptr.provenance), // TODO: handle wildcard pointers
224+
ProvenanceExtra::Wildcard => return Ok(place.ptr().provenance), // TODO: handle wildcard pointers
225225
ProvenanceExtra::Concrete(tag) => tag,
226226
};
227227

src/concurrency/data_race.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1018,7 +1018,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
10181018
// be 8-aligned).
10191019
let align = Align::from_bytes(place.layout.size.bytes()).unwrap();
10201020
this.check_ptr_access_align(
1021-
place.ptr,
1021+
place.ptr(),
10221022
place.layout.size,
10231023
align,
10241024
CheckInAllocMsg::MemoryAccessTest,
@@ -1031,7 +1031,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
10311031
// We avoid `get_ptr_alloc` since we do *not* want to run the access hooks -- the actual
10321032
// access will happen later.
10331033
let (alloc_id, _offset, _prov) =
1034-
this.ptr_try_get_alloc_id(place.ptr).expect("there are no zero-sized atomic accesses");
1034+
this.ptr_try_get_alloc_id(place.ptr()).expect("there are no zero-sized atomic accesses");
10351035
if this.get_alloc_mutability(alloc_id)? == Mutability::Not {
10361036
// FIXME: make this prettier, once these messages have separate title/span/help messages.
10371037
throw_ub_format!(
@@ -1135,15 +1135,15 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
11351135
if let Some(data_race) = &this.machine.data_race {
11361136
if data_race.race_detecting() {
11371137
let size = place.layout.size;
1138-
let (alloc_id, base_offset, _prov) = this.ptr_get_alloc_id(place.ptr)?;
1138+
let (alloc_id, base_offset, _prov) = this.ptr_get_alloc_id(place.ptr())?;
11391139
// Load and log the atomic operation.
11401140
// Note that atomic loads are possible even from read-only allocations, so `get_alloc_extra_mut` is not an option.
11411141
let alloc_meta = this.get_alloc_extra(alloc_id)?.data_race.as_ref().unwrap();
11421142
log::trace!(
11431143
"Atomic op({}) with ordering {:?} on {:?} (size={})",
11441144
description,
11451145
&atomic,
1146-
place.ptr,
1146+
place.ptr(),
11471147
size.bytes()
11481148
);
11491149

@@ -1186,7 +1186,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
11861186
{
11871187
log::trace!(
11881188
"Updated atomic memory({:?}, size={}) to {:#?}",
1189-
place.ptr,
1189+
place.ptr(),
11901190
size.bytes(),
11911191
mem_clocks.atomic_ops
11921192
);

src/concurrency/thread.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use std::task::Poll;
88
use std::time::{Duration, SystemTime};
99

1010
use log::trace;
11+
use either::Either;
1112

1213
use rustc_data_structures::fx::FxHashMap;
1314
use rustc_hir::def_id::DefId;
@@ -259,8 +260,15 @@ impl VisitTags for Frame<'_, '_, Provenance, FrameExtra<'_>> {
259260
return_place.visit_tags(visit);
260261
// Locals.
261262
for local in locals.iter() {
262-
if let LocalValue::Live(value) = &local.value {
263-
value.visit_tags(visit);
263+
match local.as_mplace_or_imm() {
264+
None => {}
265+
Some(Either::Left((ptr, meta))) => {
266+
ptr.visit_tags(visit);
267+
meta.visit_tags(visit);
268+
}
269+
Some(Either::Right(imm)) => {
270+
imm.visit_tags(visit);
271+
}
264272
}
265273
}
266274

src/concurrency/weak_memory.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
481481
place: &MPlaceTy<'tcx, Provenance>,
482482
) -> InterpResult<'tcx> {
483483
let this = self.eval_context_ref();
484-
let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(place.ptr)?;
484+
let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(place.ptr())?;
485485
if let crate::AllocExtra {
486486
weak_memory: Some(alloc_buffers),
487487
data_race: Some(alloc_clocks),
@@ -512,7 +512,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
512512
init: Scalar<Provenance>,
513513
) -> InterpResult<'tcx> {
514514
let this = self.eval_context_mut();
515-
let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(place.ptr)?;
515+
let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(place.ptr())?;
516516
if let (
517517
crate::AllocExtra { weak_memory: Some(alloc_buffers), .. },
518518
crate::MiriMachine { data_race: Some(global), threads, .. },
@@ -539,7 +539,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
539539
) -> InterpResult<'tcx, Scalar<Provenance>> {
540540
let this = self.eval_context_ref();
541541
if let Some(global) = &this.machine.data_race {
542-
let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(place.ptr)?;
542+
let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(place.ptr())?;
543543
if let Some(alloc_buffers) = this.get_alloc_extra(alloc_id)?.weak_memory.as_ref() {
544544
if atomic == AtomicReadOrd::SeqCst {
545545
global.sc_read(&this.machine.threads);
@@ -577,7 +577,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
577577
init: Scalar<Provenance>,
578578
) -> InterpResult<'tcx> {
579579
let this = self.eval_context_mut();
580-
let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(dest.ptr)?;
580+
let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(dest.ptr())?;
581581
if let (
582582
crate::AllocExtra { weak_memory: Some(alloc_buffers), .. },
583583
crate::MiriMachine { data_race: Some(global), threads, .. },
@@ -627,7 +627,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
627627
global.sc_read(&this.machine.threads);
628628
}
629629
let size = place.layout.size;
630-
let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(place.ptr)?;
630+
let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(place.ptr())?;
631631
if let Some(alloc_buffers) = this.get_alloc_extra(alloc_id)?.weak_memory.as_ref() {
632632
let buffer = alloc_buffers
633633
.get_or_create_store_buffer(alloc_range(base_offset, size), init)?;

src/diagnostics.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -376,9 +376,9 @@ pub fn report_error<'tcx, 'mir>(
376376
for (i, frame) in ecx.active_thread_stack().iter().enumerate() {
377377
trace!("-------------------");
378378
trace!("Frame {}", i);
379-
trace!(" return: {:?}", *frame.return_place);
379+
trace!(" return: {:?}", frame.return_place);
380380
for (i, local) in frame.locals.iter().enumerate() {
381-
trace!(" local {}: {:?}", i, local.value);
381+
trace!(" local {}: {:?}", i, local);
382382
}
383383
}
384384

src/eval.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -242,10 +242,7 @@ impl MainThreadState {
242242
},
243243
Done => {
244244
// Figure out exit code.
245-
let ret_place = MPlaceTy::from_aligned_ptr(
246-
this.machine.main_fn_ret_place.unwrap().ptr,
247-
this.machine.layouts.isize,
248-
);
245+
let ret_place = this.machine.main_fn_ret_place.clone().unwrap();
249246
let exit_code = this.read_target_isize(&ret_place)?;
250247
// Need to call this ourselves since we are not going to return to the scheduler
251248
// loop, and we want the main thread TLS to not show up as memory leaks.
@@ -308,7 +305,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
308305
let arg_type = Ty::new_array(tcx, tcx.types.u8, size);
309306
let arg_place =
310307
ecx.allocate(ecx.layout_of(arg_type)?, MiriMemoryKind::Machine.into())?;
311-
ecx.write_os_str_to_c_str(OsStr::new(arg), arg_place.ptr, size)?;
308+
ecx.write_os_str_to_c_str(OsStr::new(arg), arg_place.ptr(), size)?;
312309
ecx.mark_immutable(&arg_place);
313310
argvs.push(arg_place.to_ref(&ecx));
314311
}
@@ -332,15 +329,15 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
332329
ecx.allocate(ecx.machine.layouts.isize, MiriMemoryKind::Machine.into())?;
333330
ecx.write_scalar(argc, &argc_place)?;
334331
ecx.mark_immutable(&argc_place);
335-
ecx.machine.argc = Some(*argc_place);
332+
ecx.machine.argc = Some(argc_place.ptr());
336333

337334
let argv_place = ecx.allocate(
338335
ecx.layout_of(Ty::new_imm_ptr(tcx, tcx.types.unit))?,
339336
MiriMemoryKind::Machine.into(),
340337
)?;
341338
ecx.write_immediate(argv, &argv_place)?;
342339
ecx.mark_immutable(&argv_place);
343-
ecx.machine.argv = Some(*argv_place);
340+
ecx.machine.argv = Some(argv_place.ptr());
344341
}
345342
// Store command line as UTF-16 for Windows `GetCommandLineW`.
346343
{
@@ -351,7 +348,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
351348
Ty::new_array(tcx, tcx.types.u16, u64::try_from(cmd_utf16.len()).unwrap());
352349
let cmd_place =
353350
ecx.allocate(ecx.layout_of(cmd_type)?, MiriMemoryKind::Machine.into())?;
354-
ecx.machine.cmd_line = Some(*cmd_place);
351+
ecx.machine.cmd_line = Some(cmd_place.ptr());
355352
// Store the UTF-16 string. We just allocated so we know the bounds are fine.
356353
for (idx, &c) in cmd_utf16.iter().enumerate() {
357354
let place = ecx.project_field(&cmd_place, idx)?;
@@ -364,7 +361,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
364361

365362
// Return place (in static memory so that it does not count as leak).
366363
let ret_place = ecx.allocate(ecx.machine.layouts.isize, MiriMemoryKind::Machine.into())?;
367-
ecx.machine.main_fn_ret_place = Some(*ret_place);
364+
ecx.machine.main_fn_ret_place = Some(ret_place.clone());
368365
// Call start function.
369366

370367
match entry_type {

src/helpers.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
381381
// Store how far we proceeded into the place so far. Everything to the left of
382382
// this offset has already been handled, in the sense that the frozen parts
383383
// have had `action` called on them.
384-
let start_addr = place.ptr.addr();
384+
let start_addr = place.ptr().addr();
385385
let mut cur_addr = start_addr;
386386
// Called when we detected an `UnsafeCell` at the given offset and size.
387387
// Calls `action` and advances `cur_ptr`.
@@ -413,7 +413,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
413413
let mut visitor = UnsafeCellVisitor {
414414
ecx: this,
415415
unsafe_cell_action: |place| {
416-
trace!("unsafe_cell_action on {:?}", place.ptr);
416+
trace!("unsafe_cell_action on {:?}", place.ptr());
417417
// We need a size to go on.
418418
let unsafe_cell_size = this
419419
.size_and_align_of_mplace(place)?
@@ -422,7 +422,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
422422
.unwrap_or_else(|| place.layout.size);
423423
// Now handle this `UnsafeCell`, unless it is empty.
424424
if unsafe_cell_size != Size::ZERO {
425-
unsafe_cell_action(&place.ptr, unsafe_cell_size)
425+
unsafe_cell_action(&place.ptr(), unsafe_cell_size)
426426
} else {
427427
Ok(())
428428
}
@@ -432,7 +432,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
432432
}
433433
// The part between the end_ptr and the end of the place is also frozen.
434434
// So pretend there is a 0-sized `UnsafeCell` at the end.
435-
unsafe_cell_action(&place.ptr.offset(size, this)?, Size::ZERO)?;
435+
unsafe_cell_action(&place.ptr().offset(size, this)?, Size::ZERO)?;
436436
// Done!
437437
return Ok(());
438438

@@ -994,10 +994,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
994994
}
995995

996996
/// Mark a machine allocation that was just created as immutable.
997-
fn mark_immutable(&mut self, mplace: &MemPlace<Provenance>) {
997+
fn mark_immutable(&mut self, mplace: &MPlaceTy<'tcx, Provenance>) {
998998
let this = self.eval_context_mut();
999999
// This got just allocated, so there definitely is a pointer here.
1000-
let provenance = mplace.ptr.into_pointer_or_addr().unwrap().provenance;
1000+
let provenance = mplace.ptr().into_pointer_or_addr().unwrap().provenance;
10011001
this.alloc_mark_immutable(provenance.get_alloc_id().unwrap()).unwrap();
10021002
}
10031003

src/machine.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -396,14 +396,14 @@ pub struct MiriMachine<'mir, 'tcx> {
396396
pub(crate) env_vars: EnvVars<'tcx>,
397397

398398
/// Return place of the main function.
399-
pub(crate) main_fn_ret_place: Option<MemPlace<Provenance>>,
399+
pub(crate) main_fn_ret_place: Option<MPlaceTy<'tcx, Provenance>>,
400400

401401
/// Program arguments (`Option` because we can only initialize them after creating the ecx).
402402
/// These are *pointers* to argc/argv because macOS.
403403
/// We also need the full command line as one string because of Windows.
404-
pub(crate) argc: Option<MemPlace<Provenance>>,
405-
pub(crate) argv: Option<MemPlace<Provenance>>,
406-
pub(crate) cmd_line: Option<MemPlace<Provenance>>,
404+
pub(crate) argc: Option<Pointer<Option<Provenance>>>,
405+
pub(crate) argv: Option<Pointer<Option<Provenance>>>,
406+
pub(crate) cmd_line: Option<Pointer<Option<Provenance>>>,
407407

408408
/// TLS state.
409409
pub(crate) tls: TlsData<'tcx>,
@@ -670,7 +670,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
670670
) -> InterpResult<'tcx> {
671671
let place = this.allocate(val.layout, MiriMemoryKind::ExternStatic.into())?;
672672
this.write_immediate(*val, &place)?;
673-
Self::add_extern_static(this, name, place.ptr);
673+
Self::add_extern_static(this, name, place.ptr());
674674
Ok(())
675675
}
676676

@@ -686,7 +686,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
686686
Self::add_extern_static(
687687
this,
688688
"environ",
689-
this.machine.env_vars.environ.as_ref().unwrap().ptr,
689+
this.machine.env_vars.environ.as_ref().unwrap().ptr(),
690690
);
691691
// A couple zero-initialized pointer-sized extern statics.
692692
// Most of them are for weak symbols, which we all set to null (indicating that the
@@ -703,7 +703,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
703703
Self::add_extern_static(
704704
this,
705705
"environ",
706-
this.machine.env_vars.environ.as_ref().unwrap().ptr,
706+
this.machine.env_vars.environ.as_ref().unwrap().ptr(),
707707
);
708708
}
709709
"android" => {
@@ -1415,7 +1415,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
14151415
local: mir::Local,
14161416
mplace: &MPlaceTy<'tcx, Provenance>,
14171417
) -> InterpResult<'tcx> {
1418-
let Some(Provenance::Concrete { alloc_id, .. }) = mplace.ptr.provenance else {
1418+
let Some(Provenance::Concrete { alloc_id, .. }) = mplace.ptr().provenance else {
14191419
panic!("after_local_allocated should only be called on fresh allocations");
14201420
};
14211421
let local_decl = &ecx.active_thread_stack()[frame].body.local_decls[local];

src/shims/backtrace.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
8989
}
9090

9191
this.write_immediate(
92-
Immediate::new_slice(Scalar::from_maybe_pointer(alloc.ptr, this), len, this),
92+
Immediate::new_slice(Scalar::from_maybe_pointer(alloc.ptr(), this), len, this),
9393
dest,
9494
)?;
9595
}

src/shims/env.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
459459
let place = this.project_field(&vars_place, idx)?;
460460
this.write_pointer(var, &place)?;
461461
}
462-
this.write_pointer(vars_place.ptr, &this.machine.env_vars.environ.clone().unwrap())?;
462+
this.write_pointer(vars_place.ptr(), &this.machine.env_vars.environ.clone().unwrap())?;
463463

464464
Ok(())
465465
}

0 commit comments

Comments
 (0)