diff --git a/compiler/rustc_smir/src/rustc_smir/alloc.rs b/compiler/rustc_smir/src/rustc_smir/alloc.rs new file mode 100644 index 0000000000000..33c75250adcd6 --- /dev/null +++ b/compiler/rustc_smir/src/rustc_smir/alloc.rs @@ -0,0 +1,124 @@ +use rustc_middle::mir::interpret::{alloc_range, AllocRange, ConstValue, Pointer}; + +use crate::{ + rustc_internal::opaque, + rustc_smir::{Stable, Tables}, + stable_mir::mir::Mutability, + stable_mir::ty::{Allocation, ProvenanceMap}, +}; + +/// Creates new empty `Allocation` from given `Align`. +fn new_empty_allocation(align: rustc_target::abi::Align) -> Allocation { + Allocation { + bytes: Vec::new(), + provenance: ProvenanceMap { ptrs: Vec::new() }, + align: align.bytes(), + mutability: Mutability::Not, + } +} + +// We need this method instead of a Stable implementation +// because we need to get `Ty` of the const we are trying to create, to do that +// we need to have access to `ConstantKind` but we can't access that inside Stable impl. +#[allow(rustc::usage_of_qualified_ty)] +pub fn new_allocation<'tcx>( + ty: rustc_middle::ty::Ty<'tcx>, + const_value: ConstValue<'tcx>, + tables: &mut Tables<'tcx>, +) -> Allocation { + match const_value { + ConstValue::Scalar(scalar) => { + let size = scalar.size(); + let align = tables + .tcx + .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(ty)) + .unwrap() + .align; + let mut allocation = rustc_middle::mir::interpret::Allocation::uninit(size, align.abi); + allocation + .write_scalar(&tables.tcx, alloc_range(rustc_target::abi::Size::ZERO, size), scalar) + .unwrap(); + allocation.stable(tables) + } + ConstValue::ZeroSized => { + let align = + tables.tcx.layout_of(rustc_middle::ty::ParamEnv::empty().and(ty)).unwrap().align; + new_empty_allocation(align.abi) + } + ConstValue::Slice { data, start, end } => { + let alloc_id = tables.tcx.create_memory_alloc(data); + let ptr = Pointer::new(alloc_id, rustc_target::abi::Size::from_bytes(start)); + let scalar_ptr = rustc_middle::mir::interpret::Scalar::from_pointer(ptr, &tables.tcx); + let scalar_len = rustc_middle::mir::interpret::Scalar::from_target_usize( + (end - start) as u64, + &tables.tcx, + ); + let layout = + tables.tcx.layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(ty)).unwrap(); + let mut allocation = + rustc_middle::mir::interpret::Allocation::uninit(layout.size, layout.align.abi); + allocation + .write_scalar( + &tables.tcx, + alloc_range(rustc_target::abi::Size::ZERO, tables.tcx.data_layout.pointer_size), + scalar_ptr, + ) + .unwrap(); + allocation + .write_scalar( + &tables.tcx, + alloc_range(tables.tcx.data_layout.pointer_size, scalar_len.size()), + scalar_len, + ) + .unwrap(); + allocation.stable(tables) + } + ConstValue::ByRef { alloc, offset } => { + let ty_size = tables + .tcx + .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(ty)) + .unwrap() + .size; + allocation_filter(&alloc.0, alloc_range(offset, ty_size), tables) + } + } +} + +/// Creates an `Allocation` only from information within the `AllocRange`. +pub(super) fn allocation_filter<'tcx>( + alloc: &rustc_middle::mir::interpret::Allocation, + alloc_range: AllocRange, + tables: &mut Tables<'tcx>, +) -> Allocation { + let mut bytes: Vec> = alloc + .inspect_with_uninit_and_ptr_outside_interpreter( + alloc_range.start.bytes_usize()..alloc_range.end().bytes_usize(), + ) + .iter() + .copied() + .map(Some) + .collect(); + for (i, b) in bytes.iter_mut().enumerate() { + if !alloc + .init_mask() + .get(rustc_target::abi::Size::from_bytes(i + alloc_range.start.bytes_usize())) + { + *b = None; + } + } + let mut ptrs = Vec::new(); + for (offset, prov) in alloc + .provenance() + .ptrs() + .iter() + .filter(|a| a.0 >= alloc_range.start && a.0 <= alloc_range.end()) + { + ptrs.push((offset.bytes_usize() - alloc_range.start.bytes_usize(), opaque(prov))); + } + Allocation { + bytes: bytes, + provenance: ProvenanceMap { ptrs }, + align: alloc.align.bytes(), + mutability: alloc.mutability.stable(tables), + } +} diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 7877c91c2cf1a..d36835d37f54b 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -9,10 +9,7 @@ use crate::rustc_internal::{self, opaque}; use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx}; -use crate::stable_mir::ty::{ - allocation_filter, new_allocation, Const, FloatTy, GenericParamDef, IntTy, Movability, RigidTy, - TyKind, UintTy, -}; +use crate::stable_mir::ty::{FloatTy, GenericParamDef, IntTy, Movability, RigidTy, TyKind, UintTy}; use crate::stable_mir::{self, Context}; use rustc_hir as hir; use rustc_middle::mir::interpret::alloc_range; @@ -22,6 +19,8 @@ use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc_target::abi::FieldIdx; use tracing::debug; +mod alloc; + impl<'tcx> Context for Tables<'tcx> { fn local_crate(&self) -> stable_mir::Crate { smir_crate(self.tcx, LOCAL_CRATE) @@ -205,8 +204,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> { match self { Use(op) => stable_mir::mir::Rvalue::Use(op.stable(tables)), Repeat(op, len) => { - let cnst = ConstantKind::from_const(*len, tables.tcx); - let len = Const { literal: cnst.stable(tables) }; + let len = len.stable(tables); stable_mir::mir::Rvalue::Repeat(op.stable(tables), len) } Ref(region, kind, place) => stable_mir::mir::Rvalue::Ref( @@ -394,8 +392,7 @@ impl<'tcx> Stable<'tcx> for ty::TermKind<'tcx> { match self { ty::TermKind::Ty(ty) => TermKind::Type(tables.intern_ty(*ty)), ty::TermKind::Const(cnst) => { - let cnst = ConstantKind::from_const(*cnst, tables.tcx); - let cnst = Const { literal: cnst.stable(tables) }; + let cnst = cnst.stable(tables); TermKind::Const(cnst) } } @@ -1083,8 +1080,32 @@ impl<'tcx> Stable<'tcx> for ty::Const<'tcx> { type T = stable_mir::ty::Const; fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - let cnst = ConstantKind::from_const(*self, tables.tcx); - stable_mir::ty::Const { literal: cnst.stable(tables) } + stable_mir::ty::Const { + literal: match self.kind() { + ty::Value(val) => { + let const_val = tables.tcx.valtree_to_const_val((self.ty(), val)); + stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation( + self.ty(), + const_val, + tables, + )) + } + ty::ParamCt(param) => stable_mir::ty::ConstantKind::ParamCt(opaque(¶m)), + ty::ErrorCt(_) => unreachable!(), + ty::InferCt(_) => unreachable!(), + ty::BoundCt(_, _) => unimplemented!(), + ty::PlaceholderCt(_) => unimplemented!(), + ty::Unevaluated(uv) => { + stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst { + ty: tables.intern_ty(self.ty()), + def: tables.const_def(uv.def), + args: uv.args.stable(tables), + promoted: None, + }) + } + ty::ExprCt(_) => unimplemented!(), + }, + } } } @@ -1108,7 +1129,11 @@ impl<'tcx> Stable<'tcx> for mir::interpret::Allocation { type T = stable_mir::ty::Allocation; fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - allocation_filter(self, alloc_range(rustc_target::abi::Size::ZERO, self.size()), tables) + alloc::allocation_filter( + self, + alloc_range(rustc_target::abi::Size::ZERO, self.size()), + tables, + ) } } @@ -1155,26 +1180,18 @@ impl<'tcx> Stable<'tcx> for rustc_middle::mir::ConstantKind<'tcx> { type T = stable_mir::ty::ConstantKind; fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - match self { - ConstantKind::Ty(c) => match c.kind() { - ty::Value(val) => { - let const_val = tables.tcx.valtree_to_const_val((c.ty(), val)); - stable_mir::ty::ConstantKind::Allocated(new_allocation(self, const_val, tables)) - } - ty::ParamCt(param) => stable_mir::ty::ConstantKind::ParamCt(opaque(¶m)), - ty::ErrorCt(_) => unreachable!(), - _ => unimplemented!(), - }, + match *self { + ConstantKind::Ty(c) => c.stable(tables).literal, ConstantKind::Unevaluated(unev_const, ty) => { stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst { - ty: tables.intern_ty(*ty), + ty: tables.intern_ty(ty), def: tables.const_def(unev_const.def), args: unev_const.args.stable(tables), promoted: unev_const.promoted.map(|u| u.as_u32()), }) } - ConstantKind::Val(val, _) => { - stable_mir::ty::ConstantKind::Allocated(new_allocation(self, *val, tables)) + ConstantKind::Val(val, ty) => { + stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation(ty, val, tables)) } } } diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs index fce5375f848f8..d49f3243777ff 100644 --- a/compiler/rustc_smir/src/stable_mir/ty.rs +++ b/compiler/rustc_smir/src/stable_mir/ty.rs @@ -1,10 +1,5 @@ -use rustc_middle::mir::interpret::{alloc_range, AllocRange, ConstValue, Pointer}; - use super::{mir::Mutability, mir::Safety, with, DefId}; -use crate::{ - rustc_internal::{opaque, Opaque}, - rustc_smir::{Stable, Tables}, -}; +use crate::rustc_internal::Opaque; #[derive(Copy, Clone, Debug)] pub struct Ty(pub usize); @@ -286,128 +281,6 @@ pub struct Allocation { pub mutability: Mutability, } -impl Allocation { - /// Creates new empty `Allocation` from given `Align`. - fn new_empty_allocation(align: rustc_target::abi::Align) -> Allocation { - Allocation { - bytes: Vec::new(), - provenance: ProvenanceMap { ptrs: Vec::new() }, - align: align.bytes(), - mutability: Mutability::Not, - } - } -} - -// We need this method instead of a Stable implementation -// because we need to get `Ty` of the const we are trying to create, to do that -// we need to have access to `ConstantKind` but we can't access that inside Stable impl. -pub fn new_allocation<'tcx>( - const_kind: &rustc_middle::mir::ConstantKind<'tcx>, - const_value: ConstValue<'tcx>, - tables: &mut Tables<'tcx>, -) -> Allocation { - match const_value { - ConstValue::Scalar(scalar) => { - let size = scalar.size(); - let align = tables - .tcx - .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(const_kind.ty())) - .unwrap() - .align; - let mut allocation = rustc_middle::mir::interpret::Allocation::uninit(size, align.abi); - allocation - .write_scalar(&tables.tcx, alloc_range(rustc_target::abi::Size::ZERO, size), scalar) - .unwrap(); - allocation.stable(tables) - } - ConstValue::ZeroSized => { - let align = tables - .tcx - .layout_of(rustc_middle::ty::ParamEnv::empty().and(const_kind.ty())) - .unwrap() - .align; - Allocation::new_empty_allocation(align.abi) - } - ConstValue::Slice { data, start, end } => { - let alloc_id = tables.tcx.create_memory_alloc(data); - let ptr = Pointer::new(alloc_id, rustc_target::abi::Size::from_bytes(start)); - let scalar_ptr = rustc_middle::mir::interpret::Scalar::from_pointer(ptr, &tables.tcx); - let scalar_len = rustc_middle::mir::interpret::Scalar::from_target_usize( - (end - start) as u64, - &tables.tcx, - ); - let layout = tables - .tcx - .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(const_kind.ty())) - .unwrap(); - let mut allocation = - rustc_middle::mir::interpret::Allocation::uninit(layout.size, layout.align.abi); - allocation - .write_scalar( - &tables.tcx, - alloc_range(rustc_target::abi::Size::ZERO, tables.tcx.data_layout.pointer_size), - scalar_ptr, - ) - .unwrap(); - allocation - .write_scalar( - &tables.tcx, - alloc_range(tables.tcx.data_layout.pointer_size, scalar_len.size()), - scalar_len, - ) - .unwrap(); - allocation.stable(tables) - } - ConstValue::ByRef { alloc, offset } => { - let ty_size = tables - .tcx - .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(const_kind.ty())) - .unwrap() - .size; - allocation_filter(&alloc.0, alloc_range(offset, ty_size), tables) - } - } -} - -/// Creates an `Allocation` only from information within the `AllocRange`. -pub fn allocation_filter<'tcx>( - alloc: &rustc_middle::mir::interpret::Allocation, - alloc_range: AllocRange, - tables: &mut Tables<'tcx>, -) -> Allocation { - let mut bytes: Vec> = alloc - .inspect_with_uninit_and_ptr_outside_interpreter( - alloc_range.start.bytes_usize()..alloc_range.end().bytes_usize(), - ) - .iter() - .copied() - .map(Some) - .collect(); - for (i, b) in bytes.iter_mut().enumerate() { - if !alloc - .init_mask() - .get(rustc_target::abi::Size::from_bytes(i + alloc_range.start.bytes_usize())) - { - *b = None; - } - } - let mut ptrs = Vec::new(); - for (offset, prov) in alloc - .provenance() - .ptrs() - .iter() - .filter(|a| a.0 >= alloc_range.start && a.0 <= alloc_range.end()) - { - ptrs.push((offset.bytes_usize() - alloc_range.start.bytes_usize(), opaque(prov))); - } - Allocation { - bytes: bytes, - provenance: ProvenanceMap { ptrs }, - align: alloc.align.bytes(), - mutability: alloc.mutability.stable(tables), - } -} - #[derive(Clone, Debug)] pub enum ConstantKind { Allocated(Allocation), diff --git a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs index ca3c64b428e75..52a11abd545d1 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs @@ -51,13 +51,9 @@ pub(super) struct SearchGraph<'tcx> { impl<'tcx> SearchGraph<'tcx> { pub(super) fn new(tcx: TyCtxt<'tcx>, mode: SolverMode) -> SearchGraph<'tcx> { - let local_overflow_limit = { - let recursion_limit = tcx.recursion_limit().0; - if recursion_limit == 0 { 0 } else { recursion_limit.ilog2() as usize } - }; Self { mode, - local_overflow_limit, + local_overflow_limit: tcx.recursion_limit().0.checked_ilog2().unwrap_or(0) as usize, stack: Default::default(), provisional_cache: ProvisionalCache::empty(), } diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 9dbc87c337c73..e4c7622645402 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -104,16 +104,15 @@ def _download(path, url, probably_big, verbose, exception): # If curl is not present on Win32, we should not sys.exit # but raise `CalledProcessError` or `OSError` instead require(["curl", "--version"], exception=platform_is_win32()) - with open(path, "wb") as outfile: - run(["curl", option, - "-L", # Follow redirect. - "-y", "30", "-Y", "10", # timeout if speed is < 10 bytes/sec for > 30 seconds - "--connect-timeout", "30", # timeout if cannot connect within 30 seconds - "--retry", "3", "-SRf", url], - stdout=outfile, #Implements cli redirect operator '>' - verbose=verbose, - exception=True, # Will raise RuntimeError on failure - ) + run(["curl", option, + "-L", # Follow redirect. + "-y", "30", "-Y", "10", # timeout if speed is < 10 bytes/sec for > 30 seconds + "--connect-timeout", "30", # timeout if cannot connect within 30 seconds + "-o", path, + "--retry", "3", "-SRf", url], + verbose=verbose, + exception=True, # Will raise RuntimeError on failure + ) except (subprocess.CalledProcessError, OSError, RuntimeError): # see http://serverfault.com/questions/301128/how-to-download if platform_is_win32(): diff --git a/src/bootstrap/download.rs b/src/bootstrap/download.rs index 17c308e915b3f..9489297d67d51 100644 --- a/src/bootstrap/download.rs +++ b/src/bootstrap/download.rs @@ -225,6 +225,8 @@ impl Config { "10", // timeout if speed is < 10 bytes/sec for > 30 seconds "--connect-timeout", "30", // timeout if cannot connect within 30 seconds + "-o", + tempfile.to_str().unwrap(), "--retry", "3", "-SRf", @@ -236,8 +238,6 @@ impl Config { curl.arg("--progress-bar"); } curl.arg(url); - let f = File::create(tempfile).unwrap(); - curl.stdout(Stdio::from(f)); if !self.check_run(&mut curl) { if self.build.contains("windows-msvc") { eprintln!("Fallback to PowerShell"); diff --git a/tests/run-make/pgo-branch-weights/Makefile b/tests/run-make/pgo-branch-weights/Makefile index c60206a1f341c..4c9f8b2493ab8 100644 --- a/tests/run-make/pgo-branch-weights/Makefile +++ b/tests/run-make/pgo-branch-weights/Makefile @@ -1,5 +1,6 @@ # needs-profiler-support # ignore-windows-gnu +# ignore-cross-compile # FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works # properly. Since we only have GCC on the CI ignore the test for now. diff --git a/tests/run-make/pgo-gen-lto/Makefile b/tests/run-make/pgo-gen-lto/Makefile index 3f2f6a838b51c..8b647846af3b3 100644 --- a/tests/run-make/pgo-gen-lto/Makefile +++ b/tests/run-make/pgo-gen-lto/Makefile @@ -1,5 +1,6 @@ # needs-profiler-support # ignore-windows-gnu +# ignore-cross-compile # FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works # properly. Since we only have GCC on the CI ignore the test for now. diff --git a/tests/run-make/pgo-gen/Makefile b/tests/run-make/pgo-gen/Makefile index 4623a74957b0f..bf32cfdb802f5 100644 --- a/tests/run-make/pgo-gen/Makefile +++ b/tests/run-make/pgo-gen/Makefile @@ -1,5 +1,6 @@ # needs-profiler-support # ignore-windows-gnu +# ignore-cross-compile # FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works # properly. Since we only have GCC on the CI ignore the test for now. diff --git a/tests/run-make/pgo-indirect-call-promotion/Makefile b/tests/run-make/pgo-indirect-call-promotion/Makefile index 45302215cc64e..542eb244d3959 100644 --- a/tests/run-make/pgo-indirect-call-promotion/Makefile +++ b/tests/run-make/pgo-indirect-call-promotion/Makefile @@ -1,5 +1,6 @@ # needs-profiler-support # ignore-windows-gnu +# ignore-cross-compile # FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works # properly. Since we only have GCC on the CI ignore the test for now. diff --git a/tests/run-make/pgo-use/Makefile b/tests/run-make/pgo-use/Makefile index 3bac9b77aa39c..9f440118daee3 100644 --- a/tests/run-make/pgo-use/Makefile +++ b/tests/run-make/pgo-use/Makefile @@ -1,5 +1,6 @@ # needs-profiler-support # ignore-windows-gnu +# ignore-cross-compile # FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works # properly. Since we only have GCC on the CI ignore the test for now. diff --git a/tests/run-make/pointer-auth-link-with-c/Makefile b/tests/run-make/pointer-auth-link-with-c/Makefile index dffbd303582ec..8fcf10e2096cd 100644 --- a/tests/run-make/pointer-auth-link-with-c/Makefile +++ b/tests/run-make/pointer-auth-link-with-c/Makefile @@ -1,6 +1,7 @@ include ../tools.mk # only-aarch64 +# ignore-cross-compile all: $(COMPILE_OBJ) $(TMPDIR)/test.o test.c diff --git a/tests/run-make/profile/Makefile b/tests/run-make/profile/Makefile index fffc051adbf8e..7919b18ba74a5 100644 --- a/tests/run-make/profile/Makefile +++ b/tests/run-make/profile/Makefile @@ -1,4 +1,5 @@ # needs-profiler-support +# ignore-cross-compile include ../tools.mk