Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 71f4439

Browse files
committed
Auto merge of rust-lang#128829 - matthiaskrgr:rollup-kbkjllg, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - rust-lang#128306 (Update NonNull::align_offset quarantees) - rust-lang#128612 (Make `validate_mir` ensure the final MIR for all bodies) - rust-lang#128648 (Add regression test) - rust-lang#128791 (Don't implement `AsyncFn` for `FnDef`/`FnPtr` that wouldnt implement `Fn`) - rust-lang#128795 (Update E0517 message to reflect RFC 2195.) - rust-lang#128825 (rm `declared_features` field in resolver) - rust-lang#128826 (Only suggest `#[allow]` for `--warn` and `--deny` lint level flags) r? `@ghost` `@rustbot` modify labels: rollup
2 parents d3a3939 + f92c323 commit 71f4439

File tree

22 files changed

+199
-52
lines changed

22 files changed

+199
-52
lines changed

compiler/rustc_error_codes/src/error_codes/E0517.md

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,17 @@ impl Foo {
2525
These attributes do not work on typedefs, since typedefs are just aliases.
2626

2727
Representations like `#[repr(u8)]`, `#[repr(i64)]` are for selecting the
28-
discriminant size for enums with no data fields on any of the variants, e.g.
29-
`enum Color {Red, Blue, Green}`, effectively setting the size of the enum to
30-
the size of the provided type. Such an enum can be cast to a value of the same
31-
type as well. In short, `#[repr(u8)]` makes the enum behave like an integer
32-
with a constrained set of allowed values.
28+
discriminant size for enums. For enums with no data fields on any of the
29+
variants, e.g. `enum Color {Red, Blue, Green}`, this effectively sets the size
30+
of the enum to the size of the provided type. Such an enum can be cast to a
31+
value of the same type as well. In short, `#[repr(u8)]` makes a field-less enum
32+
behave like an integer with a constrained set of allowed values.
3333

34-
Only field-less enums can be cast to numerical primitives, so this attribute
35-
will not apply to structs.
34+
For a description of how `#[repr(C)]` and representations like `#[repr(u8)]`
35+
affect the layout of enums with data fields, see [RFC 2195][rfc2195].
36+
37+
Only field-less enums can be cast to numerical primitives. Representations like
38+
`#[repr(u8)]` will not apply to structs.
3639

3740
`#[repr(packed)]` reduces padding to make the struct size smaller. The
3841
representation of enums isn't strictly defined in Rust, and this attribute
@@ -42,3 +45,5 @@ won't work on enums.
4245
types (i.e., `u8`, `i32`, etc) a representation that permits vectorization via
4346
SIMD. This doesn't make much sense for enums since they don't consist of a
4447
single list of data.
48+
49+
[rfc2195]: https://github.com/rust-lang/rfcs/blob/master/text/2195-really-tagged-unions.md

compiler/rustc_interface/src/passes.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,13 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
818818
});
819819
sess.time("layout_testing", || layout_test::test_layout(tcx));
820820
sess.time("abi_testing", || abi_test::test_abi(tcx));
821+
if tcx.sess.opts.unstable_opts.validate_mir {
822+
sess.time("ensuring_optimized_MIR_is_computable", || {
823+
tcx.hir().par_body_owners(|def_id| {
824+
tcx.instance_mir(ty::InstanceKind::Item(def_id.into()));
825+
});
826+
});
827+
}
821828
}
822829

823830
/// Runs the type-checking, region checking and other miscellaneous analysis

compiler/rustc_middle/src/lint.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -228,9 +228,11 @@ pub fn explain_lint_level_source(
228228
err.note_once(format!(
229229
"`{flag} {hyphen_case_lint_name}` implied by `{flag} {hyphen_case_flag_val}`"
230230
));
231-
err.help_once(format!(
232-
"to override `{flag} {hyphen_case_flag_val}` add `#[allow({name})]`"
233-
));
231+
if matches!(orig_level, Level::Warn | Level::Deny) {
232+
err.help_once(format!(
233+
"to override `{flag} {hyphen_case_flag_val}` add `#[allow({name})]`"
234+
));
235+
}
234236
}
235237
}
236238
LintLevelSource::Node { name: lint_attr_name, span, reason, .. } => {

compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -458,28 +458,23 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
458458
))
459459
}
460460

461-
ty::FnDef(..) | ty::FnPtr(..) => {
462-
let bound_sig = self_ty.fn_sig(cx);
463-
let sig = bound_sig.skip_binder();
464-
let future_trait_def_id = cx.require_lang_item(TraitSolverLangItem::Future);
465-
// `FnDef` and `FnPtr` only implement `AsyncFn*` when their
466-
// return type implements `Future`.
467-
let nested = vec![
468-
bound_sig
469-
.rebind(ty::TraitRef::new(cx, future_trait_def_id, [sig.output()]))
470-
.upcast(cx),
471-
];
472-
let future_output_def_id = cx.require_lang_item(TraitSolverLangItem::FutureOutput);
473-
let future_output_ty = Ty::new_projection(cx, future_output_def_id, [sig.output()]);
474-
Ok((
475-
bound_sig.rebind(AsyncCallableRelevantTypes {
476-
tupled_inputs_ty: Ty::new_tup(cx, sig.inputs().as_slice()),
477-
output_coroutine_ty: sig.output(),
478-
coroutine_return_ty: future_output_ty,
479-
}),
480-
nested,
481-
))
461+
ty::FnDef(def_id, _) => {
462+
let sig = self_ty.fn_sig(cx);
463+
if sig.skip_binder().is_fn_trait_compatible() && !cx.has_target_features(def_id) {
464+
fn_item_to_async_callable(cx, sig)
465+
} else {
466+
Err(NoSolution)
467+
}
468+
}
469+
ty::FnPtr(..) => {
470+
let sig = self_ty.fn_sig(cx);
471+
if sig.skip_binder().is_fn_trait_compatible() {
472+
fn_item_to_async_callable(cx, sig)
473+
} else {
474+
Err(NoSolution)
475+
}
482476
}
477+
483478
ty::Closure(_, args) => {
484479
let args = args.as_closure();
485480
let bound_sig = args.sig();
@@ -563,6 +558,29 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
563558
}
564559
}
565560

561+
fn fn_item_to_async_callable<I: Interner>(
562+
cx: I,
563+
bound_sig: ty::Binder<I, ty::FnSig<I>>,
564+
) -> Result<(ty::Binder<I, AsyncCallableRelevantTypes<I>>, Vec<I::Predicate>), NoSolution> {
565+
let sig = bound_sig.skip_binder();
566+
let future_trait_def_id = cx.require_lang_item(TraitSolverLangItem::Future);
567+
// `FnDef` and `FnPtr` only implement `AsyncFn*` when their
568+
// return type implements `Future`.
569+
let nested = vec![
570+
bound_sig.rebind(ty::TraitRef::new(cx, future_trait_def_id, [sig.output()])).upcast(cx),
571+
];
572+
let future_output_def_id = cx.require_lang_item(TraitSolverLangItem::FutureOutput);
573+
let future_output_ty = Ty::new_projection(cx, future_output_def_id, [sig.output()]);
574+
Ok((
575+
bound_sig.rebind(AsyncCallableRelevantTypes {
576+
tupled_inputs_ty: Ty::new_tup(cx, sig.inputs().as_slice()),
577+
output_coroutine_ty: sig.output(),
578+
coroutine_return_ty: future_output_ty,
579+
}),
580+
nested,
581+
))
582+
}
583+
566584
/// Given a coroutine-closure, project to its returned coroutine when we are *certain*
567585
/// that the closure's kind is compatible with the goal.
568586
fn coroutine_closure_to_certain_coroutine<I: Interner>(

compiler/rustc_resolve/src/lib.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,9 +1129,6 @@ pub struct Resolver<'a, 'tcx> {
11291129
/// Also includes of list of each fields visibility
11301130
struct_constructors: LocalDefIdMap<(Res, ty::Visibility<DefId>, Vec<ty::Visibility<DefId>>)>,
11311131

1132-
/// Features declared for this crate.
1133-
declared_features: FxHashSet<Symbol>,
1134-
11351132
lint_buffer: LintBuffer,
11361133

11371134
next_node_id: NodeId,
@@ -1402,7 +1399,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
14021399

14031400
let registered_tools = tcx.registered_tools(());
14041401

1405-
let features = tcx.features();
14061402
let pub_vis = ty::Visibility::<DefId>::Public;
14071403
let edition = tcx.sess.edition();
14081404

@@ -1506,7 +1502,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
15061502
multi_segment_macro_resolutions: Default::default(),
15071503
builtin_attrs: Default::default(),
15081504
containers_deriving_copy: Default::default(),
1509-
declared_features: features.declared_features.clone(),
15101505
lint_buffer: LintBuffer::default(),
15111506
next_node_id: CRATE_NODE_ID,
15121507
node_id_to_def_id,

compiler/rustc_resolve/src/macros.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1001,7 +1001,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
10011001
let feature = stability.feature;
10021002

10031003
let is_allowed = |feature| {
1004-
self.declared_features.contains(&feature) || span.allows_unstable(feature)
1004+
self.tcx.features().declared_features.contains(&feature)
1005+
|| span.allows_unstable(feature)
10051006
};
10061007
let allowed_by_implication = implied_by.is_some_and(|feature| is_allowed(feature));
10071008
if !is_allowed(feature) && !allowed_by_implication {

compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -467,8 +467,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
467467
}
468468
candidates.vec.push(AsyncClosureCandidate);
469469
}
470-
ty::FnDef(..) | ty::FnPtr(..) => {
471-
candidates.vec.push(AsyncClosureCandidate);
470+
// Provide an impl, but only for suitable `fn` pointers.
471+
ty::FnPtr(sig) => {
472+
if sig.is_fn_trait_compatible() {
473+
candidates.vec.push(AsyncClosureCandidate);
474+
}
475+
}
476+
// Provide an impl for suitable functions, rejecting `#[target_feature]` functions (RFC 2396).
477+
ty::FnDef(def_id, _) => {
478+
let tcx = self.tcx();
479+
if tcx.fn_sig(def_id).skip_binder().is_fn_trait_compatible()
480+
&& tcx.codegen_fn_attrs(def_id).target_features.is_empty()
481+
{
482+
candidates.vec.push(AsyncClosureCandidate);
483+
}
472484
}
473485
_ => {}
474486
}

library/core/src/ptr/non_null.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,16 +1169,23 @@ impl<T: ?Sized> NonNull<T> {
11691169
/// `align`.
11701170
///
11711171
/// If it is not possible to align the pointer, the implementation returns
1172-
/// `usize::MAX`. It is permissible for the implementation to *always*
1173-
/// return `usize::MAX`. Only your algorithm's performance can depend
1174-
/// on getting a usable offset here, not its correctness.
1172+
/// `usize::MAX`.
11751173
///
11761174
/// The offset is expressed in number of `T` elements, and not bytes.
11771175
///
11781176
/// There are no guarantees whatsoever that offsetting the pointer will not overflow or go
11791177
/// beyond the allocation that the pointer points into. It is up to the caller to ensure that
11801178
/// the returned offset is correct in all terms other than alignment.
11811179
///
1180+
/// When this is called during compile-time evaluation (which is unstable), the implementation
1181+
/// may return `usize::MAX` in cases where that can never happen at runtime. This is because the
1182+
/// actual alignment of pointers is not known yet during compile-time, so an offset with
1183+
/// guaranteed alignment can sometimes not be computed. For example, a buffer declared as `[u8;
1184+
/// N]` might be allocated at an odd or an even address, but at compile-time this is not yet
1185+
/// known, so the execution has to be correct for either choice. It is therefore impossible to
1186+
/// find an offset that is guaranteed to be 2-aligned. (This behavior is subject to change, as usual
1187+
/// for unstable APIs.)
1188+
///
11821189
/// # Panics
11831190
///
11841191
/// The function panics if `align` is not a power-of-two.

tests/crashes/121127.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//@ known-bug: #121127
2-
//@ compile-flags: -Zpolymorphize=on -Zinline-mir=yes -C debuginfo=2
2+
//@ compile-flags: -Zvalidate-mir -Zinline-mir=yes -C debuginfo=2
33
// Note that as of PR#123949 this only crashes with debuginfo enabled
44

55
#![feature(specialization)]

tests/crashes/122909.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//@ compile-flags: -Zpolymorphize=on -Zinline-mir=yes
1+
//@ compile-flags: -Zvalidate-mir -Zinline-mir=yes
22
//@ known-bug: #122909
33

44

0 commit comments

Comments
 (0)