Skip to content

Commit 71f4439

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

22 files changed

+199
-52
lines changed

compiler/rustc_error_codes/src/error_codes/E0517.md

+12-7
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

+7
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

+5-3
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

+39-21
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

-5
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

+2-1
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

+14-2
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

+10-3
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

+1-1
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

+1-1
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

tests/crashes/126896.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//@ known-bug: rust-lang/rust#126896
2-
//@ compile-flags: -Zpolymorphize=on -Zinline-mir=yes
2+
//@ compile-flags: -Zvalidate-mir -Zinline-mir=yes
33

44
#![feature(type_alias_impl_trait)]
55
type Two<'a, 'b> = impl std::fmt::Debug;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//@ edition: 2021
2+
3+
#![feature(async_closure, target_feature_11)]
4+
// `target_feature_11` just to test safe functions w/ target features.
5+
6+
use std::pin::Pin;
7+
use std::future::Future;
8+
9+
unsafe extern "Rust" {
10+
pub unsafe fn unsafety() -> Pin<Box<dyn Future<Output = ()> + 'static>>;
11+
}
12+
13+
unsafe extern "C" {
14+
pub safe fn abi() -> Pin<Box<dyn Future<Output = ()> + 'static>>;
15+
}
16+
17+
18+
#[target_feature(enable = "sse2")]
19+
fn target_feature() -> Pin<Box<dyn Future<Output = ()> + 'static>> { todo!() }
20+
21+
fn test(f: impl async Fn()) {}
22+
23+
fn main() {
24+
test(unsafety); //~ ERROR the trait bound
25+
test(abi); //~ ERROR the trait bound
26+
test(target_feature); //~ ERROR the trait bound
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
error[E0277]: the trait bound `unsafe fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {unsafety}: AsyncFn<()>` is not satisfied
2+
--> $DIR/fn-exception.rs:24:10
3+
|
4+
LL | test(unsafety);
5+
| ---- ^^^^^^^^ the trait `AsyncFn<()>` is not implemented for fn item `unsafe fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {unsafety}`
6+
| |
7+
| required by a bound introduced by this call
8+
|
9+
note: required by a bound in `test`
10+
--> $DIR/fn-exception.rs:21:17
11+
|
12+
LL | fn test(f: impl async Fn()) {}
13+
| ^^^^^^^^^^ required by this bound in `test`
14+
15+
error[E0277]: the trait bound `extern "C" fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {abi}: AsyncFn<()>` is not satisfied
16+
--> $DIR/fn-exception.rs:25:10
17+
|
18+
LL | test(abi);
19+
| ---- ^^^ the trait `AsyncFn<()>` is not implemented for fn item `extern "C" fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {abi}`
20+
| |
21+
| required by a bound introduced by this call
22+
|
23+
note: required by a bound in `test`
24+
--> $DIR/fn-exception.rs:21:17
25+
|
26+
LL | fn test(f: impl async Fn()) {}
27+
| ^^^^^^^^^^ required by this bound in `test`
28+
29+
error[E0277]: the trait bound `fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {target_feature}: AsyncFn<()>` is not satisfied
30+
--> $DIR/fn-exception.rs:26:10
31+
|
32+
LL | test(target_feature);
33+
| ---- ^^^^^^^^^^^^^^ the trait `AsyncFn<()>` is not implemented for fn item `fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {target_feature}`
34+
| |
35+
| required by a bound introduced by this call
36+
|
37+
note: required by a bound in `test`
38+
--> $DIR/fn-exception.rs:21:17
39+
|
40+
LL | fn test(f: impl async Fn()) {}
41+
| ^^^^^^^^^^ required by this bound in `test`
42+
43+
error: aborting due to 3 previous errors
44+
45+
For more information about this error, try `rustc --explain E0277`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Test for ICE: cannot convert ReLateParam to a region vid
2+
// https://github.com/rust-lang/rust/issues/125873
3+
4+
#![feature(closure_lifetime_binder)]
5+
fn foo() {
6+
let a = for<'a> |b: &'a ()| -> &'a () {
7+
const {
8+
let awd = ();
9+
let _: &'a () = &awd;
10+
//~^ `awd` does not live long enough
11+
};
12+
b
13+
};
14+
}
15+
16+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error[E0597]: `awd` does not live long enough
2+
--> $DIR/using-late-bound-from-closure.rs:9:29
3+
|
4+
LL | let a = for<'a> |b: &'a ()| -> &'a () {
5+
| -- lifetime `'a` defined here
6+
LL | const {
7+
LL | let awd = ();
8+
| --- binding `awd` declared here
9+
LL | let _: &'a () = &awd;
10+
| ------ ^^^^ borrowed value does not live long enough
11+
| |
12+
| type annotation requires that `awd` is borrowed for `'a`
13+
LL |
14+
LL | };
15+
| - `awd` dropped here while still borrowed
16+
17+
error: aborting due to 1 previous error
18+
19+
For more information about this error, try `rustc --explain E0597`.

tests/ui/lint/command-line-lint-group-forbid.stderr

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ LL | let _InappropriateCamelCasing = true;
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `_inappropriate_camel_casing`
66
|
77
= note: `-F non-snake-case` implied by `-F bad-style`
8-
= help: to override `-F bad-style` add `#[allow(non_snake_case)]`
98

109
error: aborting due to 1 previous error
1110

tests/ui/lint/force-warn/cap-lints-warn-allowed-warn-by-default-lint.stderr

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ LL | 0...100 => true,
77
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
88
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
99
= note: `--force-warn ellipsis-inclusive-range-patterns` implied by `--force-warn rust-2021-compatibility`
10-
= help: to override `--force-warn rust-2021-compatibility` add `#[allow(ellipsis_inclusive_range_patterns)]`
1110

1211
warning: 1 warning emitted
1312

tests/ui/lint/force-warn/lint-group-allow-warnings.stderr

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ LL | pub fn FUNCTION() {}
55
| ^^^^^^^^ help: convert the identifier to snake case: `function`
66
|
77
= note: `--force-warn non-snake-case` implied by `--force-warn nonstandard-style`
8-
= help: to override `--force-warn nonstandard-style` add `#[allow(non_snake_case)]`
98

109
warning: 1 warning emitted
1110

tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
77
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
88
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
99
= note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
10-
= help: to override `--force-warn rust-2018-idioms` add `#[allow(bare_trait_objects)]`
1110
help: if this is an object-safe trait, use `dyn`
1211
|
1312
LL | pub fn function(_x: Box<dyn SomeTrait>) {}

tests/ui/lint/force-warn/lint-group-allowed-lint-group.stderr

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
77
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
88
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
99
= note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
10-
= help: to override `--force-warn rust-2018-idioms` add `#[allow(bare_trait_objects)]`
1110
help: if this is an object-safe trait, use `dyn`
1211
|
1312
LL | pub fn function(_x: Box<dyn SomeTrait>) {}

tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
77
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
88
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
99
= note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
10-
= help: to override `--force-warn rust-2018-idioms` add `#[allow(bare_trait_objects)]`
1110
help: if this is an object-safe trait, use `dyn`
1211
|
1312
LL | pub fn function(_x: Box<dyn SomeTrait>) {}

0 commit comments

Comments
 (0)