Skip to content

Commit e30daf3

Browse files
committed
Auto merge of rust-lang#140269 - cuviper:beta-next, r=cuviper
[beta] backports - Do not mix normalized and unnormalized caller bounds when constructing param-env for `receiver_is_dispatchable` rust-lang#138941 - Ignore zero-sized types in wasm future-compat warning rust-lang#139498 - Don't warn about `v128` in wasm ABI transition rust-lang#139809 - Revert overzealous parse recovery for single colons in paths rust-lang#140228 r? cuviper
2 parents 386abeb + 7ef0050 commit e30daf3

17 files changed

+193
-145
lines changed

compiler/rustc_monomorphize/src/mono_checks/abi_check.rs

+11
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ fn wasm_abi_safe<'tcx>(tcx: TyCtxt<'tcx>, arg: &ArgAbi<'tcx, Ty<'tcx>>) -> bool
9999
return true;
100100
}
101101

102+
// Both the old and the new ABIs treat vector types like `v128` the same
103+
// way.
104+
if uses_vector_registers(&arg.mode, &arg.layout.backend_repr) {
105+
return true;
106+
}
107+
102108
// This matches `unwrap_trivial_aggregate` in the wasm ABI logic.
103109
if arg.layout.is_aggregate() {
104110
let cx = LayoutCx::new(tcx, TypingEnv::fully_monomorphized());
@@ -111,6 +117,11 @@ fn wasm_abi_safe<'tcx>(tcx: TyCtxt<'tcx>, arg: &ArgAbi<'tcx, Ty<'tcx>>) -> bool
111117
}
112118
}
113119

120+
// Zero-sized types are dropped in both ABIs, so they're safe
121+
if arg.layout.is_zst() {
122+
return true;
123+
}
124+
114125
false
115126
}
116127

compiler/rustc_parse/src/parser/item.rs

+11
Original file line numberDiff line numberDiff line change
@@ -2066,6 +2066,17 @@ impl<'a> Parser<'a> {
20662066
}
20672067
self.expect_field_ty_separator()?;
20682068
let ty = self.parse_ty()?;
2069+
if self.token == token::Colon && self.look_ahead(1, |t| *t != token::Colon) {
2070+
self.dcx()
2071+
.struct_span_err(self.token.span, "found single colon in a struct field type path")
2072+
.with_span_suggestion_verbose(
2073+
self.token.span,
2074+
"write a path separator here",
2075+
"::",
2076+
Applicability::MaybeIncorrect,
2077+
)
2078+
.emit();
2079+
}
20692080
let default = if self.token == token::Eq {
20702081
self.bump();
20712082
let const_expr = self.parse_expr_anon_const()?;

compiler/rustc_parse/src/parser/path.rs

+7-13
Original file line numberDiff line numberDiff line change
@@ -248,19 +248,13 @@ impl<'a> Parser<'a> {
248248
segments.push(segment);
249249

250250
if self.is_import_coupler() || !self.eat_path_sep() {
251-
let ok_for_recovery = self.may_recover()
252-
&& match style {
253-
PathStyle::Expr => true,
254-
PathStyle::Type if let Some((ident, _)) = self.prev_token.ident() => {
255-
self.token == token::Colon
256-
&& ident.as_str().chars().all(|c| c.is_lowercase())
257-
&& self.token.span.lo() == self.prev_token.span.hi()
258-
&& self
259-
.look_ahead(1, |token| self.token.span.hi() == token.span.lo())
260-
}
261-
_ => false,
262-
};
263-
if ok_for_recovery
251+
// IMPORTANT: We can *only ever* treat single colons as typo'ed double colons in
252+
// expression contexts (!) since only there paths cannot possibly be followed by
253+
// a colon and still form a syntactically valid construct. In pattern contexts,
254+
// a path may be followed by a type annotation. E.g., `let pat:ty`. In type
255+
// contexts, a path may be followed by a list of bounds. E.g., `where ty:bound`.
256+
if self.may_recover()
257+
&& style == PathStyle::Expr // (!)
264258
&& self.token == token::Colon
265259
&& self.look_ahead(1, |token| token.is_ident() && !token.is_reserved_ident())
266260
{

compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs

+22-13
Original file line numberDiff line numberDiff line change
@@ -583,27 +583,36 @@ fn receiver_is_dispatchable<'tcx>(
583583
// create a modified param env, with `Self: Unsize<U>` and `U: Trait` (and all of
584584
// its supertraits) added to caller bounds. `U: ?Sized` is already implied here.
585585
let param_env = {
586-
let param_env = tcx.param_env(method.def_id);
586+
// N.B. We generally want to emulate the construction of the `unnormalized_param_env`
587+
// in the param-env query here. The fact that we don't just start with the clauses
588+
// in the param-env of the method is because those are already normalized, and mixing
589+
// normalized and unnormalized copies of predicates in `normalize_param_env_or_error`
590+
// will cause ambiguity that the user can't really avoid.
591+
//
592+
// We leave out certain complexities of the param-env query here. Specifically, we:
593+
// 1. Do not add `~const` bounds since there are no `dyn const Trait`s.
594+
// 2. Do not add RPITIT self projection bounds for defaulted methods, since we
595+
// are not constructing a param-env for "inside" of the body of the defaulted
596+
// method, so we don't really care about projecting to a specific RPIT type,
597+
// and because RPITITs are not dyn compatible (yet).
598+
let mut predicates = tcx.predicates_of(method.def_id).instantiate_identity(tcx).predicates;
587599

588600
// Self: Unsize<U>
589601
let unsize_predicate =
590-
ty::TraitRef::new(tcx, unsize_did, [tcx.types.self_param, unsized_self_ty]).upcast(tcx);
602+
ty::TraitRef::new(tcx, unsize_did, [tcx.types.self_param, unsized_self_ty]);
603+
predicates.push(unsize_predicate.upcast(tcx));
591604

592605
// U: Trait<Arg1, ..., ArgN>
593-
let trait_predicate = {
594-
let trait_def_id = method.trait_container(tcx).unwrap();
595-
let args = GenericArgs::for_item(tcx, trait_def_id, |param, _| {
596-
if param.index == 0 { unsized_self_ty.into() } else { tcx.mk_param_from_def(param) }
597-
});
598-
599-
ty::TraitRef::new_from_args(tcx, trait_def_id, args).upcast(tcx)
600-
};
606+
let trait_def_id = method.trait_container(tcx).unwrap();
607+
let args = GenericArgs::for_item(tcx, trait_def_id, |param, _| {
608+
if param.index == 0 { unsized_self_ty.into() } else { tcx.mk_param_from_def(param) }
609+
});
610+
let trait_predicate = ty::TraitRef::new_from_args(tcx, trait_def_id, args);
611+
predicates.push(trait_predicate.upcast(tcx));
601612

602613
normalize_param_env_or_error(
603614
tcx,
604-
ty::ParamEnv::new(tcx.mk_clauses_from_iter(
605-
param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]),
606-
)),
615+
ty::ParamEnv::new(tcx.mk_clauses(&predicates)),
607616
ObligationCause::dummy_with_span(tcx.def_span(method.def_id)),
608617
)
609618
};

tests/ui/associated-consts/issue-93835.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@
33
fn e() {
44
type_ascribe!(p, a<p:p<e=6>>);
55
//~^ ERROR cannot find type `a` in this scope
6-
//~| ERROR path separator must be a double colon
76
//~| ERROR cannot find value
87
//~| ERROR associated const equality
8+
//~| ERROR cannot find trait `p` in this scope
99
//~| ERROR associated const equality
10-
//~| ERROR failed to resolve: use of unresolved module or unlinked crate `p`
1110
}
1211

1312
fn main() {}
+9-23
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,3 @@
1-
error: path separator must be a double colon
2-
--> $DIR/issue-93835.rs:4:25
3-
|
4-
LL | type_ascribe!(p, a<p:p<e=6>>);
5-
| ^
6-
|
7-
= note: if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>
8-
help: use a double colon instead
9-
|
10-
LL | type_ascribe!(p, a<p::p<e=6>>);
11-
| +
12-
131
error[E0425]: cannot find value `p` in this scope
142
--> $DIR/issue-93835.rs:4:19
153
|
@@ -22,6 +10,12 @@ error[E0412]: cannot find type `a` in this scope
2210
LL | type_ascribe!(p, a<p:p<e=6>>);
2311
| ^ not found in this scope
2412

13+
error[E0405]: cannot find trait `p` in this scope
14+
--> $DIR/issue-93835.rs:4:26
15+
|
16+
LL | type_ascribe!(p, a<p:p<e=6>>);
17+
| ^ not found in this scope
18+
2519
error[E0658]: associated const equality is incomplete
2620
--> $DIR/issue-93835.rs:4:28
2721
|
@@ -43,15 +37,7 @@ LL | type_ascribe!(p, a<p:p<e=6>>);
4337
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
4438
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
4539

46-
error[E0433]: failed to resolve: use of unresolved module or unlinked crate `p`
47-
--> $DIR/issue-93835.rs:4:24
48-
|
49-
LL | type_ascribe!(p, a<p:p<e=6>>);
50-
| ^ use of unresolved module or unlinked crate `p`
51-
|
52-
= help: you might be missing a crate named `p`
53-
54-
error: aborting due to 6 previous errors
40+
error: aborting due to 5 previous errors
5541

56-
Some errors have detailed explanations: E0412, E0425, E0433, E0658.
57-
For more information about an error, try `rustc --explain E0412`.
42+
Some errors have detailed explanations: E0405, E0412, E0425, E0658.
43+
For more information about an error, try `rustc --explain E0405`.

tests/ui/associated-types/issue-59324.stderr

+13-13
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,18 @@ LL | |
3636
LL | | &self,
3737
LL | | ) -> Self::AssocType;
3838
| |_________________________^ the trait `Foo` is not implemented for `Bug`
39+
40+
error[E0277]: the trait bound `(): Foo` is not satisfied
41+
--> $DIR/issue-59324.rs:24:29
3942
|
40-
help: consider further restricting type parameter `Bug` with trait `Foo`
43+
LL | fn with_factory<H>(factory: dyn ThriftService<()>) {}
44+
| ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
4145
|
42-
LL | pub trait ThriftService<Bug: NotFoo + Foo>:
43-
| +++++
46+
help: this trait has no implementations, consider adding one
47+
--> $DIR/issue-59324.rs:3:1
48+
|
49+
LL | pub trait Foo: NotFoo {
50+
| ^^^^^^^^^^^^^^^^^^^^^
4451

4552
error[E0277]: the trait bound `Bug: Foo` is not satisfied
4653
--> $DIR/issue-59324.rs:16:5
@@ -51,18 +58,11 @@ LL | |
5158
LL | | &self,
5259
LL | | ) -> Self::AssocType;
5360
| |_________________________^ the trait `Foo` is not implemented for `Bug`
54-
55-
error[E0277]: the trait bound `(): Foo` is not satisfied
56-
--> $DIR/issue-59324.rs:24:29
5761
|
58-
LL | fn with_factory<H>(factory: dyn ThriftService<()>) {}
59-
| ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
60-
|
61-
help: this trait has no implementations, consider adding one
62-
--> $DIR/issue-59324.rs:3:1
62+
help: consider further restricting type parameter `Bug` with trait `Foo`
6363
|
64-
LL | pub trait Foo: NotFoo {
65-
| ^^^^^^^^^^^^^^^^^^^^^
64+
LL | pub trait ThriftService<Bug: NotFoo + Foo>:
65+
| +++++
6666

6767
error[E0277]: the trait bound `Bug: Foo` is not satisfied
6868
--> $DIR/issue-59324.rs:20:10
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
error: path separator must be a double colon
22
--> $DIR/single-colon-path-not-const-generics.rs:8:18
33
|
4+
LL | pub struct Foo {
5+
| --- while parsing this struct
46
LL | a: Vec<foo::bar:A>,
57
| ^
68
|
79
= note: if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>
810
help: use a double colon instead
911
|
1012
LL | a: Vec<foo::bar::A>,
11-
| +
13+
| +
1214

1315
error: aborting due to 1 previous error
1416

tests/ui/lint/wasm_c_abi_transition.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//@ add-core-stubs
44
//@ build-fail
55

6-
#![feature(no_core)]
6+
#![feature(no_core, repr_simd)]
77
#![no_core]
88
#![crate_type = "lib"]
99
#![deny(wasm_c_abi)]
@@ -39,3 +39,19 @@ pub fn call_other_fun(x: MyType) {
3939
unsafe { other_fun(x) } //~ERROR: wasm ABI transition
4040
//~^WARN: previously accepted
4141
}
42+
43+
// Zero-sized types are safe in both ABIs
44+
#[repr(C)]
45+
pub struct MyZstType;
46+
#[allow(improper_ctypes_definitions)]
47+
pub extern "C" fn zst_safe(_x: (), _y: MyZstType) {}
48+
49+
// The old and new wasm ABI treats simd types like `v128` the same way, so no
50+
// wasm_c_abi warning should be emitted.
51+
#[repr(simd)]
52+
#[allow(non_camel_case_types)]
53+
pub struct v128([i32; 4]);
54+
#[target_feature(enable = "simd128")]
55+
pub extern "C" fn my_safe_simd(x: v128) -> v128 { x }
56+
//~^ WARN `extern` fn uses type `v128`, which is not FFI-safe
57+
//~| WARN `extern` fn uses type `v128`, which is not FFI-safe

tests/ui/lint/wasm_c_abi_transition.stderr

+30-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,32 @@
1+
warning: `extern` fn uses type `v128`, which is not FFI-safe
2+
--> $DIR/wasm_c_abi_transition.rs:55:35
3+
|
4+
LL | pub extern "C" fn my_safe_simd(x: v128) -> v128 { x }
5+
| ^^^^ not FFI-safe
6+
|
7+
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
8+
= note: this struct has unspecified layout
9+
note: the type is defined here
10+
--> $DIR/wasm_c_abi_transition.rs:53:1
11+
|
12+
LL | pub struct v128([i32; 4]);
13+
| ^^^^^^^^^^^^^^^
14+
= note: `#[warn(improper_ctypes_definitions)]` on by default
15+
16+
warning: `extern` fn uses type `v128`, which is not FFI-safe
17+
--> $DIR/wasm_c_abi_transition.rs:55:44
18+
|
19+
LL | pub extern "C" fn my_safe_simd(x: v128) -> v128 { x }
20+
| ^^^^ not FFI-safe
21+
|
22+
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
23+
= note: this struct has unspecified layout
24+
note: the type is defined here
25+
--> $DIR/wasm_c_abi_transition.rs:53:1
26+
|
27+
LL | pub struct v128([i32; 4]);
28+
| ^^^^^^^^^^^^^^^
29+
130
error: this function definition involves an argument of type `MyType` which is affected by the wasm ABI transition
231
--> $DIR/wasm_c_abi_transition.rs:18:1
332
|
@@ -33,7 +62,7 @@ LL | unsafe { other_fun(x) }
3362
= note: for more information, see issue #138762 <https://github.com/rust-lang/rust/issues/138762>
3463
= help: the "C" ABI Rust uses on wasm32-unknown-unknown will change to align with the standard "C" ABI for this target
3564

36-
error: aborting due to 3 previous errors
65+
error: aborting due to 3 previous errors; 2 warnings emitted
3766

3867
Future incompatibility report: Future breakage diagnostic:
3968
error: this function definition involves an argument of type `MyType` which is affected by the wasm ABI transition
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Paths in type contexts may be followed by single colons.
2+
// This means we can't generally assume that the user typo'ed a double colon.
3+
// issue: <https://github.com/rust-lang/rust/issues/140227>
4+
//@ check-pass
5+
#![crate_type = "lib"]
6+
#![expect(non_camel_case_types)]
7+
8+
#[rustfmt::skip]
9+
mod garden {
10+
11+
fn f<path>() where path:to::somewhere {} // OK!
12+
13+
fn g(_: impl Take<path:to::somewhere>) {} // OK!
14+
15+
#[cfg(any())] fn h() where a::path:to::nowhere {} // OK!
16+
17+
fn i(_: impl Take<path::<>:to::somewhere>) {} // OK!
18+
19+
mod to { pub(super) trait somewhere {} }
20+
trait Take { type path; }
21+
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//@ check-pass
2+
3+
// Regression test for <https://github.com/rust-lang/rust/issues/138937>.
4+
5+
// Previously, we'd take the normalized param env's clauses which included
6+
// `<PF as TraitC>::Value = i32`, which comes from the supertraits of `TraitD`
7+
// after normalizing `<PF as TraitC>::Value = <PF as TraitD>::Scalar`. Since
8+
// `normalize_param_env_or_error` ends up re-elaborating `PF: TraitD`, we'd
9+
// end up with both versions of this predicate (normalized and unnormalized).
10+
// Since these projections preds are not equal, we'd fail with ambiguity.
11+
12+
trait TraitB<T> {}
13+
14+
trait TraitC: TraitB<Self::Value> {
15+
type Value;
16+
}
17+
18+
trait TraitD: TraitC<Value = Self::Scalar> {
19+
type Scalar;
20+
}
21+
22+
trait TraitE {
23+
fn apply<PF: TraitD<Scalar = i32>>(&self);
24+
}
25+
26+
fn main() {}

tests/ui/suggestions/argument-list-from-path-sep-error-129273.fixed

-15
This file was deleted.

tests/ui/suggestions/argument-list-from-path-sep-error-129273.rs

-15
This file was deleted.

0 commit comments

Comments
 (0)