Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions compiler/rustc_abi/src/layout/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,19 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
/// function call isn't allowed (a.k.a. `va_list`).
///
/// This function handles transparent types automatically.
pub fn pass_indirectly_in_non_rustic_abis<C>(mut self, cx: &C) -> bool
pub fn pass_indirectly_in_non_rustic_abis<C>(self, cx: &C) -> bool
where
Ty: TyAbiInterface<'a, C> + Copy,
{
let base = self.peel_transparent_wrappers(cx);
Ty::is_pass_indirectly_in_non_rustic_abis_flag_set(base)
}

/// Recursively peel away transparent wrappers, returning the inner value.
///
/// The return value is not `repr(transparent)` and/or does
/// not have a non-1zst field.
pub fn peel_transparent_wrappers<C>(mut self, cx: &C) -> Self
where
Ty: TyAbiInterface<'a, C> + Copy,
{
Expand All @@ -300,7 +312,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
self = field;
}

Ty::is_pass_indirectly_in_non_rustic_abis_flag_set(self)
self
}

/// Finds the one field that is not a 1-ZST.
Expand Down
26 changes: 11 additions & 15 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use rustc_abi::{BackendRepr, ExternAbi, Float, Integer, Primitive, Scalar};
use rustc_abi::ExternAbi;
use rustc_errors::{DiagCtxtHandle, E0781, struct_span_code_err};
use rustc_hir::{self as hir, HirId};
use rustc_middle::bug;
use rustc_middle::ty::layout::{LayoutError, TyAndLayout};
use rustc_middle::ty::layout::{LayoutCx, LayoutError, TyAndLayout};
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
use rustc_span::Span;

Expand Down Expand Up @@ -150,34 +150,30 @@ fn is_valid_cmse_output<'tcx>(

let typing_env = ty::TypingEnv::fully_monomorphized();
let layout = tcx.layout_of(typing_env.as_query_input(return_type))?;
let layout_cx = LayoutCx::new(tcx, typing_env);

if !is_valid_cmse_output_layout(layout) {
if !is_valid_cmse_output_layout(layout_cx, layout) {
dcx.emit_err(errors::CmseOutputStackSpill { span: fn_decl.output.span(), abi });
}

Ok(())
}

/// Returns whether the output will fit into the available registers
fn is_valid_cmse_output_layout<'tcx>(layout: TyAndLayout<'tcx>) -> bool {
fn is_valid_cmse_output_layout<'tcx>(cx: LayoutCx<'tcx>, layout: TyAndLayout<'tcx>) -> bool {
let size = layout.layout.size().bytes();

if size <= 4 {
return true;
} else if size > 8 {
} else if size != 8 {
return false;
}

// Accept scalar 64-bit types.
let BackendRepr::Scalar(scalar) = layout.layout.backend_repr else {
return false;
};

let Scalar::Initialized { value, .. } = scalar else {
return false;
};

matches!(value, Primitive::Int(Integer::I64, _) | Primitive::Float(Float::F64))
// Accept (transparently wrapped) scalar 64-bit primitives.
matches!(
layout.peel_transparent_wrappers(&cx).ty.kind(),
ty::Int(ty::IntTy::I64) | ty::Uint(ty::UintTy::U64) | ty::Float(ty::FloatTy::F64)
)
}

fn should_emit_layout_error<'tcx>(abi: ExternAbi, layout_err: &'tcx LayoutError<'tcx>) -> bool {
Expand Down
70 changes: 66 additions & 4 deletions library/core/src/num/nonzero.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1240,16 +1240,78 @@ macro_rules! nonzero_integer {
// So the result cannot be zero.
unsafe { Self::new_unchecked(self.get().saturating_pow(other)) }
}

/// Parses a non-zero integer from a string slice with digits in a given base.
///
/// The string is expected to be an optional
#[doc = sign_dependent_expr!{
$signedness ?
if signed {
" `+` or `-` "
}
if unsigned {
" `+` "
}
}]
/// sign followed by only digits. Leading and trailing non-digit characters (including
/// whitespace) represent an error. Underscores (which are accepted in Rust literals)
/// also represent an error.
///
/// Digits are a subset of these characters, depending on `radix`:
///
/// - `0-9`
/// - `a-z`
/// - `A-Z`
///
/// # Panics
///
/// This method panics if `radix` is not in the range from 2 to 36.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(nonzero_from_str_radix)]
///
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::from_str_radix(\"A\", 16), Ok(NonZero::new(10)?));")]
/// # Some(())
/// # }
/// ```
///
/// Trailing space returns error:
///
/// ```
/// #![feature(nonzero_from_str_radix)]
///
/// # use std::num::NonZero;
/// #
#[doc = concat!("assert!(NonZero::<", stringify!($Int), ">::from_str_radix(\"1 \", 10).is_err());")]
/// ```
#[unstable(feature = "nonzero_from_str_radix", issue = "152193")]
#[inline]
pub const fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
let n = match <$Int>::from_str_radix(src, radix) {
Ok(n) => n,
Err(err) => return Err(err),
};
if let Some(n) = Self::new(n) {
Ok(n)
} else {
Err(ParseIntError { kind: IntErrorKind::Zero })
}
}
}

#[stable(feature = "nonzero_parse", since = "1.35.0")]
impl FromStr for NonZero<$Int> {
type Err = ParseIntError;
fn from_str(src: &str) -> Result<Self, Self::Err> {
Self::new(<$Int>::from_str_radix(src, 10)?)
.ok_or(ParseIntError {
kind: IntErrorKind::Zero
})
Self::from_str_radix(src, 10)
}
}

Expand Down
1 change: 1 addition & 0 deletions library/coretests/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
#![feature(new_range_api)]
#![feature(next_index)]
#![feature(non_exhaustive_omitted_patterns_lint)]
#![feature(nonzero_from_str_radix)]
#![feature(numfmt)]
#![feature(one_sided_range)]
#![feature(option_reduce)]
Expand Down
35 changes: 35 additions & 0 deletions library/coretests/tests/nonzero.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,41 @@ fn test_from_signed_nonzero() {
assert_eq!(num, 1i32);
}

#[test]
fn test_from_str_radix() {
assert_eq!(NonZero::<u8>::from_str_radix("123", 10), Ok(NonZero::new(123).unwrap()));
assert_eq!(NonZero::<u8>::from_str_radix("1001", 2), Ok(NonZero::new(9).unwrap()));
assert_eq!(NonZero::<u8>::from_str_radix("123", 8), Ok(NonZero::new(83).unwrap()));
assert_eq!(NonZero::<u16>::from_str_radix("123", 16), Ok(NonZero::new(291).unwrap()));
assert_eq!(NonZero::<u16>::from_str_radix("ffff", 16), Ok(NonZero::new(65535).unwrap()));
assert_eq!(NonZero::<u8>::from_str_radix("z", 36), Ok(NonZero::new(35).unwrap()));
assert_eq!(
NonZero::<u8>::from_str_radix("0", 10).err().map(|e| e.kind().clone()),
Some(IntErrorKind::Zero)
);
assert_eq!(
NonZero::<u8>::from_str_radix("-1", 10).err().map(|e| e.kind().clone()),
Some(IntErrorKind::InvalidDigit)
);
assert_eq!(
NonZero::<i8>::from_str_radix("-129", 10).err().map(|e| e.kind().clone()),
Some(IntErrorKind::NegOverflow)
);
assert_eq!(
NonZero::<u8>::from_str_radix("257", 10).err().map(|e| e.kind().clone()),
Some(IntErrorKind::PosOverflow)
);

assert_eq!(
NonZero::<u8>::from_str_radix("Z", 10).err().map(|e| e.kind().clone()),
Some(IntErrorKind::InvalidDigit)
);
assert_eq!(
NonZero::<u8>::from_str_radix("_", 2).err().map(|e| e.kind().clone()),
Some(IntErrorKind::InvalidDigit)
);
}

#[test]
fn test_from_str() {
assert_eq!("123".parse::<NonZero<u8>>(), Ok(NonZero::new(123).unwrap()));
Expand Down
2 changes: 1 addition & 1 deletion src/bootstrap/src/core/build_steps/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@ macro_rules! tool_check_step {
const IS_HOST: bool = true;

fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.paths(&[ $path, $( $alt_path ),* ])
run.path($path) $( .path( $alt_path ) )*
}

fn is_default_step(_builder: &Builder<'_>) -> bool {
Expand Down
6 changes: 3 additions & 3 deletions src/bootstrap/src/core/build_steps/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3156,7 +3156,7 @@ impl Step for CrateRustdoc {
const IS_HOST: bool = true;

fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.paths(&["src/librustdoc", "src/tools/rustdoc"])
run.path("src/librustdoc").path("src/tools/rustdoc")
}

fn is_default_step(_builder: &Builder<'_>) -> bool {
Expand Down Expand Up @@ -3817,7 +3817,7 @@ impl Step for CodegenCranelift {
const IS_HOST: bool = true;

fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.paths(&["compiler/rustc_codegen_cranelift"])
run.path("compiler/rustc_codegen_cranelift")
}

fn is_default_step(_builder: &Builder<'_>) -> bool {
Expand Down Expand Up @@ -3938,7 +3938,7 @@ impl Step for CodegenGCC {
const IS_HOST: bool = true;

fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.paths(&["compiler/rustc_codegen_gcc"])
run.path("compiler/rustc_codegen_gcc")
}

fn is_default_step(_builder: &Builder<'_>) -> bool {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,5 @@ expression: bench
- Set({bench::compiler/rustc_windows_rc})
[Bench] test::CrateRustdoc
targets: [x86_64-unknown-linux-gnu]
- Set({bench::src/librustdoc, bench::src/tools/rustdoc})
- Set({bench::src/librustdoc})
- Set({bench::src/tools/rustdoc})
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ expression: check
- Set({check::compiler/rustc_windows_rc})
[Check] check::Rustdoc
targets: [x86_64-unknown-linux-gnu]
- Set({check::src/librustdoc, check::src/tools/rustdoc})
- Set({check::src/librustdoc})
- Set({check::src/tools/rustdoc})
[Check] check::CraneliftCodegenBackend
targets: [x86_64-unknown-linux-gnu]
- Set({check::cg_clif})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ expression: check compiletest --include-default-paths
- Set({check::compiler/rustc_windows_rc})
[Check] check::Rustdoc
targets: [x86_64-unknown-linux-gnu]
- Set({check::src/librustdoc, check::src/tools/rustdoc})
- Set({check::src/librustdoc})
- Set({check::src/tools/rustdoc})
[Check] check::CraneliftCodegenBackend
targets: [x86_64-unknown-linux-gnu]
- Set({check::cg_clif})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ expression: fix
- Set({fix::compiler/rustc_windows_rc})
[Fix] check::Rustdoc
targets: [x86_64-unknown-linux-gnu]
- Set({fix::src/librustdoc, fix::src/tools/rustdoc})
- Set({fix::src/librustdoc})
- Set({fix::src/tools/rustdoc})
[Fix] check::CraneliftCodegenBackend
targets: [x86_64-unknown-linux-gnu]
- Set({fix::cg_clif})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ expression: test
- Set({test::compiler/rustc_windows_rc})
[Test] test::CrateRustdoc
targets: [x86_64-unknown-linux-gnu]
- Set({test::src/librustdoc, test::src/tools/rustdoc})
- Set({test::src/librustdoc})
- Set({test::src/tools/rustdoc})
[Test] test::CrateRustdocJsonTypes
targets: [x86_64-unknown-linux-gnu]
- Set({test::src/rustdoc-json-types})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ expression: test librustdoc rustdoc
---
[Test] test::CrateRustdoc
targets: [x86_64-unknown-linux-gnu]
- Set({test::src/librustdoc, test::src/tools/rustdoc})
- Set({test::src/librustdoc})
- Set({test::src/tools/rustdoc})
[Test] test::RustdocBook
targets: [x86_64-unknown-linux-gnu]
- Set({test::src/doc/rustdoc})
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ expression: test --skip=coverage
- Set({test::compiler/rustc_windows_rc})
[Test] test::CrateRustdoc
targets: [x86_64-unknown-linux-gnu]
- Set({test::src/librustdoc, test::src/tools/rustdoc})
- Set({test::src/librustdoc})
- Set({test::src/tools/rustdoc})
[Test] test::CrateRustdocJsonTypes
targets: [x86_64-unknown-linux-gnu]
- Set({test::src/rustdoc-json-types})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ expression: test --skip=tests
- Set({test::compiler/rustc_windows_rc})
[Test] test::CrateRustdoc
targets: [x86_64-unknown-linux-gnu]
- Set({test::src/librustdoc, test::src/tools/rustdoc})
- Set({test::src/librustdoc})
- Set({test::src/tools/rustdoc})
[Test] test::CrateRustdocJsonTypes
targets: [x86_64-unknown-linux-gnu]
- Set({test::src/rustdoc-json-types})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ expression: test --skip=tests --skip=coverage-map --skip=coverage-run --skip=lib
- Set({test::compiler/rustc_windows_rc})
[Test] test::CrateRustdoc
targets: [x86_64-unknown-linux-gnu]
- Set({test::src/librustdoc, test::src/tools/rustdoc})
- Set({test::src/librustdoc})
- Set({test::src/tools/rustdoc})
[Test] test::CrateRustdocJsonTypes
targets: [x86_64-unknown-linux-gnu]
- Set({test::src/rustdoc-json-types})
Expand Down
39 changes: 10 additions & 29 deletions src/bootstrap/src/core/builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -558,38 +558,19 @@ impl<'a> ShouldRun<'a> {
/// single, non-aliased path
///
/// Must be an on-disk path; use `alias` for names that do not correspond to on-disk paths.
pub fn path(self, path: &str) -> Self {
self.paths(&[path])
}

/// Multiple aliases for the same job.
///
/// This differs from [`path`] in that multiple calls to path will end up calling `make_run`
/// multiple times, whereas a single call to `paths` will only ever generate a single call to
/// `make_run`.
///
/// This is analogous to `all_krates`, although `all_krates` is gone now. Prefer [`path`] where possible.
///
/// [`path`]: ShouldRun::path
pub fn paths(mut self, paths: &[&str]) -> Self {
pub fn path(mut self, path: &str) -> Self {
let submodules_paths = self.builder.submodule_paths();

self.paths.insert(PathSet::Set(
paths
.iter()
.map(|p| {
// assert only if `p` isn't submodule
if !submodules_paths.iter().any(|sm_p| p.contains(sm_p)) {
assert!(
self.builder.src.join(p).exists(),
"`should_run.paths` should correspond to real on-disk paths - use `alias` if there is no relevant path: {p}"
);
}
// assert only if `p` isn't submodule
if !submodules_paths.iter().any(|sm_p| path.contains(sm_p)) {
assert!(
self.builder.src.join(path).exists(),
"`should_run.path` should correspond to a real on-disk path - use `alias` if there is no relevant path: {path}"
);
}

TaskPath { path: p.into(), kind: Some(self.kind) }
})
.collect(),
));
let task = TaskPath { path: path.into(), kind: Some(self.kind) };
self.paths.insert(PathSet::Set(BTreeSet::from_iter([task])));
self
}

Expand Down
Loading
Loading