about summary refs log tree commit diff
diff options
context:
space:
mode:
authorlcnr <rust@lcnr.de>2025-08-25 11:48:55 +0200
committerlcnr <rust@lcnr.de>2025-08-25 14:20:18 +0200
commitd6a18e18676f355e9f5350a9204f81c4dd2bc0f3 (patch)
tree7531f8f27fe5392efe1732aef67ea8a471ae1cb8
parent14b0ba6a0543cdbbd19b5a0aaa3ae03500fb72d2 (diff)
downloadrust-d6a18e18676f355e9f5350a9204f81c4dd2bc0f3.tar.gz
rust-d6a18e18676f355e9f5350a9204f81c4dd2bc0f3.zip
change non-defining use error message
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs1
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl4
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs12
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs11
-rw-r--r--compiler/rustc_hir_typeck/src/opaque_types.rs25
-rw-r--r--compiler/rustc_trait_selection/src/opaque_types.rs28
-rw-r--r--tests/ui/type-alias-impl-trait/generic_nondefining_use.current.stderr (renamed from tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr)6
-rw-r--r--tests/ui/type-alias-impl-trait/generic_nondefining_use.next.stderr44
-rw-r--r--tests/ui/type-alias-impl-trait/generic_nondefining_use.rs14
9 files changed, 98 insertions, 47 deletions
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs
index d1222ab21a2..bee82e17835 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs
@@ -42,7 +42,6 @@ use region_ctxt::RegionCtxt;
 /// if there are no `RegionErrors`. If there are region errors, it's likely
 /// that errors here are caused by them and don't need to be handled separately.
 pub(crate) enum DeferredOpaqueTypeError<'tcx> {
-    /// FIXME(-Znext-solver=no): Only used by the old solver.
     InvalidOpaqueTypeArgs(NonDefiningUseReason<'tcx>),
     LifetimeMismatchOpaqueParam(LifetimeMismatchOpaqueParam<'tcx>),
     UnexpectedHiddenRegion {
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 2428c1aa29f..06f2ec512ab 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -509,10 +509,6 @@ hir_analysis_supertrait_item_shadowee = item from `{$supertrait}` is shadowed by
 
 hir_analysis_supertrait_item_shadowing = trait item `{$item}` from `{$subtrait}` shadows identically named item from supertrait
 
-hir_analysis_tait_forward_compat2 = item does not constrain `{$opaque_type}`
-    .note = consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
-    .opaque = this opaque type is supposed to be constrained
-
 hir_analysis_target_feature_on_main = `main` function is not allowed to have `#[target_feature]`
 
 hir_analysis_too_large_static = extern static is too large for the target architecture
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
index bc8abdde052..b6d898886ac 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
@@ -4,9 +4,10 @@ use rustc_hir::{self as hir, Expr, ImplItem, Item, Node, TraitItem, def, intravi
 use rustc_middle::bug;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::{self, DefiningScopeKind, Ty, TyCtxt, TypeVisitableExt};
+use rustc_trait_selection::opaque_types::report_item_does_not_constrain_error;
 use tracing::{debug, instrument, trace};
 
-use crate::errors::{TaitForwardCompat2, UnconstrainedOpaqueType};
+use crate::errors::UnconstrainedOpaqueType;
 
 /// Checks "defining uses" of opaque `impl Trait` in associated types.
 /// These can only be defined by associated items of the same trait.
@@ -131,14 +132,7 @@ impl<'tcx> TaitConstraintLocator<'tcx> {
         // type checking the defining scope, so this error is unreachable
         // with the new solver.
         assert!(!self.tcx.next_trait_solver_globally());
-        let guar = self.tcx.dcx().emit_err(TaitForwardCompat2 {
-            span: self
-                .tcx
-                .def_ident_span(item_def_id)
-                .unwrap_or_else(|| self.tcx.def_span(item_def_id)),
-            opaque_type_span: self.tcx.def_span(self.def_id),
-            opaque_type: self.tcx.def_path_str(self.def_id),
-        });
+        let guar = report_item_does_not_constrain_error(self.tcx, item_def_id, self.def_id, None);
         self.insert_found(ty::OpaqueHiddenType::new_error(self.tcx, guar));
     }
 
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index fc3dca73caf..6565ad7cf53 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -410,17 +410,6 @@ pub(crate) struct UnconstrainedOpaqueType {
     pub what: &'static str,
 }
 
-#[derive(Diagnostic)]
-#[diag(hir_analysis_tait_forward_compat2)]
-#[note]
-pub struct TaitForwardCompat2 {
-    #[primary_span]
-    pub span: Span,
-    #[note(hir_analysis_opaque)]
-    pub opaque_type_span: Span,
-    pub opaque_type: String,
-}
-
 pub(crate) struct MissingTypeParams {
     pub span: Span,
     pub def_span: Span,
diff --git a/compiler/rustc_hir_typeck/src/opaque_types.rs b/compiler/rustc_hir_typeck/src/opaque_types.rs
index 8188c0eb7d1..97feac3d009 100644
--- a/compiler/rustc_hir_typeck/src/opaque_types.rs
+++ b/compiler/rustc_hir_typeck/src/opaque_types.rs
@@ -1,5 +1,4 @@
 use rustc_hir::def::DefKind;
-use rustc_hir_analysis::errors::TaitForwardCompat2;
 use rustc_infer::traits::ObligationCause;
 use rustc_middle::ty::{
     self, DefiningScopeKind, EarlyBinder, OpaqueHiddenType, OpaqueTypeKey, TypeVisitableExt,
@@ -7,7 +6,7 @@ use rustc_middle::ty::{
 };
 use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded;
 use rustc_trait_selection::opaque_types::{
-    NonDefiningUseReason, opaque_type_has_defining_use_args,
+    NonDefiningUseReason, opaque_type_has_defining_use_args, report_item_does_not_constrain_error,
 };
 use rustc_trait_selection::solve;
 use tracing::{debug, instrument};
@@ -43,7 +42,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
 
 enum UsageKind<'tcx> {
     None,
-    NonDefiningUse(OpaqueHiddenType<'tcx>),
+    NonDefiningUse(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>),
     UnconstrainedHiddenType(OpaqueHiddenType<'tcx>),
     HasDefiningUse,
 }
@@ -106,18 +105,16 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
                     if let Some(guar) = self.tainted_by_errors() {
                         guar
                     } else {
-                        self.tcx.dcx().emit_err(TaitForwardCompat2 {
-                            span: self
-                                .tcx
-                                .def_ident_span(self.body_id)
-                                .unwrap_or_else(|| self.tcx.def_span(self.body_id)),
-                            opaque_type_span: self.tcx.def_span(def_id),
-                            opaque_type: self.tcx.def_path_str(def_id),
-                        })
+                        report_item_does_not_constrain_error(self.tcx, self.body_id, def_id, None)
                     }
                 }
-                UsageKind::NonDefiningUse(hidden_type) => {
-                    tcx.dcx().span_err(hidden_type.span, "non-defining use in the defining scope")
+                UsageKind::NonDefiningUse(opaque_type_key, hidden_type) => {
+                    report_item_does_not_constrain_error(
+                        self.tcx,
+                        self.body_id,
+                        def_id,
+                        Some((opaque_type_key, hidden_type.span)),
+                    )
                 }
                 UsageKind::UnconstrainedHiddenType(hidden_type) => {
                     let infer_var = hidden_type
@@ -166,7 +163,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
                     );
                     return UsageKind::HasDefiningUse;
                 }
-                _ => return UsageKind::NonDefiningUse(hidden_type),
+                _ => return UsageKind::NonDefiningUse(opaque_type_key, hidden_type),
             };
         }
 
diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs
index 46bde670207..bc7bdd372ba 100644
--- a/compiler/rustc_trait_selection/src/opaque_types.rs
+++ b/compiler/rustc_trait_selection/src/opaque_types.rs
@@ -4,8 +4,8 @@ use rustc_hir::def_id::LocalDefId;
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
 use rustc_middle::ty::{
-    self, DefiningScopeKind, GenericArgKind, GenericArgs, OpaqueTypeKey, TyCtxt, TypeVisitableExt,
-    TypingMode, fold_regions,
+    self, DefiningScopeKind, GenericArgKind, GenericArgs, OpaqueTypeKey, Ty, TyCtxt,
+    TypeVisitableExt, TypingMode, fold_regions,
 };
 use rustc_span::{ErrorGuaranteed, Span};
 
@@ -208,3 +208,27 @@ impl<'tcx> LazyOpaqueTyEnv<'tcx> {
         canonical_args
     }
 }
+
+pub fn report_item_does_not_constrain_error<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    item_def_id: LocalDefId,
+    def_id: LocalDefId,
+    non_defining_use: Option<(OpaqueTypeKey<'tcx>, Span)>,
+) -> ErrorGuaranteed {
+    let span = tcx.def_ident_span(item_def_id).unwrap_or_else(|| tcx.def_span(item_def_id));
+    let opaque_type_span = tcx.def_span(def_id);
+    let opaque_type_name = tcx.def_path_str(def_id);
+
+    let mut err =
+        tcx.dcx().struct_span_err(span, format!("item does not constrain `{opaque_type_name}`"));
+    err.note("consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`");
+    err.span_note(opaque_type_span, "this opaque type is supposed to be constrained");
+    if let Some((key, span)) = non_defining_use {
+        let opaque_ty = Ty::new_opaque(tcx, key.def_id.into(), key.args);
+        err.span_note(
+            span,
+            format!("this use of `{opaque_ty}` does not have unique universal generic arguments"),
+        );
+    }
+    err.emit()
+}
diff --git a/tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr b/tests/ui/type-alias-impl-trait/generic_nondefining_use.current.stderr
index 71e415271ee..2a78860689b 100644
--- a/tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_nondefining_use.current.stderr
@@ -1,5 +1,5 @@
 error[E0792]: expected generic type parameter, found `u32`
-  --> $DIR/generic_nondefining_use.rs:16:21
+  --> $DIR/generic_nondefining_use.rs:20:21
    |
 LL | type OneTy<T> = impl Debug;
    |            - this generic parameter must be used with a generic type parameter
@@ -8,7 +8,7 @@ LL | fn concrete_ty() -> OneTy<u32> {
    |                     ^^^^^^^^^^
 
 error[E0792]: expected generic lifetime parameter, found `'static`
-  --> $DIR/generic_nondefining_use.rs:23:5
+  --> $DIR/generic_nondefining_use.rs:29:5
    |
 LL | type OneLifetime<'a> = impl Debug;
    |                  -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type
@@ -17,7 +17,7 @@ LL |     6u32
    |     ^^^^
 
 error[E0792]: expected generic constant parameter, found `123`
-  --> $DIR/generic_nondefining_use.rs:28:24
+  --> $DIR/generic_nondefining_use.rs:35:24
    |
 LL | type OneConst<const X: usize> = impl Debug;
    |               -------------- this generic parameter must be used with a generic constant parameter
diff --git a/tests/ui/type-alias-impl-trait/generic_nondefining_use.next.stderr b/tests/ui/type-alias-impl-trait/generic_nondefining_use.next.stderr
new file mode 100644
index 00000000000..2b53614ee3f
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/generic_nondefining_use.next.stderr
@@ -0,0 +1,44 @@
+error: item does not constrain `OneTy::{opaque#0}`
+  --> $DIR/generic_nondefining_use.rs:20:4
+   |
+LL | fn concrete_ty() -> OneTy<u32> {
+   |    ^^^^^^^^^^^
+   |
+   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
+note: this opaque type is supposed to be constrained
+  --> $DIR/generic_nondefining_use.rs:11:17
+   |
+LL | type OneTy<T> = impl Debug;
+   |                 ^^^^^^^^^^
+note: this use of `OneTy<u32>` does not have unique universal generic arguments
+  --> $DIR/generic_nondefining_use.rs:23:5
+   |
+LL |     5u32
+   |     ^^^^
+
+error: non-defining use of `OneLifetime<'_>` in the defining scope
+  --> $DIR/generic_nondefining_use.rs:27:1
+   |
+LL | fn concrete_lifetime() -> OneLifetime<'static> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: item does not constrain `OneConst::{opaque#0}`
+  --> $DIR/generic_nondefining_use.rs:35:4
+   |
+LL | fn concrete_const() -> OneConst<{ 123 }> {
+   |    ^^^^^^^^^^^^^^
+   |
+   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
+note: this opaque type is supposed to be constrained
+  --> $DIR/generic_nondefining_use.rs:15:33
+   |
+LL | type OneConst<const X: usize> = impl Debug;
+   |                                 ^^^^^^^^^^
+note: this use of `OneConst<123>` does not have unique universal generic arguments
+  --> $DIR/generic_nondefining_use.rs:38:5
+   |
+LL |     7u32
+   |     ^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/type-alias-impl-trait/generic_nondefining_use.rs b/tests/ui/type-alias-impl-trait/generic_nondefining_use.rs
index cf38c93bd92..7250a9ac0b3 100644
--- a/tests/ui/type-alias-impl-trait/generic_nondefining_use.rs
+++ b/tests/ui/type-alias-impl-trait/generic_nondefining_use.rs
@@ -1,5 +1,9 @@
 #![feature(type_alias_impl_trait)]
 
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
 use std::fmt::Debug;
 
 fn main() {}
@@ -14,18 +18,22 @@ type OneConst<const X: usize> = impl Debug;
 
 #[define_opaque(OneTy)]
 fn concrete_ty() -> OneTy<u32> {
-    //~^ ERROR: expected generic type parameter, found `u32`
+    //[current]~^ ERROR: expected generic type parameter, found `u32`
+    //[next]~^^ ERROR: item does not constrain `OneTy::{opaque#0}`
     5u32
 }
 
 #[define_opaque(OneLifetime)]
 fn concrete_lifetime() -> OneLifetime<'static> {
+    //[next]~^ ERROR: non-defining use of `OneLifetime<'_>` in the defining scope
     6u32
-    //~^ ERROR: expected generic lifetime parameter, found `'static`
+    //[current]~^ ERROR: expected generic lifetime parameter, found `'static`
+
 }
 
 #[define_opaque(OneConst)]
 fn concrete_const() -> OneConst<{ 123 }> {
-    //~^ ERROR: expected generic constant parameter, found `123`
+    //[current]~^ ERROR: expected generic constant parameter, found `123`
+    //[next]~^^ ERROR: item does not constrain `OneConst::{opaque#0}`
     7u32
 }