summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-04-26 19:05:06 +0000
committerbors <bors@rust-lang.org>2025-04-26 19:05:06 +0000
commit74f40c495e867ec6b6b355b548436c7b6c967859 (patch)
tree37d49069b7f5bde80bb4d947effab5e511687748
parent386abeb93ab8e683357f54ffe76ae53861b2d984 (diff)
parent7ef00508c52417b1a1ad73811f05907c8e2a4b62 (diff)
downloadrust-74f40c495e867ec6b6b355b548436c7b6c967859.tar.gz
rust-74f40c495e867ec6b6b355b548436c7b6c967859.zip
Auto merge of #140269 - cuviper:beta-next, r=cuviper
[beta] backports

- Do not mix normalized and unnormalized caller bounds when constructing param-env for `receiver_is_dispatchable` #138941
- Ignore zero-sized types in wasm future-compat warning #139498
- Don't warn about `v128` in wasm ABI transition #139809
- Revert overzealous parse recovery for single colons in paths #140228

r? cuviper
-rw-r--r--compiler/rustc_monomorphize/src/mono_checks/abi_check.rs11
-rw-r--r--compiler/rustc_parse/src/parser/item.rs11
-rw-r--r--compiler/rustc_parse/src/parser/path.rs20
-rw-r--r--compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs35
-rw-r--r--tests/ui/associated-consts/issue-93835.rs3
-rw-r--r--tests/ui/associated-consts/issue-93835.stderr32
-rw-r--r--tests/ui/associated-types/issue-59324.stderr26
-rw-r--r--tests/ui/generics/single-colon-path-not-const-generics.stderr4
-rw-r--r--tests/ui/lint/wasm_c_abi_transition.rs18
-rw-r--r--tests/ui/lint/wasm_c_abi_transition.stderr31
-rw-r--r--tests/ui/parser/ty-path-followed-by-single-colon.rs22
-rw-r--r--tests/ui/self/dyn-dispatch-do-not-mix-normalized-and-unnormalized.rs26
-rw-r--r--tests/ui/suggestions/argument-list-from-path-sep-error-129273.fixed15
-rw-r--r--tests/ui/suggestions/argument-list-from-path-sep-error-129273.rs15
-rw-r--r--tests/ui/suggestions/argument-list-from-path-sep-error-129273.stderr14
-rw-r--r--tests/ui/suggestions/struct-field-type-including-single-colon.rs8
-rw-r--r--tests/ui/suggestions/struct-field-type-including-single-colon.stderr47
17 files changed, 193 insertions, 145 deletions
diff --git a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs
index 0f5bdc8d768..81bf8c5d21c 100644
--- a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs
+++ b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs
@@ -99,6 +99,12 @@ fn wasm_abi_safe<'tcx>(tcx: TyCtxt<'tcx>, arg: &ArgAbi<'tcx, Ty<'tcx>>) -> bool
         return true;
     }
 
+    // Both the old and the new ABIs treat vector types like `v128` the same
+    // way.
+    if uses_vector_registers(&arg.mode, &arg.layout.backend_repr) {
+        return true;
+    }
+
     // This matches `unwrap_trivial_aggregate` in the wasm ABI logic.
     if arg.layout.is_aggregate() {
         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
         }
     }
 
+    // Zero-sized types are dropped in both ABIs, so they're safe
+    if arg.layout.is_zst() {
+        return true;
+    }
+
     false
 }
 
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index aad18578375..97146d2a6b8 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -2066,6 +2066,17 @@ impl<'a> Parser<'a> {
         }
         self.expect_field_ty_separator()?;
         let ty = self.parse_ty()?;
+        if self.token == token::Colon && self.look_ahead(1, |t| *t != token::Colon) {
+            self.dcx()
+                .struct_span_err(self.token.span, "found single colon in a struct field type path")
+                .with_span_suggestion_verbose(
+                    self.token.span,
+                    "write a path separator here",
+                    "::",
+                    Applicability::MaybeIncorrect,
+                )
+                .emit();
+        }
         let default = if self.token == token::Eq {
             self.bump();
             let const_expr = self.parse_expr_anon_const()?;
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index 9c6830c3672..a25664a6c89 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -248,19 +248,13 @@ impl<'a> Parser<'a> {
             segments.push(segment);
 
             if self.is_import_coupler() || !self.eat_path_sep() {
-                let ok_for_recovery = self.may_recover()
-                    && match style {
-                        PathStyle::Expr => true,
-                        PathStyle::Type if let Some((ident, _)) = self.prev_token.ident() => {
-                            self.token == token::Colon
-                                && ident.as_str().chars().all(|c| c.is_lowercase())
-                                && self.token.span.lo() == self.prev_token.span.hi()
-                                && self
-                                    .look_ahead(1, |token| self.token.span.hi() == token.span.lo())
-                        }
-                        _ => false,
-                    };
-                if ok_for_recovery
+                // IMPORTANT: We can *only ever* treat single colons as typo'ed double colons in
+                // expression contexts (!) since only there paths cannot possibly be followed by
+                // a colon and still form a syntactically valid construct. In pattern contexts,
+                // a path may be followed by a type annotation. E.g., `let pat:ty`. In type
+                // contexts, a path may be followed by a list of bounds. E.g., `where ty:bound`.
+                if self.may_recover()
+                    && style == PathStyle::Expr // (!)
                     && self.token == token::Colon
                     && self.look_ahead(1, |token| token.is_ident() && !token.is_reserved_ident())
                 {
diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
index 78a45243983..fa6bbf1d6e5 100644
--- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
+++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
@@ -583,27 +583,36 @@ fn receiver_is_dispatchable<'tcx>(
     // create a modified param env, with `Self: Unsize<U>` and `U: Trait` (and all of
     // its supertraits) added to caller bounds. `U: ?Sized` is already implied here.
     let param_env = {
-        let param_env = tcx.param_env(method.def_id);
+        // N.B. We generally want to emulate the construction of the `unnormalized_param_env`
+        // in the param-env query here. The fact that we don't just start with the clauses
+        // in the param-env of the method is because those are already normalized, and mixing
+        // normalized and unnormalized copies of predicates in `normalize_param_env_or_error`
+        // will cause ambiguity that the user can't really avoid.
+        //
+        // We leave out certain complexities of the param-env query here. Specifically, we:
+        // 1. Do not add `~const` bounds since there are no `dyn const Trait`s.
+        // 2. Do not add RPITIT self projection bounds for defaulted methods, since we
+        //    are not constructing a param-env for "inside" of the body of the defaulted
+        //    method, so we don't really care about projecting to a specific RPIT type,
+        //    and because RPITITs are not dyn compatible (yet).
+        let mut predicates = tcx.predicates_of(method.def_id).instantiate_identity(tcx).predicates;
 
         // Self: Unsize<U>
         let unsize_predicate =
-            ty::TraitRef::new(tcx, unsize_did, [tcx.types.self_param, unsized_self_ty]).upcast(tcx);
+            ty::TraitRef::new(tcx, unsize_did, [tcx.types.self_param, unsized_self_ty]);
+        predicates.push(unsize_predicate.upcast(tcx));
 
         // U: Trait<Arg1, ..., ArgN>
-        let trait_predicate = {
-            let trait_def_id = method.trait_container(tcx).unwrap();
-            let args = GenericArgs::for_item(tcx, trait_def_id, |param, _| {
-                if param.index == 0 { unsized_self_ty.into() } else { tcx.mk_param_from_def(param) }
-            });
-
-            ty::TraitRef::new_from_args(tcx, trait_def_id, args).upcast(tcx)
-        };
+        let trait_def_id = method.trait_container(tcx).unwrap();
+        let args = GenericArgs::for_item(tcx, trait_def_id, |param, _| {
+            if param.index == 0 { unsized_self_ty.into() } else { tcx.mk_param_from_def(param) }
+        });
+        let trait_predicate = ty::TraitRef::new_from_args(tcx, trait_def_id, args);
+        predicates.push(trait_predicate.upcast(tcx));
 
         normalize_param_env_or_error(
             tcx,
-            ty::ParamEnv::new(tcx.mk_clauses_from_iter(
-                param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]),
-            )),
+            ty::ParamEnv::new(tcx.mk_clauses(&predicates)),
             ObligationCause::dummy_with_span(tcx.def_span(method.def_id)),
         )
     };
diff --git a/tests/ui/associated-consts/issue-93835.rs b/tests/ui/associated-consts/issue-93835.rs
index 048681f0477..d6c2acaa9ed 100644
--- a/tests/ui/associated-consts/issue-93835.rs
+++ b/tests/ui/associated-consts/issue-93835.rs
@@ -3,11 +3,10 @@
 fn e() {
     type_ascribe!(p, a<p:p<e=6>>);
     //~^ ERROR cannot find type `a` in this scope
-    //~| ERROR path separator must be a double colon
     //~| ERROR cannot find value
     //~| ERROR associated const equality
+    //~| ERROR cannot find trait `p` in this scope
     //~| ERROR associated const equality
-    //~| ERROR failed to resolve: use of unresolved module or unlinked crate `p`
 }
 
 fn main() {}
diff --git a/tests/ui/associated-consts/issue-93835.stderr b/tests/ui/associated-consts/issue-93835.stderr
index e154ae25de2..551b50d0eb6 100644
--- a/tests/ui/associated-consts/issue-93835.stderr
+++ b/tests/ui/associated-consts/issue-93835.stderr
@@ -1,15 +1,3 @@
-error: path separator must be a double colon
-  --> $DIR/issue-93835.rs:4:25
-   |
-LL |     type_ascribe!(p, a<p:p<e=6>>);
-   |                         ^
-   |
-   = 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>
-help: use a double colon instead
-   |
-LL |     type_ascribe!(p, a<p::p<e=6>>);
-   |                          +
-
 error[E0425]: cannot find value `p` in this scope
   --> $DIR/issue-93835.rs:4:19
    |
@@ -22,6 +10,12 @@ error[E0412]: cannot find type `a` in this scope
 LL |     type_ascribe!(p, a<p:p<e=6>>);
    |                      ^ not found in this scope
 
+error[E0405]: cannot find trait `p` in this scope
+  --> $DIR/issue-93835.rs:4:26
+   |
+LL |     type_ascribe!(p, a<p:p<e=6>>);
+   |                          ^ not found in this scope
+
 error[E0658]: associated const equality is incomplete
   --> $DIR/issue-93835.rs:4:28
    |
@@ -43,15 +37,7 @@ LL |     type_ascribe!(p, a<p:p<e=6>>);
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error[E0433]: failed to resolve: use of unresolved module or unlinked crate `p`
-  --> $DIR/issue-93835.rs:4:24
-   |
-LL |     type_ascribe!(p, a<p:p<e=6>>);
-   |                        ^ use of unresolved module or unlinked crate `p`
-   |
-   = help: you might be missing a crate named `p`
-
-error: aborting due to 6 previous errors
+error: aborting due to 5 previous errors
 
-Some errors have detailed explanations: E0412, E0425, E0433, E0658.
-For more information about an error, try `rustc --explain E0412`.
+Some errors have detailed explanations: E0405, E0412, E0425, E0658.
+For more information about an error, try `rustc --explain E0405`.
diff --git a/tests/ui/associated-types/issue-59324.stderr b/tests/ui/associated-types/issue-59324.stderr
index f5e696b7ac1..f79afc89d10 100644
--- a/tests/ui/associated-types/issue-59324.stderr
+++ b/tests/ui/associated-types/issue-59324.stderr
@@ -36,11 +36,18 @@ LL | |
 LL | |         &self,
 LL | |     ) -> Self::AssocType;
    | |_________________________^ the trait `Foo` is not implemented for `Bug`
+
+error[E0277]: the trait bound `(): Foo` is not satisfied
+  --> $DIR/issue-59324.rs:24:29
    |
-help: consider further restricting type parameter `Bug` with trait `Foo`
+LL | fn with_factory<H>(factory: dyn ThriftService<()>) {}
+   |                             ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
    |
-LL | pub trait ThriftService<Bug: NotFoo + Foo>:
-   |                                     +++++
+help: this trait has no implementations, consider adding one
+  --> $DIR/issue-59324.rs:3:1
+   |
+LL | pub trait Foo: NotFoo {
+   | ^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `Bug: Foo` is not satisfied
   --> $DIR/issue-59324.rs:16:5
@@ -51,18 +58,11 @@ LL | |
 LL | |         &self,
 LL | |     ) -> Self::AssocType;
    | |_________________________^ the trait `Foo` is not implemented for `Bug`
-
-error[E0277]: the trait bound `(): Foo` is not satisfied
-  --> $DIR/issue-59324.rs:24:29
    |
-LL | fn with_factory<H>(factory: dyn ThriftService<()>) {}
-   |                             ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
-   |
-help: this trait has no implementations, consider adding one
-  --> $DIR/issue-59324.rs:3:1
+help: consider further restricting type parameter `Bug` with trait `Foo`
    |
-LL | pub trait Foo: NotFoo {
-   | ^^^^^^^^^^^^^^^^^^^^^
+LL | pub trait ThriftService<Bug: NotFoo + Foo>:
+   |                                     +++++
 
 error[E0277]: the trait bound `Bug: Foo` is not satisfied
   --> $DIR/issue-59324.rs:20:10
diff --git a/tests/ui/generics/single-colon-path-not-const-generics.stderr b/tests/ui/generics/single-colon-path-not-const-generics.stderr
index c14a5e62a0c..4e695b2dcd6 100644
--- a/tests/ui/generics/single-colon-path-not-const-generics.stderr
+++ b/tests/ui/generics/single-colon-path-not-const-generics.stderr
@@ -1,6 +1,8 @@
 error: path separator must be a double colon
   --> $DIR/single-colon-path-not-const-generics.rs:8:18
    |
+LL | pub struct Foo {
+   |            --- while parsing this struct
 LL |   a: Vec<foo::bar:A>,
    |                  ^
    |
@@ -8,7 +10,7 @@ LL |   a: Vec<foo::bar:A>,
 help: use a double colon instead
    |
 LL |   a: Vec<foo::bar::A>,
-   |                   +
+   |                  +
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/lint/wasm_c_abi_transition.rs b/tests/ui/lint/wasm_c_abi_transition.rs
index 1fe81679e65..411772ae890 100644
--- a/tests/ui/lint/wasm_c_abi_transition.rs
+++ b/tests/ui/lint/wasm_c_abi_transition.rs
@@ -3,7 +3,7 @@
 //@ add-core-stubs
 //@ build-fail
 
-#![feature(no_core)]
+#![feature(no_core, repr_simd)]
 #![no_core]
 #![crate_type = "lib"]
 #![deny(wasm_c_abi)]
@@ -39,3 +39,19 @@ pub fn call_other_fun(x: MyType) {
     unsafe { other_fun(x) } //~ERROR: wasm ABI transition
     //~^WARN: previously accepted
 }
+
+// Zero-sized types are safe in both ABIs
+#[repr(C)]
+pub struct MyZstType;
+#[allow(improper_ctypes_definitions)]
+pub extern "C" fn zst_safe(_x: (), _y: MyZstType) {}
+
+// The old and new wasm ABI treats simd types like `v128` the same way, so no
+// wasm_c_abi warning should be emitted.
+#[repr(simd)]
+#[allow(non_camel_case_types)]
+pub struct v128([i32; 4]);
+#[target_feature(enable = "simd128")]
+pub extern "C" fn my_safe_simd(x: v128) -> v128 { x }
+//~^ WARN `extern` fn uses type `v128`, which is not FFI-safe
+//~| WARN `extern` fn uses type `v128`, which is not FFI-safe
diff --git a/tests/ui/lint/wasm_c_abi_transition.stderr b/tests/ui/lint/wasm_c_abi_transition.stderr
index 389710d5cb3..b4526bf8d68 100644
--- a/tests/ui/lint/wasm_c_abi_transition.stderr
+++ b/tests/ui/lint/wasm_c_abi_transition.stderr
@@ -1,3 +1,32 @@
+warning: `extern` fn uses type `v128`, which is not FFI-safe
+  --> $DIR/wasm_c_abi_transition.rs:55:35
+   |
+LL | pub extern "C" fn my_safe_simd(x: v128) -> v128 { x }
+   |                                   ^^^^ not FFI-safe
+   |
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
+note: the type is defined here
+  --> $DIR/wasm_c_abi_transition.rs:53:1
+   |
+LL | pub struct v128([i32; 4]);
+   | ^^^^^^^^^^^^^^^
+   = note: `#[warn(improper_ctypes_definitions)]` on by default
+
+warning: `extern` fn uses type `v128`, which is not FFI-safe
+  --> $DIR/wasm_c_abi_transition.rs:55:44
+   |
+LL | pub extern "C" fn my_safe_simd(x: v128) -> v128 { x }
+   |                                            ^^^^ not FFI-safe
+   |
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
+note: the type is defined here
+  --> $DIR/wasm_c_abi_transition.rs:53:1
+   |
+LL | pub struct v128([i32; 4]);
+   | ^^^^^^^^^^^^^^^
+
 error: this function definition involves an argument of type `MyType` which is affected by the wasm ABI transition
   --> $DIR/wasm_c_abi_transition.rs:18:1
    |
@@ -33,7 +62,7 @@ LL |     unsafe { other_fun(x) }
    = note: for more information, see issue #138762 <https://github.com/rust-lang/rust/issues/138762>
    = help: the "C" ABI Rust uses on wasm32-unknown-unknown will change to align with the standard "C" ABI for this target
 
-error: aborting due to 3 previous errors
+error: aborting due to 3 previous errors; 2 warnings emitted
 
 Future incompatibility report: Future breakage diagnostic:
 error: this function definition involves an argument of type `MyType` which is affected by the wasm ABI transition
diff --git a/tests/ui/parser/ty-path-followed-by-single-colon.rs b/tests/ui/parser/ty-path-followed-by-single-colon.rs
new file mode 100644
index 00000000000..a9082ea317a
--- /dev/null
+++ b/tests/ui/parser/ty-path-followed-by-single-colon.rs
@@ -0,0 +1,22 @@
+// Paths in type contexts may be followed by single colons.
+// This means we can't generally assume that the user typo'ed a double colon.
+// issue: <https://github.com/rust-lang/rust/issues/140227>
+//@ check-pass
+#![crate_type = "lib"]
+#![expect(non_camel_case_types)]
+
+#[rustfmt::skip]
+mod garden {
+
+    fn f<path>() where path:to::somewhere {} // OK!
+
+    fn g(_: impl Take<path:to::somewhere>) {} // OK!
+
+    #[cfg(any())] fn h() where a::path:to::nowhere {} // OK!
+
+    fn i(_: impl Take<path::<>:to::somewhere>) {} // OK!
+
+    mod to { pub(super) trait somewhere {} }
+    trait Take { type path; }
+
+}
diff --git a/tests/ui/self/dyn-dispatch-do-not-mix-normalized-and-unnormalized.rs b/tests/ui/self/dyn-dispatch-do-not-mix-normalized-and-unnormalized.rs
new file mode 100644
index 00000000000..2bc70de2a34
--- /dev/null
+++ b/tests/ui/self/dyn-dispatch-do-not-mix-normalized-and-unnormalized.rs
@@ -0,0 +1,26 @@
+//@ check-pass
+
+// Regression test for <https://github.com/rust-lang/rust/issues/138937>.
+
+// Previously, we'd take the normalized param env's clauses which included
+// `<PF as TraitC>::Value = i32`, which comes from the supertraits of `TraitD`
+// after normalizing `<PF as TraitC>::Value = <PF as TraitD>::Scalar`. Since
+// `normalize_param_env_or_error` ends up re-elaborating `PF: TraitD`, we'd
+// end up with both versions of this predicate (normalized and unnormalized).
+// Since these projections preds are not equal, we'd fail with ambiguity.
+
+trait TraitB<T> {}
+
+trait TraitC: TraitB<Self::Value> {
+    type Value;
+}
+
+trait TraitD: TraitC<Value = Self::Scalar> {
+    type Scalar;
+}
+
+trait TraitE {
+    fn apply<PF: TraitD<Scalar = i32>>(&self);
+}
+
+fn main() {}
diff --git a/tests/ui/suggestions/argument-list-from-path-sep-error-129273.fixed b/tests/ui/suggestions/argument-list-from-path-sep-error-129273.fixed
deleted file mode 100644
index f5dbf0c8b6f..00000000000
--- a/tests/ui/suggestions/argument-list-from-path-sep-error-129273.fixed
+++ /dev/null
@@ -1,15 +0,0 @@
-//@ run-rustfix
-
-use std::fmt;
-
-struct Hello;
-
-impl fmt::Display for Hello {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { //~ ERROR path separator must be a double colon
-        write!(f, "hello")
-    }
-}
-
-fn main() {
-    let _ = Hello;
-}
diff --git a/tests/ui/suggestions/argument-list-from-path-sep-error-129273.rs b/tests/ui/suggestions/argument-list-from-path-sep-error-129273.rs
deleted file mode 100644
index c41880a26f6..00000000000
--- a/tests/ui/suggestions/argument-list-from-path-sep-error-129273.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-//@ run-rustfix
-
-use std::fmt;
-
-struct Hello;
-
-impl fmt::Display for Hello {
-    fn fmt(&self, f: &mut fmt:Formatter) -> fmt::Result { //~ ERROR path separator must be a double colon
-        write!(f, "hello")
-    }
-}
-
-fn main() {
-    let _ = Hello;
-}
diff --git a/tests/ui/suggestions/argument-list-from-path-sep-error-129273.stderr b/tests/ui/suggestions/argument-list-from-path-sep-error-129273.stderr
deleted file mode 100644
index 92947e3b177..00000000000
--- a/tests/ui/suggestions/argument-list-from-path-sep-error-129273.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error: path separator must be a double colon
-  --> $DIR/argument-list-from-path-sep-error-129273.rs:8:30
-   |
-LL |     fn fmt(&self, f: &mut fmt:Formatter) -> fmt::Result {
-   |                              ^
-   |
-   = 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>
-help: use a double colon instead
-   |
-LL |     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-   |                               +
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/suggestions/struct-field-type-including-single-colon.rs b/tests/ui/suggestions/struct-field-type-including-single-colon.rs
index a3111028895..482641fc7ca 100644
--- a/tests/ui/suggestions/struct-field-type-including-single-colon.rs
+++ b/tests/ui/suggestions/struct-field-type-including-single-colon.rs
@@ -7,14 +7,14 @@ mod foo {
 
 struct Foo {
     a: foo:A,
-    //~^ ERROR path separator must be a double colon
-    //~| ERROR struct `A` is private
+    //~^ ERROR found single colon in a struct field type path
+    //~| ERROR expected `,`, or `}`, found `:`
 }
 
 struct Bar {
     b: foo::bar:B,
-    //~^ ERROR path separator must be a double colon
-    //~| ERROR module `bar` is private
+    //~^ ERROR found single colon in a struct field type path
+    //~| ERROR expected `,`, or `}`, found `:`
 }
 
 fn main() {}
diff --git a/tests/ui/suggestions/struct-field-type-including-single-colon.stderr b/tests/ui/suggestions/struct-field-type-including-single-colon.stderr
index ce16aca1e14..5ffc5b40849 100644
--- a/tests/ui/suggestions/struct-field-type-including-single-colon.stderr
+++ b/tests/ui/suggestions/struct-field-type-including-single-colon.stderr
@@ -1,53 +1,40 @@
-error: path separator must be a double colon
+error: found single colon in a struct field type path
   --> $DIR/struct-field-type-including-single-colon.rs:9:11
    |
 LL |     a: foo:A,
    |           ^
    |
-   = 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>
-help: use a double colon instead
+help: write a path separator here
    |
 LL |     a: foo::A,
    |            +
 
-error: path separator must be a double colon
+error: expected `,`, or `}`, found `:`
+  --> $DIR/struct-field-type-including-single-colon.rs:9:11
+   |
+LL | struct Foo {
+   |        --- while parsing this struct
+LL |     a: foo:A,
+   |           ^
+
+error: found single colon in a struct field type path
   --> $DIR/struct-field-type-including-single-colon.rs:15:16
    |
 LL |     b: foo::bar:B,
    |                ^
    |
-   = 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>
-help: use a double colon instead
+help: write a path separator here
    |
 LL |     b: foo::bar::B,
    |                 +
 
-error[E0603]: struct `A` is private
-  --> $DIR/struct-field-type-including-single-colon.rs:9:12
-   |
-LL |     a: foo:A,
-   |            ^ private struct
-   |
-note: the struct `A` is defined here
-  --> $DIR/struct-field-type-including-single-colon.rs:2:5
-   |
-LL |     struct A;
-   |     ^^^^^^^^^
-
-error[E0603]: module `bar` is private
-  --> $DIR/struct-field-type-including-single-colon.rs:15:13
+error: expected `,`, or `}`, found `:`
+  --> $DIR/struct-field-type-including-single-colon.rs:15:16
    |
+LL | struct Bar {
+   |        --- while parsing this struct
 LL |     b: foo::bar:B,
-   |             ^^^ - struct `B` is not publicly re-exported
-   |             |
-   |             private module
-   |
-note: the module `bar` is defined here
-  --> $DIR/struct-field-type-including-single-colon.rs:3:5
-   |
-LL |     mod bar {
-   |     ^^^^^^^
+   |                ^
 
 error: aborting due to 4 previous errors
 
-For more information about this error, try `rustc --explain E0603`.