Skip to content

Rollup of 7 pull requests #136470

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 28 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
e00cbf3
Move std::env unit tests to integration tests
bjorn3 Jan 17, 2025
03d44a6
Move std::error unit tests to integration tests
bjorn3 Jan 17, 2025
29166cd
Move std float unit tests to integration tests
bjorn3 Jan 17, 2025
9baeb45
Move std::num unit tests to integration tests
bjorn3 Jan 17, 2025
09c4dbf
Move std::panic unit tests to integration tests
bjorn3 Jan 17, 2025
b8fa843
Move std::path unit tests to integration tests
bjorn3 Jan 17, 2025
4ce917d
Move std::time unit tests to integration tests
bjorn3 Jan 17, 2025
332fb7e
Move std::thread_local unit tests to integration tests
bjorn3 Jan 17, 2025
b8ae372
Move std::sync unit tests to integration tests
bjorn3 Jan 17, 2025
e76d0b8
Fix benchmarking of libstd
bjorn3 Jan 17, 2025
52907d7
Fix for SGX
bjorn3 Jan 23, 2025
05cbf03
Move env modifying tests to a separate integration test
bjorn3 Jan 23, 2025
a063cf5
fix(rustdoc): always use a channel when linking to doc.rust-lang.org
poliorcetics Dec 26, 2024
5efee2c
Enable more tests on Windows
saethlin Dec 26, 2024
88260f4
bootstrap: only build `crt{begin,end}.o` when compiling to MUSL
japaric Jan 21, 2025
acb3bab
bootstrap: add wrapper macros for `tracing`-gated tracing macros
jieyouxu Jan 31, 2025
cc7e3a6
Remove stabilized feature gate
bjorn3 Jan 23, 2025
5465770
Pretty print pattern type values with `transmute` if they don't satis…
oli-obk Jan 29, 2025
7de67a1
Flatten the option check in `lower_pattern_range_endpoint`
Zalathar Feb 3, 2025
85f4cdc
Return range endpoint ascriptions/consts via a `&mut Vec`
Zalathar Feb 3, 2025
2fb1261
Simplify the pattern unpeeling in `lower_pattern_range_endpoint`
Zalathar Feb 3, 2025
b1e8099
Rollup merge of #134777 - saethlin:enable-more-tests-on-windows, r=No…
matthiaskrgr Feb 3, 2025
dcc1acf
Rollup merge of #134807 - poliorcetics:ab/push-skpynvsmwkll, r=camelid
matthiaskrgr Feb 3, 2025
a554771
Rollup merge of #135621 - bjorn3:move_tests_to_stdtests, r=Noratrieb
matthiaskrgr Feb 3, 2025
e8ef8ec
Rollup merge of #135836 - ferrocene:ja-gh135782-build-crt-only-for-mu…
matthiaskrgr Feb 3, 2025
6ec477c
Rollup merge of #136235 - oli-obk:transmuty-pat-tys, r=RalfJung
matthiaskrgr Feb 3, 2025
281a27b
Rollup merge of #136392 - jieyouxu:wrap-tracing, r=onur-ozkan
matthiaskrgr Feb 3, 2025
5ce6787
Rollup merge of #136462 - Zalathar:endpoint, r=oli-obk
matthiaskrgr Feb 3, 2025
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
2 changes: 2 additions & 0 deletions compiler/rustc_const_eval/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ pub fn provide(providers: &mut Providers) {
providers.check_validity_requirement = |tcx, (init_kind, param_env_and_ty)| {
util::check_validity_requirement(tcx, init_kind, param_env_and_ty)
};
providers.hooks.validate_scalar_in_layout =
|tcx, scalar, layout| util::validate_scalar_in_layout(tcx, scalar, layout);
}

/// `rustc_driver::main` installs a handler that will set this to `true` if
Expand Down
52 changes: 40 additions & 12 deletions compiler/rustc_const_eval/src/util/check_validity_requirement.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use rustc_abi::{BackendRepr, FieldsShape, Scalar, Variants};
use rustc_middle::bug;
use rustc_middle::query::TyCtxtAt;
use rustc_middle::ty::layout::{
HasTyCtxt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, ValidityRequirement,
};
use rustc_middle::ty::{PseudoCanonicalInput, Ty, TyCtxt};
use rustc_middle::ty::{PseudoCanonicalInput, ScalarInt, Ty, TyCtxt};
use rustc_middle::{bug, span_bug, ty};

use crate::const_eval::{CanAccessMutGlobal, CheckAlignment, CompileTimeMachine};
use crate::interpret::{InterpCx, MemoryKind};
Expand Down Expand Up @@ -34,7 +35,7 @@ pub fn check_validity_requirement<'tcx>(

let layout_cx = LayoutCx::new(tcx, input.typing_env);
if kind == ValidityRequirement::Uninit || tcx.sess.opts.unstable_opts.strict_init_checks {
check_validity_requirement_strict(layout, &layout_cx, kind)
Ok(check_validity_requirement_strict(layout, &layout_cx, kind))
} else {
check_validity_requirement_lax(layout, &layout_cx, kind)
}
Expand All @@ -46,7 +47,7 @@ fn check_validity_requirement_strict<'tcx>(
ty: TyAndLayout<'tcx>,
cx: &LayoutCx<'tcx>,
kind: ValidityRequirement,
) -> Result<bool, &'tcx LayoutError<'tcx>> {
) -> bool {
let machine = CompileTimeMachine::new(CanAccessMutGlobal::No, CheckAlignment::Error);

let mut cx = InterpCx::new(cx.tcx(), rustc_span::DUMMY_SP, cx.typing_env, machine);
Expand All @@ -69,14 +70,13 @@ fn check_validity_requirement_strict<'tcx>(
// due to this.
// The value we are validating is temporary and discarded at the end of this function, so
// there is no point in reseting provenance and padding.
Ok(cx
.validate_operand(
&allocated.into(),
/*recursive*/ false,
/*reset_provenance_and_padding*/ false,
)
.discard_err()
.is_some())
cx.validate_operand(
&allocated.into(),
/*recursive*/ false,
/*reset_provenance_and_padding*/ false,
)
.discard_err()
.is_some()
}

/// Implements the 'lax' (default) version of the [`check_validity_requirement`] checks; see that
Expand Down Expand Up @@ -168,3 +168,31 @@ fn check_validity_requirement_lax<'tcx>(

Ok(true)
}

pub(crate) fn validate_scalar_in_layout<'tcx>(
tcx: TyCtxtAt<'tcx>,
scalar: ScalarInt,
ty: Ty<'tcx>,
) -> bool {
let machine = CompileTimeMachine::new(CanAccessMutGlobal::No, CheckAlignment::Error);

let typing_env = ty::TypingEnv::fully_monomorphized();
let mut cx = InterpCx::new(tcx.tcx, tcx.span, typing_env, machine);

let Ok(layout) = cx.layout_of(ty) else {
span_bug!(tcx.span, "could not compute layout of {scalar:?}:{ty:?}")
};
let allocated = cx
.allocate(layout, MemoryKind::Machine(crate::const_eval::MemoryKind::Heap))
.expect("OOM: failed to allocate for uninit check");

cx.write_scalar(scalar, &allocated).unwrap();

cx.validate_operand(
&allocated.into(),
/*recursive*/ false,
/*reset_provenance_and_padding*/ false,
)
.discard_err()
.is_some()
}
1 change: 1 addition & 0 deletions compiler/rustc_const_eval/src/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ mod type_name;

pub use self::alignment::{is_disaligned, is_within_packed};
pub use self::check_validity_requirement::check_validity_requirement;
pub(crate) use self::check_validity_requirement::validate_scalar_in_layout;
pub use self::compare_types::{relate_types, sub_types};
pub use self::type_name::type_name;

Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_middle/src/hooks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ declare_hooks! {
hook save_dep_graph() -> ();

hook query_key_hash_verify_all() -> ();

/// Ensure the given scalar is valid for the given type.
/// This checks non-recursive runtime validity.
hook validate_scalar_in_layout(scalar: crate::ty::ScalarInt, ty: Ty<'tcx>) -> bool;
}

#[cold]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1741,7 +1741,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
" as ",
)?;
}
ty::Pat(base_ty, pat) => {
ty::Pat(base_ty, pat) if self.tcx().validate_scalar_in_layout(int, ty) => {
self.pretty_print_const_scalar_int(int, *base_ty, print_ty)?;
p!(write(" is {pat:?}"));
}
Expand Down
81 changes: 42 additions & 39 deletions compiler/rustc_mir_build/src/thir/pattern/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,42 +155,41 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
fn lower_pattern_range_endpoint(
&mut self,
expr: Option<&'tcx hir::PatExpr<'tcx>>,
) -> Result<
(Option<PatRangeBoundary<'tcx>>, Option<Ascription<'tcx>>, Option<LocalDefId>),
ErrorGuaranteed,
> {
match expr {
None => Ok((None, None, None)),
Some(expr) => {
let (kind, ascr, inline_const) = match self.lower_lit(expr) {
PatKind::ExpandedConstant { subpattern, def_id, is_inline: true } => {
(subpattern.kind, None, def_id.as_local())
}
PatKind::ExpandedConstant { subpattern, is_inline: false, .. } => {
(subpattern.kind, None, None)
}
PatKind::AscribeUserType { ascription, subpattern: box Pat { kind, .. } } => {
(kind, Some(ascription), None)
}
kind => (kind, None, None),
};
let value = match kind {
PatKind::Constant { value } => value,
PatKind::ExpandedConstant { subpattern, .. }
if let PatKind::Constant { value } = subpattern.kind =>
{
value
}
_ => {
let msg = format!(
"found bad range pattern endpoint `{expr:?}` outside of error recovery"
);
return Err(self.tcx.dcx().span_delayed_bug(expr.span, msg));
// Out-parameters collecting extra data to be reapplied by the caller
ascriptions: &mut Vec<Ascription<'tcx>>,
inline_consts: &mut Vec<LocalDefId>,
) -> Result<Option<PatRangeBoundary<'tcx>>, ErrorGuaranteed> {
let Some(expr) = expr else { return Ok(None) };

// Lower the endpoint into a temporary `PatKind` that will then be
// deconstructed to obtain the constant value and other data.
let mut kind: PatKind<'tcx> = self.lower_lit(expr);

// Unpeel any ascription or inline-const wrapper nodes.
loop {
match kind {
PatKind::AscribeUserType { ascription, subpattern } => {
ascriptions.push(ascription);
kind = subpattern.kind;
}
PatKind::ExpandedConstant { is_inline, def_id, subpattern } => {
if is_inline {
inline_consts.extend(def_id.as_local());
}
};
Ok((Some(PatRangeBoundary::Finite(value)), ascr, inline_const))
kind = subpattern.kind;
}
_ => break,
}
}

// The unpeeled kind should now be a constant, giving us the endpoint value.
let PatKind::Constant { value } = kind else {
let msg =
format!("found bad range pattern endpoint `{expr:?}` outside of error recovery");
return Err(self.tcx.dcx().span_delayed_bug(expr.span, msg));
};

Ok(Some(PatRangeBoundary::Finite(value)))
}

/// Overflowing literals are linted against in a late pass. This is mostly fine, except when we
Expand Down Expand Up @@ -253,11 +252,15 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
self.tcx.dcx().span_bug(span, msg);
}

let (lo, lo_ascr, lo_inline) = self.lower_pattern_range_endpoint(lo_expr)?;
let (hi, hi_ascr, hi_inline) = self.lower_pattern_range_endpoint(hi_expr)?;
// Collect extra data while lowering the endpoints, to be reapplied later.
let mut ascriptions = vec![];
let mut inline_consts = vec![];

let mut lower_endpoint =
|expr| self.lower_pattern_range_endpoint(expr, &mut ascriptions, &mut inline_consts);

let lo = lo.unwrap_or(PatRangeBoundary::NegInfinity);
let hi = hi.unwrap_or(PatRangeBoundary::PosInfinity);
let lo = lower_endpoint(lo_expr)?.unwrap_or(PatRangeBoundary::NegInfinity);
let hi = lower_endpoint(hi_expr)?.unwrap_or(PatRangeBoundary::PosInfinity);

let cmp = lo.compare_with(hi, ty, self.tcx, self.typing_env);
let mut kind = PatKind::Range(Box::new(PatRange { lo, hi, end, ty }));
Expand Down Expand Up @@ -298,13 +301,13 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
// If we are handling a range with associated constants (e.g.
// `Foo::<'a>::A..=Foo::B`), we need to put the ascriptions for the associated
// constants somewhere. Have them on the range pattern.
for ascription in [lo_ascr, hi_ascr].into_iter().flatten() {
for ascription in ascriptions {
kind = PatKind::AscribeUserType {
ascription,
subpattern: Box::new(Pat { span, ty, kind }),
};
}
for def in [lo_inline, hi_inline].into_iter().flatten() {
for def in inline_consts {
kind = PatKind::ExpandedConstant {
def_id: def.to_def_id(),
is_inline: true,
Expand Down
13 changes: 13 additions & 0 deletions library/std/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-lang/rust.git"
description = "The Rust Standard Library"
edition = "2021"
autobenches = false

[lib]
crate-type = ["dylib", "rlib"]
Expand Down Expand Up @@ -130,6 +131,18 @@ name = "pipe-subprocess"
path = "tests/pipe_subprocess.rs"
harness = false

[[test]]
name = "sync"
path = "tests/sync/lib.rs"

[[test]]
name = "floats"
path = "tests/floats/lib.rs"

[[test]]
name = "thread_local"
path = "tests/thread_local/lib.rs"

[[bench]]
name = "stdbenches"
path = "benches/lib.rs"
Expand Down
2 changes: 2 additions & 0 deletions library/std/benches/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@
extern crate test;

mod hash;
mod path;
mod time;
114 changes: 114 additions & 0 deletions library/std/benches/path.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
use core::hint::black_box;
use std::collections::{BTreeSet, HashSet};
use std::hash::{DefaultHasher, Hash, Hasher};
use std::path::*;

#[bench]
#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_cmp_fast_path_buf_sort(b: &mut test::Bencher) {
let prefix = "my/home";
let mut paths: Vec<_> =
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();

paths.sort();

b.iter(|| {
black_box(paths.as_mut_slice()).sort_unstable();
});
}

#[bench]
#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_cmp_fast_path_long(b: &mut test::Bencher) {
let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
let paths: Vec<_> =
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();

let mut set = BTreeSet::new();

paths.iter().for_each(|p| {
set.insert(p.as_path());
});

b.iter(|| {
set.remove(paths[500].as_path());
set.insert(paths[500].as_path());
});
}

#[bench]
#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_cmp_fast_path_short(b: &mut test::Bencher) {
let prefix = "my/home";
let paths: Vec<_> =
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();

let mut set = BTreeSet::new();

paths.iter().for_each(|p| {
set.insert(p.as_path());
});

b.iter(|| {
set.remove(paths[500].as_path());
set.insert(paths[500].as_path());
});
}

#[bench]
#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_hashset(b: &mut test::Bencher) {
let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
let paths: Vec<_> =
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();

let mut set = HashSet::new();

paths.iter().for_each(|p| {
set.insert(p.as_path());
});

b.iter(|| {
set.remove(paths[500].as_path());
set.insert(black_box(paths[500].as_path()))
});
}

#[bench]
#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_hashset_miss(b: &mut test::Bencher) {
let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
let paths: Vec<_> =
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();

let mut set = HashSet::new();

paths.iter().for_each(|p| {
set.insert(p.as_path());
});

let probe = PathBuf::from(prefix).join("other");

b.iter(|| set.remove(black_box(probe.as_path())));
}

#[bench]
fn bench_hash_path_short(b: &mut test::Bencher) {
let mut hasher = DefaultHasher::new();
let path = Path::new("explorer.exe");

b.iter(|| black_box(path).hash(&mut hasher));

black_box(hasher.finish());
}

#[bench]
fn bench_hash_path_long(b: &mut test::Bencher) {
let mut hasher = DefaultHasher::new();
let path =
Path::new("/aaaaa/aaaaaa/./../aaaaaaaa/bbbbbbbbbbbbb/ccccccccccc/ddddddddd/eeeeeee.fff");

b.iter(|| black_box(path).hash(&mut hasher));

black_box(hasher.finish());
}
Loading
Loading