Auto merge of #139220 - matthiaskrgr:rollup-v1un5wz, r=matthiaskrgr

Rollup of 8 pull requests

Successful merges:

 - #110406 (rustdoc-json: Add test for #[automatically_derived] attribute)
 - #138790 (Note potential but private items in show_candidates)
 - #139002 (Add release notes for 1.86.0)
 - #139022 (increment depth of nested obligations)
 - #139129 (Add tests for slice bounds check optimization)
 - #139188 (PassWrapper: adapt for llvm/llvm-project@94122d58fc77079a291a3d008914…)
 - #139193 (Feed HIR for by-move coroutine body def, since the inliner tries to read its attrs)
 - #139202 (Improve docs of ValTreeKind)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-04-01 21:28:39 +00:00
commit 9b7d5ac818
37 changed files with 420 additions and 105 deletions

View File

@ -1,3 +1,126 @@
Version 1.86.0 (2025-04-03)
==========================
<a id="1.86.0-Language"></a>
Language
--------
- [Stabilize upcasting trait objects to supertraits.](https://github.com/rust-lang/rust/pull/134367)
- [Allow safe functions to be marked with the `#[target_feature]` attribute.](https://github.com/rust-lang/rust/pull/134090)
- [The `missing_abi` lint now warns-by-default.](https://github.com/rust-lang/rust/pull/132397)
- Rust now lints about double negations, to catch cases that might have intended to be a prefix decrement operator (`--x`) as written in other languages. This was previously a clippy lint, `clippy::double_neg`, and is [now available directly in Rust as `double_negations`.](https://github.com/rust-lang/rust/pull/126604)
- [More pointers are now detected as definitely not-null based on their alignment in const eval.](https://github.com/rust-lang/rust/pull/133700)
- [Empty `repr()` attribute applied to invalid items are now correctly rejected.](https://github.com/rust-lang/rust/pull/133925)
- [Inner attributes `#![test]` and `#![rustfmt::skip]` are no longer accepted in more places than intended.](https://github.com/rust-lang/rust/pull/134276)
<a id="1.86.0-Compiler"></a>
Compiler
--------
- [Debug-assert that raw pointers are non-null on access.](https://github.com/rust-lang/rust/pull/134424)
- [Change `-O` to mean `-C opt-level=3` instead of `-C opt-level=2` to match Cargo's defaults.](https://github.com/rust-lang/rust/pull/135439)
- [Fix emission of `overflowing_literals` under certain macro environments.](https://github.com/rust-lang/rust/pull/136393)
<a id="1.86.0-Platform-Support"></a>
Platform Support
----------------
- [Replace `i686-unknown-redox` target with `i586-unknown-redox`.](https://github.com/rust-lang/rust/pull/136698)
- [Increase baseline CPU of `i686-unknown-hurd-gnu` to Pentium 4.](https://github.com/rust-lang/rust/pull/136700)
- New tier 3 targets:
- [`{aarch64-unknown,x86_64-pc}-nto-qnx710_iosock`](https://github.com/rust-lang/rust/pull/133631).
For supporting Neutrino QNX 7.1 with `io-socket` network stack.
- [`{aarch64-unknown,x86_64-pc}-nto-qnx800`](https://github.com/rust-lang/rust/pull/133631).
For supporting Neutrino QNX 8.0 (`no_std`-only).
- [`{x86_64,i686}-win7-windows-gnu`](https://github.com/rust-lang/rust/pull/134609).
Intended for backwards compatibility with Windows 7. `{x86_64,i686}-win7-windows-msvc` are the Windows MSVC counterparts that already exist as Tier 3 targets.
- [`amdgcn-amd-amdhsa`](https://github.com/rust-lang/rust/pull/134740).
- [`x86_64-pc-cygwin`](https://github.com/rust-lang/rust/pull/134999).
- [`{mips,mipsel}-mti-none-elf`](https://github.com/rust-lang/rust/pull/135074).
Initial bare-metal support.
- [`m68k-unknown-none-elf`](https://github.com/rust-lang/rust/pull/135085).
- [`armv7a-nuttx-{eabi,eabihf}`, `aarch64-unknown-nuttx`, and `thumbv7a-nuttx-{eabi,eabihf}`](https://github.com/rust-lang/rust/pull/135757).
Refer to Rust's [platform support page][platform-support-doc]
for more information on Rust's tiered platform support.
<a id="1.86.0-Libraries"></a>
Libraries
---------
- The type of `FromBytesWithNulError` in `CStr::from_bytes_with_nul(bytes: &[u8]) -> Result<&Self, FromBytesWithNulError>` was [changed from an opaque struct to an enum](https://github.com/rust-lang/rust/pull/134143), allowing users to examine why the conversion failed.
- [Remove `RustcDecodable` and `RustcEncodable`.](https://github.com/rust-lang/rust/pull/134272)
- [Deprecate libtest's `--logfile` option.](https://github.com/rust-lang/rust/pull/134283)
- [On recent versions of Windows, `std::fs::remove_file` will now remove read-only files.](https://github.com/rust-lang/rust/pull/134679)
<a id="1.86.0-Stabilized-APIs"></a>
Stabilized APIs
---------------
- [`{float}::next_down`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.next_down)
- [`{float}::next_up`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.next_up)
- [`<[_]>::get_disjoint_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.get_disjoint_mut)
- [`<[_]>::get_disjoint_unchecked_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.get_disjoint_unchecked_mut)
- [`slice::GetDisjointMutError`](https://doc.rust-lang.org/stable/std/slice/enum.GetDisjointMutError.html)
- [`HashMap::get_disjoint_mut`](https://doc.rust-lang.org/std/collections/hash_map/struct.HashMap.html#method.get_disjoint_mut)
- [`HashMap::get_disjoint_unchecked_mut`](https://doc.rust-lang.org/std/collections/hash_map/struct.HashMap.html#method.get_disjoint_unchecked_mut)
- [`NonZero::count_ones`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.count_ones)
- [`Vec::pop_if`](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.pop_if)
- [`sync::Once::wait`](https://doc.rust-lang.org/stable/std/sync/struct.Once.html#method.wait)
- [`sync::Once::wait_force`](https://doc.rust-lang.org/stable/std/sync/struct.Once.html#method.wait_force)
- [`sync::OnceLock::wait`](https://doc.rust-lang.org/stable/std/sync/struct.OnceLock.html#method.wait)
These APIs are now stable in const contexts:
- [`hint::black_box`](https://doc.rust-lang.org/stable/std/hint/fn.black_box.html)
- [`io::Cursor::get_mut`](https://doc.rust-lang.org/stable/std/io/struct.Cursor.html#method.get_mut)
- [`io::Cursor::set_position`](https://doc.rust-lang.org/stable/std/io/struct.Cursor.html#method.set_position)
- [`str::is_char_boundary`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.is_char_boundary)
- [`str::split_at`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_at)
- [`str::split_at_checked`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_at_checked)
- [`str::split_at_mut`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_at_mut)
- [`str::split_at_mut_checked`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_at_mut_checked)
<a id="1.86.0-Cargo"></a>
Cargo
-----
- [When merging, replace rather than combine configuration keys that refer to a program path and its arguments.](https://github.com/rust-lang/cargo/pull/15066/)
- [Error if both `--package` and `--workspace` are passed but the requested package is missing.](https://github.com/rust-lang/cargo/pull/15071/) This was previously silently ignored, which was considered a bug since missing packages should be reported.
- [Deprecate the token argument in `cargo login` to avoid shell history leaks.](https://github.com/rust-lang/cargo/pull/15057/)
- [Simplify the implementation of `SourceID` comparisons.](https://github.com/rust-lang/cargo/pull/14980/) This may potentially change behavior if the canonicalized URL compares differently in alternative registries.
<a id="1.86.0-Rustdoc"></a>
Rustdoc
-----
- [Add a sans-serif font setting.](https://github.com/rust-lang/rust/pull/133636)
<a id="1.86.0-Compatibility-Notes"></a>
Compatibility Notes
-------------------
- [The `wasm_c_abi` future compatibility warning is now a hard error.](https://github.com/rust-lang/rust/pull/133951)
Users of `wasm-bindgen` should upgrade to at least version 0.2.89, otherwise compilation will fail.
- [Remove long-deprecated no-op attributes `#![no_start]` and `#![crate_id]`.](https://github.com/rust-lang/rust/pull/134300)
- [The future incompatibility lint `cenum_impl_drop_cast` has been made into a hard error.](https://github.com/rust-lang/rust/pull/135964) This means it is now an error to cast a field-less enum to an integer if the enum implements `Drop`.
- [SSE2 is now required for "i686" 32-bit x86 hard-float targets; disabling it causes a warning that will become a hard error eventually.](https://github.com/rust-lang/rust/pull/137037)
To compile for pre-SSE2 32-bit x86, use a "i586" target instead.
<a id="1.86.0-Internal-Changes"></a>
Internal Changes
----------------
These changes do not affect any public interfaces of Rust, but they represent
significant improvements to the performance or internals of rustc and related
tools.
- [Build the rustc on AArch64 Linux with ThinLTO + PGO.](https://github.com/rust-lang/rust/pull/133807)
The ARM 64-bit compiler (AArch64) on Linux is now optimized with ThinLTO and PGO, similar to the optimizations we have already performed for the x86-64 compiler on Linux. This should make it up to 30% faster.
Version 1.85.1 (2025-03-18)
==========================

View File

@ -855,10 +855,15 @@ extern "C" LLVMRustResult LLVMRustOptimize(
}
if (LintIR) {
PipelineStartEPCallbacks.push_back(
[](ModulePassManager &MPM, OptimizationLevel Level) {
MPM.addPass(createModuleToFunctionPassAdaptor(LintPass()));
});
PipelineStartEPCallbacks.push_back([](ModulePassManager &MPM,
OptimizationLevel Level) {
#if LLVM_VERSION_GE(21, 0)
MPM.addPass(
createModuleToFunctionPassAdaptor(LintPass(/*AbortOnError=*/true)));
#else
MPM.addPass(createModuleToFunctionPassAdaptor(LintPass()));
#endif
});
}
if (InstrumentCoverage) {

View File

@ -33,7 +33,7 @@ pub enum ValTreeKind<'tcx> {
/// The fields of any kind of aggregate. Structs, tuples and arrays are represented by
/// listing their fields' values in order.
///
/// Enums are represented by storing their discriminant as a field, followed by all
/// Enums are represented by storing their variant index as a u32 field, followed by all
/// the fields of the variant.
///
/// ZST types are represented as an empty slice.

View File

@ -219,6 +219,8 @@ pub(crate) fn coroutine_by_move_body_def_id<'tcx>(
mir::MirSource::from_instance(InstanceKind::Item(body_def.def_id().to_def_id()));
dump_mir(tcx, false, "built", &"after", &by_move_body, |_, _| Ok(()));
// Feed HIR because we try to access this body's attrs in the inliner.
body_def.feed_hir();
// Inherited from the by-ref coroutine.
body_def.codegen_fn_attrs(tcx.codegen_fn_attrs(coroutine_def_id).clone());
body_def.coverage_attr_on(tcx.coverage_attr_on(coroutine_def_id));

View File

@ -1325,11 +1325,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
})
}
// If only some candidates are accessible, take just them
if !candidates.iter().all(|v: &ImportSuggestion| !v.accessible) {
candidates.retain(|x| x.accessible)
}
candidates
}
@ -1793,7 +1788,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
&import_suggestions,
Instead::Yes,
FoundUse::Yes,
DiagMode::Import { append: single_nested },
DiagMode::Import { append: single_nested, unresolved_import: false },
vec![],
"",
);
@ -2750,6 +2745,8 @@ pub(crate) enum DiagMode {
Pattern,
/// The binding is part of a use statement
Import {
/// `true` means diagnostics is for unresolved import
unresolved_import: bool,
/// `true` mean add the tips afterward for case `use a::{b,c}`,
/// rather than replacing within.
append: bool,
@ -2800,6 +2797,7 @@ fn show_candidates(
return false;
}
let mut showed = false;
let mut accessible_path_strings: Vec<PathString<'_>> = Vec::new();
let mut inaccessible_path_strings: Vec<PathString<'_>> = Vec::new();
@ -2958,8 +2956,11 @@ fn show_candidates(
append_candidates(&mut msg, accessible_path_strings);
err.help(msg);
}
true
} else if !(inaccessible_path_strings.is_empty() || matches!(mode, DiagMode::Import { .. })) {
showed = true;
}
if !inaccessible_path_strings.is_empty()
&& (!matches!(mode, DiagMode::Import { unresolved_import: false, .. }))
{
let prefix =
if let DiagMode::Pattern = mode { "you might have meant to match on " } else { "" };
if let [(name, descr, source_span, note, _)] = &inaccessible_path_strings[..] {
@ -3022,10 +3023,9 @@ fn show_candidates(
err.span_note(multi_span, msg);
}
true
} else {
false
showed = true;
}
showed
}
#[derive(Debug)]

View File

@ -734,7 +734,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
&mut diag,
Some(err.span),
candidates,
DiagMode::Import { append: false },
DiagMode::Import { append: false, unresolved_import: true },
(source != target)
.then(|| format!(" as {target}"))
.as_deref()

View File

@ -106,10 +106,6 @@ fn match_candidate<'tcx>(
more_nested(selcx, &mut nested);
for nested in &mut nested {
nested.set_depth_from_parent(obligation.recursion_depth);
}
Ok(nested)
}
@ -378,10 +374,6 @@ fn evaluate_host_effect_from_selection_candiate<'tcx>(
}),
);
for nested in &mut nested {
nested.set_depth_from_parent(obligation.recursion_depth);
}
Ok(nested)
}
_ => Err(EvaluationFailure::NoSolution),

View File

@ -225,9 +225,15 @@ struct FulfillProcessor<'a, 'tcx> {
selcx: SelectionContext<'a, 'tcx>,
}
fn mk_pending<'tcx>(os: PredicateObligations<'tcx>) -> PendingPredicateObligations<'tcx> {
fn mk_pending<'tcx>(
parent: &PredicateObligation<'tcx>,
os: PredicateObligations<'tcx>,
) -> PendingPredicateObligations<'tcx> {
os.into_iter()
.map(|o| PendingPredicateObligation { obligation: o, stalled_on: vec![] })
.map(|mut o| {
o.set_depth_from_parent(parent.recursion_depth);
PendingPredicateObligation { obligation: o, stalled_on: vec![] }
})
.collect()
}
@ -341,7 +347,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
);
if predicate != obligation.predicate {
obligations.push(obligation.with(infcx.tcx, predicate));
return ProcessResult::Changed(mk_pending(obligations));
return ProcessResult::Changed(mk_pending(obligation, obligations));
}
}
let binder = obligation.predicate.kind();
@ -385,7 +391,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
let mut obligations = PredicateObligations::with_capacity(1);
obligations.push(obligation.with(infcx.tcx, pred));
ProcessResult::Changed(mk_pending(obligations))
ProcessResult::Changed(mk_pending(obligation, obligations))
}
ty::PredicateKind::Ambiguous => ProcessResult::Unchanged,
ty::PredicateKind::NormalizesTo(..) => {
@ -410,6 +416,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
let host_obligation = obligation.with(infcx.tcx, data);
self.process_host_obligation(
obligation,
host_obligation,
&mut pending_obligation.stalled_on,
)
@ -486,7 +493,10 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
// `<lhs_ty as Add<rhs_ty>>::Output` when this is an `Expr` representing
// `lhs + rhs`.
ty::ConstKind::Expr(_) => {
return ProcessResult::Changed(mk_pending(PredicateObligations::new()));
return ProcessResult::Changed(mk_pending(
obligation,
PredicateObligations::new(),
));
}
ty::ConstKind::Placeholder(_) => {
bug!("placeholder const {:?} in old solver", ct)
@ -503,7 +513,10 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
ct_ty,
ty,
) {
Ok(inf_ok) => ProcessResult::Changed(mk_pending(inf_ok.into_obligations())),
Ok(inf_ok) => ProcessResult::Changed(mk_pending(
obligation,
inf_ok.into_obligations(),
)),
Err(_) => ProcessResult::Error(FulfillmentErrorCode::Select(
SelectionError::ConstArgHasWrongType { ct, ct_ty, expected_ty: ty },
)),
@ -537,7 +550,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
vec![TyOrConstInferVar::maybe_from_generic_arg(arg).unwrap()];
ProcessResult::Unchanged
}
Some(os) => ProcessResult::Changed(mk_pending(os)),
Some(os) => ProcessResult::Changed(mk_pending(obligation, os)),
}
}
@ -553,11 +566,8 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
vec![TyOrConstInferVar::Ty(a), TyOrConstInferVar::Ty(b)];
ProcessResult::Unchanged
}
Ok(Ok(mut ok)) => {
for subobligation in &mut ok.obligations {
subobligation.set_depth_from_parent(obligation.recursion_depth);
}
ProcessResult::Changed(mk_pending(ok.obligations))
Ok(Ok(ok)) => {
ProcessResult::Changed(mk_pending(obligation, ok.obligations))
}
Ok(Err(err)) => {
let expected_found = if subtype.a_is_expected {
@ -582,7 +592,9 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
vec![TyOrConstInferVar::Ty(a), TyOrConstInferVar::Ty(b)];
ProcessResult::Unchanged
}
Ok(Ok(ok)) => ProcessResult::Changed(mk_pending(ok.obligations)),
Ok(Ok(ok)) => {
ProcessResult::Changed(mk_pending(obligation, ok.obligations))
}
Ok(Err(err)) => {
let expected_found = ExpectedFound::new(coerce.b, coerce.a);
ProcessResult::Error(FulfillmentErrorCode::Subtype(expected_found, err))
@ -645,6 +657,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
)
{
return ProcessResult::Changed(mk_pending(
obligation,
new_obligations.into_obligations(),
));
}
@ -659,6 +672,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
.eq(DefineOpaqueTypes::Yes, c1, c2)
{
return ProcessResult::Changed(mk_pending(
obligation,
new_obligations.into_obligations(),
));
}
@ -704,9 +718,10 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
c1,
c2,
) {
Ok(inf_ok) => {
ProcessResult::Changed(mk_pending(inf_ok.into_obligations()))
}
Ok(inf_ok) => ProcessResult::Changed(mk_pending(
obligation,
inf_ok.into_obligations(),
)),
Err(err) => {
ProcessResult::Error(FulfillmentErrorCode::ConstEquate(
ExpectedFound::new(c1, c2),
@ -790,7 +805,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
match self.selcx.poly_select(&trait_obligation) {
Ok(Some(impl_source)) => {
debug!("selecting trait at depth {} yielded Ok(Some)", obligation.recursion_depth);
ProcessResult::Changed(mk_pending(impl_source.nested_obligations()))
ProcessResult::Changed(mk_pending(obligation, impl_source.nested_obligations()))
}
Ok(None) => {
debug!("selecting trait at depth {} yielded Ok(None)", obligation.recursion_depth);
@ -854,7 +869,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
}
match project::poly_project_and_unify_term(&mut self.selcx, &project_obligation) {
ProjectAndUnifyResult::Holds(os) => ProcessResult::Changed(mk_pending(os)),
ProjectAndUnifyResult::Holds(os) => ProcessResult::Changed(mk_pending(obligation, os)),
ProjectAndUnifyResult::FailedNormalization => {
stalled_on.clear();
stalled_on.extend(args_infer_vars(
@ -868,7 +883,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
let mut obligations = PredicateObligations::with_capacity(1);
obligations.push(project_obligation.with(tcx, project_obligation.predicate));
ProcessResult::Changed(mk_pending(obligations))
ProcessResult::Changed(mk_pending(obligation, obligations))
}
ProjectAndUnifyResult::MismatchedProjectionTypes(e) => {
ProcessResult::Error(FulfillmentErrorCode::Project(e))
@ -878,11 +893,12 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
fn process_host_obligation(
&mut self,
obligation: &PredicateObligation<'tcx>,
host_obligation: HostEffectObligation<'tcx>,
stalled_on: &mut Vec<TyOrConstInferVar>,
) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
match effects::evaluate_host_effect_obligation(&mut self.selcx, &host_obligation) {
Ok(nested) => ProcessResult::Changed(mk_pending(nested)),
Ok(nested) => ProcessResult::Changed(mk_pending(obligation, nested)),
Err(effects::EvaluationFailure::Ambiguous) => {
stalled_on.clear();
stalled_on.extend(args_infer_vars(

View File

@ -39,7 +39,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
obligation: &PolyTraitObligation<'tcx>,
candidate: SelectionCandidate<'tcx>,
) -> Result<Selection<'tcx>, SelectionError<'tcx>> {
let mut impl_src = match candidate {
Ok(match candidate {
SizedCandidate { has_nested } => {
let data = self.confirm_builtin_candidate(obligation, has_nested);
ImplSource::Builtin(BuiltinImplSource::Misc, data)
@ -139,15 +139,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
BikeshedGuaranteedNoDropCandidate => {
self.confirm_bikeshed_guaranteed_no_drop_candidate(obligation)
}
};
// The obligations returned by confirmation are recursively evaluated
// so we need to make sure they have the correct depth.
for subobligation in impl_src.borrow_nested_obligations_mut() {
subobligation.set_depth_from_parent(obligation.recursion_depth);
}
Ok(impl_src)
})
}
fn confirm_projection_candidate(

View File

@ -2,7 +2,7 @@
//@ add-core-stubs
//@ revisions:aarch64 loongarch64 powerpc64 sparc64 x86_64
//@ min-llvm-version: 19
//@ compile-flags: -Copt-level=3 -Cno-prepopulate-passes -Zlint-llvm-ir -Cllvm-args=-lint-abort-on-error
//@ compile-flags: -Copt-level=3 -Cno-prepopulate-passes -Zlint-llvm-ir
//@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu
//@[aarch64] needs-llvm-components: arm

View File

@ -1,7 +1,7 @@
//@ add-core-stubs
//@ revisions: linux apple
//@ min-llvm-version: 19
//@ compile-flags: -Copt-level=0 -Cno-prepopulate-passes -Zlint-llvm-ir -Cllvm-args=-lint-abort-on-error
//@ compile-flags: -Copt-level=0 -Cno-prepopulate-passes -Zlint-llvm-ir
//@[linux] compile-flags: --target x86_64-unknown-linux-gnu
//@[linux] needs-llvm-components: x86

View File

@ -0,0 +1,37 @@
//@ compile-flags: -Copt-level=3
//@ only-x86_64
//@ min-llvm-version: 20
#![crate_type = "lib"]
// This test verifies that LLVM 20 properly optimizes the bounds check
// when accessing the last few elements of a slice with proper conditions.
// Previously, this would generate an unreachable branch to
// slice_start_index_len_fail even when the bounds check was provably safe.
// CHECK-LABEL: @last_four_initial(
#[no_mangle]
pub fn last_four_initial(s: &[u8]) -> &[u8] {
// Previously this would generate a branch to slice_start_index_len_fail
// that is unreachable. The LLVM 20 fix should eliminate this branch.
// CHECK-NOT: slice_start_index_len_fail
// CHECK-NOT: unreachable
let start = if s.len() <= 4 { 0 } else { s.len() - 4 };
&s[start..]
}
// CHECK-LABEL: @last_four_optimized(
#[no_mangle]
pub fn last_four_optimized(s: &[u8]) -> &[u8] {
// This version was already correctly optimized before the fix in LLVM 20.
// CHECK-NOT: slice_start_index_len_fail
// CHECK-NOT: unreachable
if s.len() <= 4 { &s[0..] } else { &s[s.len() - 4..] }
}
// Just to verify we're correctly checking for the right thing
// CHECK-LABEL: @test_bounds_check_happens(
#[no_mangle]
pub fn test_bounds_check_happens(s: &[u8], i: usize) -> &[u8] {
// CHECK: slice_start_index_len_fail
&s[i..]
}

View File

@ -1,12 +0,0 @@
//@ known-bug: #134335
//@compile-flags: -Zunstable-options --edition=2024 --crate-type=lib
pub async fn async_closure(x: &mut i32) {
let c = async move || {
*x += 1;
};
call_once(c).await;
}
fn call_once<T>(f: impl FnOnce() -> T) -> T {
f()
}

View File

@ -0,0 +1,13 @@
#[derive(Default)]
pub struct Derive;
pub struct Manual;
impl Default for Manual {
fn default() -> Self {
Self
}
}
//@ is '$.index[?(@.inner.impl.for.resolved_path.path == "Derive" && @.inner.impl.trait.path == "Default")].attrs' '["#[automatically_derived]"]'
//@ is '$.index[?(@.inner.impl.for.resolved_path.path == "Manual" && @.inner.impl.trait.path == "Default")].attrs' '[]'

View File

@ -0,0 +1,28 @@
//@ check-pass
//@ compile-flags: -Zinline-mir -Zvalidate-mir
//@ edition: 2024
// See comment below.
use std::future::Future;
use std::pin::pin;
use std::task::{Context, Waker};
fn call_once<T>(f: impl FnOnce() -> T) -> T { f() }
fn main() {
let x = async || {};
// We first inline `call_once<{async closure}>`.
//
// This gives us a future whose type is the "FnOnce" flavor of the async closure's
// child coroutine. The body of this coroutine is synthetic, which we synthesize in
// the by-move body query.
let fut = pin!(call_once(x));
// We then try to inline that body in this poll call.
//
// The inliner does some inlinability checks; one of these checks involves checking
// the body for the `#[rustc_no_mir_inline]` attribute. Since the synthetic body had
// no HIR synthesized, but it's still a local def id, we end up ICEing in the
// `local_def_id_to_hir_id` call when trying to read its attrs.
fut.poll(&mut Context::from_waker(Waker::noop()));
}

View File

@ -58,6 +58,11 @@ error[E0425]: cannot find function `import` in this scope
LL | import();
| ^^^^^^ not found in this scope
|
note: function `bar::import` exists but is inaccessible
--> $DIR/glob-resolve1.rs:7:5
|
LL | fn fpriv() {}
| ^^^^^^^^^^ not accessible
help: consider importing this function
|
LL + use other::import;

View File

@ -16,6 +16,11 @@ error[E0423]: expected function, found module `foo`
LL | foo();
| ^^^ not a function
|
note: function `m1::foo` exists but is inaccessible
--> $DIR/issue-4366-2.rs:21:5
|
LL | fn foo() {}
| ^^^^^^^^ not accessible
help: consider importing this function instead
|
LL + use foo::foo;

View File

@ -4,6 +4,11 @@ error[E0425]: cannot find function `foo` in this scope
LL | fn sub() -> isize { foo(); 1 }
| ^^^ not found in this scope
|
note: function `m1::foo` exists but is inaccessible
--> $DIR/issue-4366.rs:23:5
|
LL | fn foo() {}
| ^^^^^^^^ not accessible
help: consider importing this function
|
LL + use foo::foo;

View File

@ -0,0 +1,19 @@
pub mod one {
mod foo {
pub struct Foo;
}
pub use self::foo::Foo;
}
pub mod two {
mod foo {
mod bar {
pub struct Foo;
}
}
pub use crate::two::foo::Foo; //~ ERROR unresolved import `crate::two::foo::Foo` [E0432]
}
fn main() {}

View File

@ -0,0 +1,20 @@
error[E0432]: unresolved import `crate::two::foo::Foo`
--> $DIR/show-private-items-issue-138626.rs:16:13
|
LL | pub use crate::two::foo::Foo;
| ^^^^^^^^^^^^^^^^^^^^ no `Foo` in `two::foo`
|
note: struct `two::foo::bar::Foo` exists but is inaccessible
--> $DIR/show-private-items-issue-138626.rs:12:13
|
LL | pub struct Foo;
| ^^^^^^^^^^^^^^^ not accessible
help: consider importing this struct through its public re-export instead
|
LL - pub use crate::two::foo::Foo;
LL + pub use one::Foo;
|
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0432`.

View File

@ -1,8 +1,8 @@
error[E0275]: overflow assigning `Box<_>` to `_`
--> $DIR/infinite-autoderef.rs:16:13
--> $DIR/infinite-autoderef.rs:16:22
|
LL | x = Box::new(x);
| ^^^^^^^^^^^
| ^
error: aborting due to 1 previous error

View File

@ -4,6 +4,6 @@ fn main() {
let g;
g = f;
f = Box::new(g);
//~^ ERROR overflow assigning `Box<_>` to `_`
f = Box::new(g);
}

View File

@ -1,8 +1,8 @@
error[E0275]: overflow assigning `Box<_>` to `_`
--> $DIR/occurs-check-2.rs:7:9
--> $DIR/occurs-check-2.rs:6:9
|
LL | f = Box::new(g);
| ^^^^^^^^^^^
LL | g = f;
| ^
error: aborting due to 1 previous error

View File

@ -1,8 +1,8 @@
error[E0275]: overflow assigning `Clam<_>` to `_`
--> $DIR/occurs-check-3.rs:6:9
--> $DIR/occurs-check-3.rs:6:17
|
LL | c = Clam::A(c);
| ^^^^^^^^^^
| ^
error: aborting due to 1 previous error

View File

@ -1,8 +1,8 @@
error[E0275]: overflow assigning `Box<_>` to `_`
--> $DIR/occurs-check.rs:3:9
--> $DIR/occurs-check.rs:3:18
|
LL | f = Box::new(f);
| ^^^^^^^^^^^
| ^
error: aborting due to 1 previous error

View File

@ -7,6 +7,14 @@ LL | pub struct Baz;
LL | Bar();
| ^^^
|
note: these functions exist but are inaccessible
--> $DIR/privacy-ns1.rs:14:5
|
LL | fn Bar() { }
| ^^^^^^^^ `foo1::Bar`: not accessible
...
LL | fn Bar() { }
| ^^^^^^^^ `foo3::Bar`: not accessible
help: a unit struct with a similar name exists
|
LL - Bar();
@ -26,6 +34,14 @@ LL | pub struct Baz;
LL | Bar();
| ^^^
|
note: these functions exist but are inaccessible
--> $DIR/privacy-ns1.rs:14:5
|
LL | fn Bar() { }
| ^^^^^^^^ `foo1::Bar`: not accessible
...
LL | fn Bar() { }
| ^^^^^^^^ `foo3::Bar`: not accessible
help: a unit struct with a similar name exists
|
LL - Bar();
@ -45,6 +61,14 @@ LL | pub struct Baz;
LL | let _x: Box<Bar>;
| ^^^
|
note: these traits exist but are inaccessible
--> $DIR/privacy-ns1.rs:25:5
|
LL | trait Bar {
| ^^^^^^^^^ `foo2::Bar`: not accessible
...
LL | trait Bar {
| ^^^^^^^^^ `foo3::Bar`: not accessible
help: a struct with a similar name exists
|
LL - let _x: Box<Bar>;

View File

@ -4,6 +4,14 @@ error[E0423]: expected function, tuple struct or tuple variant, found trait `Bar
LL | Bar();
| ^^^ not a function, tuple struct or tuple variant
|
note: these functions exist but are inaccessible
--> $DIR/privacy-ns2.rs:14:5
|
LL | fn Bar() { }
| ^^^^^^^^ `foo1::Bar`: not accessible
...
LL | fn Bar() { }
| ^^^^^^^^ `foo3::Bar`: not accessible
help: consider importing this function instead
|
LL + use foo2::Bar;
@ -18,6 +26,14 @@ LL | pub struct Baz;
LL | Bar();
| ^^^
|
note: these functions exist but are inaccessible
--> $DIR/privacy-ns2.rs:14:5
|
LL | fn Bar() { }
| ^^^^^^^^ `foo1::Bar`: not accessible
...
LL | fn Bar() { }
| ^^^^^^^^ `foo3::Bar`: not accessible
help: a unit struct with a similar name exists
|
LL - Bar();
@ -34,6 +50,14 @@ error[E0573]: expected type, found function `Bar`
LL | let _x : Bar();
| ^^^^^ not a type
|
note: these traits exist but are inaccessible
--> $DIR/privacy-ns2.rs:31:5
|
LL | trait Bar {
| ^^^^^^^^^ `foo2::Bar`: not accessible
...
LL | trait Bar {
| ^^^^^^^^^ `foo3::Bar`: not accessible
help: use `=` if you meant to assign
|
LL - let _x : Bar();

View File

@ -19,6 +19,17 @@ error[E0412]: cannot find type `Mul` in this scope
LL | fn getMul() -> Mul {
| ^^^ not found in this scope
|
note: these items exist but are inaccessible
--> $DIR/issue-21221-1.rs:10:5
|
LL | enum Mul {
| ^^^^^^^^ `mul3::Mul`: not accessible
...
LL | type Mul = String;
| ^^^^^^^^^^^^^^^^^^ `mul4::Mul`: not accessible
...
LL | struct Mul{
| ^^^^^^^^^^ `mul5::Mul`: not accessible
help: consider importing one of these traits
|
LL + use std::ops::Mul;

View File

@ -2,7 +2,7 @@ error[E0275]: overflow assigning `_` to `Option<_>`
--> $DIR/mutual-recursion-issue-75860.rs:9:33
|
LL | let left = |o_a: Option<_>| o_a.unwrap();
| ^^^
| ^^^^^^^^^^^^
error: aborting due to 1 previous error

View File

@ -1,9 +1,10 @@
#![feature(type_alias_impl_trait)]
//@ known-bug: #109268
type Foo = impl Fn() -> Foo;
#[define_opaque(Foo)]
fn crash(x: Foo) -> Foo {
//~^ ERROR overflow evaluating the requirement `<Foo as FnOnce<()>>::Output == Foo`
x
}

View File

@ -1,10 +1,9 @@
error: unconstrained opaque type
--> $DIR/type-alias-impl-trait-with-cycle-error-1.rs:4:12
error[E0275]: overflow evaluating the requirement `<Foo as FnOnce<()>>::Output == Foo`
--> $DIR/type-alias-impl-trait-with-cycle-error-1.rs:6:21
|
LL | type Foo = impl Fn() -> Foo;
| ^^^^^^^^^^^^^^^^
|
= note: `Foo` must be used in combination with a concrete type within the same crate
LL | fn crash(x: Foo) -> Foo {
| ^^^
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0275`.

View File

@ -1,13 +1,13 @@
#![feature(type_alias_impl_trait)]
//@ known-bug: #109268
pub trait Bar<T> {
type Item;
}
type Foo = impl Bar<Foo, Item = Foo>;
#[define_opaque(Foo)]
fn crash(x: Foo) -> Foo {
//~^ ERROR overflow evaluating the requirement `<Foo as Bar<Foo>>::Item == Foo`
x
}

View File

@ -1,10 +1,9 @@
error: unconstrained opaque type
--> $DIR/type-alias-impl-trait-with-cycle-error-2.rs:8:12
error[E0275]: overflow evaluating the requirement `<Foo as Bar<Foo>>::Item == Foo`
--> $DIR/type-alias-impl-trait-with-cycle-error-2.rs:9:21
|
LL | type Foo = impl Bar<Foo, Item = Foo>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `Foo` must be used in combination with a concrete type within the same crate
LL | fn crash(x: Foo) -> Foo {
| ^^^
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0275`.

View File

@ -1,9 +1,9 @@
#![feature(type_alias_impl_trait)]
//@ known-bug: #109268
type Foo<'a> = impl Fn() -> Foo<'a>;
#[define_opaque(Foo)]
fn crash<'a>(_: &'a (), x: Foo<'a>) -> Foo<'a> {
//~^ ERROR overflow evaluating the requirement `<Foo<'_> as FnOnce<()>>::Output == Foo<'a>`
x
}

View File

@ -1,10 +1,9 @@
error: unconstrained opaque type
--> $DIR/type-alias-impl-trait-with-cycle-error-3.rs:4:16
error[E0275]: overflow evaluating the requirement `<Foo<'_> as FnOnce<()>>::Output == Foo<'a>`
--> $DIR/type-alias-impl-trait-with-cycle-error-3.rs:5:40
|
LL | type Foo<'a> = impl Fn() -> Foo<'a>;
| ^^^^^^^^^^^^^^^^^^^^
|
= note: `Foo` must be used in combination with a concrete type within the same crate
LL | fn crash<'a>(_: &'a (), x: Foo<'a>) -> Foo<'a> {
| ^^^^^^^
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0275`.

View File

@ -31,6 +31,8 @@ mod food {
mod zug {
pub mod baz {
//~^ NOTE module `food::zug::baz` exists but is inaccessible
//~| NOTE not accessible
pub struct Foobar;
}
}

View File

@ -26,6 +26,12 @@ LL | use food::baz;
| | |
| | help: a similar name exists in the module: `bag`
| no `baz` in `food`
|
note: module `food::zug::baz` exists but is inaccessible
--> $DIR/unresolved-import.rs:33:9
|
LL | pub mod baz {
| ^^^^^^^^^^^ not accessible
error[E0432]: unresolved import `food::beens`
--> $DIR/unresolved-import.rs:19:12
@ -37,13 +43,13 @@ LL | use food::{beens as Foo};
| help: a similar name exists in the module: `beans`
error[E0432]: unresolved import `MyEnum`
--> $DIR/unresolved-import.rs:44:9
--> $DIR/unresolved-import.rs:46:9
|
LL | use MyEnum::*;
| ^^^^^^ help: a similar path exists: `self::MyEnum`
error[E0432]: unresolved import `Enum`
--> $DIR/unresolved-import.rs:55:9
--> $DIR/unresolved-import.rs:57:9
|
LL | use Enum::*;
| ^^^^ help: a similar path exists: `self::Enum`