From ff2b0282991b73c0f65725e42d5fc3ea9defe954 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 16 Oct 2023 20:46:43 +0000 Subject: [PATCH 1/3] Normalize when collecting TAITs in signature --- compiler/rustc_middle/src/ty/util.rs | 16 +- compiler/rustc_ty_utils/src/opaque_types.rs | 242 +++++++++++------- .../issue-90014-tait.rs | 6 + .../issue-90014-tait.stderr | 46 ++-- tests/ui/lint/issue-99387.rs | 4 +- tests/ui/lint/issue-99387.stderr | 15 -- ...n_behind_projection_behind_struct_field.rs | 7 +- ...hind_projection_behind_struct_field.stderr | 20 -- .../higher_kinded_params2.rs | 4 +- .../higher_kinded_params2.stderr | 15 -- .../higher_kinded_params3.rs | 1 - .../higher_kinded_params3.stderr | 15 +- tests/ui/type-alias-impl-trait/issue-70121.rs | 3 +- .../type-alias-impl-trait/issue-70121.stderr | 15 -- 14 files changed, 206 insertions(+), 203 deletions(-) delete mode 100644 tests/ui/lint/issue-99387.stderr delete mode 100644 tests/ui/type-alias-impl-trait/hidden_behind_projection_behind_struct_field.stderr delete mode 100644 tests/ui/type-alias-impl-trait/higher_kinded_params2.stderr delete mode 100644 tests/ui/type-alias-impl-trait/issue-70121.stderr diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 31b52677b2797..b26a7e94dbe98 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -468,8 +468,20 @@ impl<'tcx> TyCtxt<'tcx> { for arg in args { match arg.unpack() { GenericArgKind::Lifetime(lt) => match (ignore_regions, lt.kind()) { - (CheckRegions::Bound, ty::ReLateBound(di, reg)) => { - if !seen_late.insert((di, reg)) { + ( + CheckRegions::Bound, + ty::ReFree(ty::FreeRegion { + bound_region: ty::BoundRegionKind::BrNamed(def_id, _), + .. + }) + | ty::ReLateBound( + _, + ty::BoundRegion { + kind: ty::BoundRegionKind::BrNamed(def_id, _), .. + }, + ), + ) => { + if !seen_late.insert(def_id) { return Err(NotUniqueParam::DuplicateParam(lt.into())); } } diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 06a30677d2005..0551b17d7b3d6 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -2,19 +2,27 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir::intravisit::Visitor; use rustc_hir::{def::DefKind, def_id::LocalDefId}; use rustc_hir::{intravisit, CRATE_HIR_ID}; +use rustc_infer::infer::outlives::env::OutlivesEnvironment; +use rustc_infer::infer::{InferOk, TyCtxtInferExt}; +use rustc_infer::traits::{TraitEngine, TraitEngineExt as _}; use rustc_middle::query::Providers; +use rustc_middle::traits::ObligationCause; use rustc_middle::ty::util::{CheckRegions, NotUniqueParam}; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; -use rustc_span::Span; -use rustc_trait_selection::traits::check_args_compatible; +use rustc_middle::ty::{TypeFoldable, TypeSuperVisitable, TypeVisitableExt, TypeVisitor}; +use rustc_span::{ErrorGuaranteed, Span}; +use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt; +use rustc_trait_selection::traits::project::with_replaced_escaping_bound_vars; +use rustc_trait_selection::traits::{NormalizeExt, TraitEngineExt as _}; use std::ops::ControlFlow; use crate::errors::{DuplicateArg, NotParam}; struct OpaqueTypeCollector<'tcx> { tcx: TyCtxt<'tcx>, + opaques: Vec, + /// The `DefId` of the item which we are collecting opaque types for. item: LocalDefId, @@ -22,11 +30,20 @@ struct OpaqueTypeCollector<'tcx> { seen: FxHashSet, span: Option, + + binder: ty::DebruijnIndex, } impl<'tcx> OpaqueTypeCollector<'tcx> { fn new(tcx: TyCtxt<'tcx>, item: LocalDefId) -> Self { - Self { tcx, opaques: Vec::new(), item, seen: Default::default(), span: None } + Self { + tcx, + opaques: Vec::new(), + item, + seen: Default::default(), + span: None, + binder: ty::INNERMOST, + } } fn span(&self) -> Span { @@ -35,33 +52,91 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { }) } - fn visit_spanned(&mut self, span: Span, value: impl TypeVisitable>) { + fn visit_spanned_after_normalizing( + &mut self, + span: Span, + value: impl TypeFoldable>, + ) { let old = self.span; self.span = Some(span); - value.visit_with(self); - self.span = old; - } - fn parent_trait_ref(&self) -> Option> { - let parent = self.parent()?; - if matches!(self.tcx.def_kind(parent), DefKind::Impl { .. }) { - Some(self.tcx.impl_trait_ref(parent)?.instantiate_identity()) - } else { - None + if let Ok(value) = self.normalize_if_possible(span, value) { + value.visit_with(self); } + + self.span = old; } - fn parent(&self) -> Option { - match self.tcx.def_kind(self.item) { - DefKind::AnonConst | DefKind::InlineConst | DefKind::Fn | DefKind::TyAlias => None, - DefKind::AssocFn | DefKind::AssocTy | DefKind::AssocConst => { - Some(self.tcx.local_parent(self.item)) - } - other => span_bug!( - self.tcx.def_span(self.item), - "unhandled item with opaque types: {other:?}" - ), + fn normalize_if_possible>>( + &self, + span: Span, + value: T, + ) -> Result { + if !value.has_projections() { + return Ok(value); } + + let infcx = self.tcx.infer_ctxt().build(); + let param_env = self.tcx.param_env(self.item); + + with_replaced_escaping_bound_vars( + &infcx, + &mut vec![None; self.binder.as_usize()], + value, + |value| { + let mut fulfill_cx = >::new(&infcx); + + let normalized_value = match infcx + .at(&ObligationCause::misc(span, self.item), param_env) + .deeply_normalize(value, &mut *fulfill_cx) + { + Ok(t) => t, + Err(errors) => { + return Err(self + .tcx + .sess + .delay_span_bug(span, format!("{errors:#?} in {:?}", self.item))); + } + }; + + let InferOk { value: implied_wf_types, obligations } = + infcx.at(&ObligationCause::misc(span, self.item), param_env).normalize( + self.tcx + .assumed_wf_types(self.item) + .iter() + .map(|(ty, _span)| *ty) + .collect::>(), + ); + fulfill_cx.register_predicate_obligations(&infcx, obligations); + + let errors = fulfill_cx.select_all_or_error(&infcx); + if !errors.is_empty() { + return Err(self.tcx.sess.delay_span_bug(span, format!("{errors:#?}"))); + } + + let outlives_env = OutlivesEnvironment::with_bounds( + param_env, + infcx.implied_bounds_tys( + param_env, + self.item, + implied_wf_types.into_iter().collect(), + ), + ); + let errors = infcx.resolve_regions(&outlives_env); + if !errors.is_empty() { + return Err(self.tcx.sess.delay_span_bug(span, format!("{errors:#?}"))); + } + + let resolved_value = match infcx.fully_resolve(normalized_value) { + Ok(resolved_value) => resolved_value, + Err(f) => { + return Err(self.tcx.sess.delay_span_bug(span, format!("{f:?}"))); + } + }; + + Ok(resolved_value) + }, + ) } /// Returns `true` if `opaque_hir_id` is a sibling or a child of a sibling of `self.item`. @@ -100,7 +175,9 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { fn collect_body_and_predicate_taits(&mut self) { // Look at all where bounds. - self.tcx.predicates_of(self.item).instantiate_identity(self.tcx).visit_with(self); + for (pred, span) in self.tcx.predicates_of(self.item).instantiate_identity(self.tcx) { + self.visit_spanned_after_normalizing(span, pred); + } // An item is allowed to constrain opaques declared within its own body (but not nested within // nested functions). self.collect_taits_declared_in_body(); @@ -133,6 +210,16 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { } impl<'tcx> TypeVisitor> for OpaqueTypeCollector<'tcx> { + fn visit_binder>>( + &mut self, + t: &ty::Binder<'tcx, T>, + ) -> ControlFlow { + self.binder.shift_in(1); + t.super_visit_with(self); + self.binder.shift_out(1); + ControlFlow::Continue(()) + } + #[instrument(skip(self), ret, level = "trace")] fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { t.super_visit_with(self)?; @@ -149,7 +236,23 @@ impl<'tcx> TypeVisitor> for OpaqueTypeCollector<'tcx> { rustc_hir::OpaqueTyOrigin::FnReturn(_) | rustc_hir::OpaqueTyOrigin::AsyncFn(_) => {} rustc_hir::OpaqueTyOrigin::TyAlias { in_assoc_ty } => { - if !in_assoc_ty { + if in_assoc_ty { + // Make sure that the TAIT comes from an associated item + // in the same implementation. + let Some(assoc_item) = + self.tcx.opt_associated_item(self.item.to_def_id()) + else { + return ControlFlow::Continue(()); + }; + let mut tait_parent = self.tcx.parent(alias_ty.def_id); + while self.tcx.def_kind(tait_parent) == DefKind::OpaqueTy { + tait_parent = self.tcx.parent(tait_parent); + } + if self.tcx.parent(tait_parent) != assoc_item.container_id(self.tcx) { + return ControlFlow::Continue(()); + } + } else { + // Otherwise, the TAIT must be a sibling of the item. if !self.check_tait_defining_scope(alias_ty.def_id.expect_local()) { return ControlFlow::Continue(()); } @@ -166,15 +269,13 @@ impl<'tcx> TypeVisitor> for OpaqueTypeCollector<'tcx> { // start seeing the error below. // Collect opaque types nested within the associated type bounds of this opaque type. - // We use identity args here, because we already know that the opaque type uses - // only generic parameters, and thus substituting would not give us more information. for (pred, span) in self .tcx .explicit_item_bounds(alias_ty.def_id) - .instantiate_identity_iter_copied() + .iter_instantiated_copied(self.tcx, alias_ty.args) { trace!(?pred); - self.visit_spanned(span, pred); + self.visit_spanned_after_normalizing(span, pred); } } Err(NotUniqueParam::NotParam(arg)) => { @@ -193,61 +294,7 @@ impl<'tcx> TypeVisitor> for OpaqueTypeCollector<'tcx> { } } } - ty::Alias(ty::Weak, alias_ty) if alias_ty.def_id.is_local() => { - self.tcx - .type_of(alias_ty.def_id) - .instantiate(self.tcx, alias_ty.args) - .visit_with(self)?; - } - ty::Alias(ty::Projection, alias_ty) => { - // This avoids having to do normalization of `Self::AssocTy` by only - // supporting the case of a method defining opaque types from assoc types - // in the same impl block. - if let Some(parent_trait_ref) = self.parent_trait_ref() { - // If the trait ref of the associated item and the impl differs, - // then we can't use the impl's identity substitutions below, so - // just skip. - if alias_ty.trait_ref(self.tcx) == parent_trait_ref { - let parent = self.parent().expect("we should have a parent here"); - - for &assoc in self.tcx.associated_items(parent).in_definition_order() { - trace!(?assoc); - if assoc.trait_item_def_id != Some(alias_ty.def_id) { - continue; - } - - // If the type is further specializable, then the type_of - // is not actually correct below. - if !assoc.defaultness(self.tcx).is_final() { - continue; - } - - let impl_args = alias_ty.args.rebase_onto( - self.tcx, - parent_trait_ref.def_id, - ty::GenericArgs::identity_for_item(self.tcx, parent), - ); - - if check_args_compatible(self.tcx, assoc, impl_args) { - return self - .tcx - .type_of(assoc.def_id) - .instantiate(self.tcx, impl_args) - .visit_with(self); - } else { - self.tcx.sess.delay_span_bug( - self.tcx.def_span(assoc.def_id), - "item had incorrect args", - ); - } - } - } - } - } - ty::Adt(def, _) if def.did().is_local() => { - if !self.seen.insert(def.did().expect_local()) { - return ControlFlow::Continue(()); - } + ty::Adt(def, args) if def.did().is_local() => { for variant in def.variants().iter() { for field in variant.fields.iter() { // Don't use the `ty::Adt` args, we either @@ -258,8 +305,8 @@ impl<'tcx> TypeVisitor> for OpaqueTypeCollector<'tcx> { // not found. While we could substitute and walk those, that would mean we // would have to walk all substitutions of an Adt, which can quickly // degenerate into looking at an exponential number of types. - let ty = self.tcx.type_of(field.did).instantiate_identity(); - self.visit_spanned(self.tcx.def_span(field.did), ty); + let ty = self.tcx.type_of(field.did).instantiate(self.tcx, args); + self.visit_spanned_after_normalizing(self.tcx.def_span(field.did), ty); } } } @@ -276,12 +323,15 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [ match kind { // Walk over the signature of the function-like to find the opaques. DefKind::AssocFn | DefKind::Fn => { - let ty_sig = tcx.fn_sig(item).instantiate_identity(); + let ty_sig = tcx.liberate_late_bound_regions( + item.to_def_id(), + tcx.fn_sig(item).instantiate_identity(), + ); let hir_sig = tcx.hir().get_by_def_id(item).fn_sig().unwrap(); // Walk over the inputs and outputs manually in order to get good spans for them. - collector.visit_spanned(hir_sig.decl.output.span(), ty_sig.output()); + collector.visit_spanned_after_normalizing(hir_sig.decl.output.span(), ty_sig.output()); for (hir, ty) in hir_sig.decl.inputs.iter().zip(ty_sig.inputs().iter()) { - collector.visit_spanned(hir.span, ty.map_bound(|x| *x)); + collector.visit_spanned_after_normalizing(hir.span, *ty); } collector.collect_body_and_predicate_taits(); } @@ -291,16 +341,22 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [ Some(ty) => ty.span, _ => tcx.def_span(item), }; - collector.visit_spanned(span, tcx.type_of(item).instantiate_identity()); + collector + .visit_spanned_after_normalizing(span, tcx.type_of(item).instantiate_identity()); collector.collect_body_and_predicate_taits(); } // We're also doing this for `AssocTy` for the wf checks in `check_opaque_meets_bounds` DefKind::TyAlias | DefKind::AssocTy => { - tcx.type_of(item).instantiate_identity().visit_with(&mut collector); + let span = match tcx.hir().get_by_def_id(item).ty() { + Some(ty) => ty.span, + _ => tcx.def_span(item), + }; + collector + .visit_spanned_after_normalizing(span, tcx.type_of(item).instantiate_identity()); } DefKind::OpaqueTy => { for (pred, span) in tcx.explicit_item_bounds(item).instantiate_identity_iter_copied() { - collector.visit_spanned(span, pred); + collector.visit_spanned_after_normalizing(span, pred); } } DefKind::Mod diff --git a/tests/ui/generic-associated-types/issue-90014-tait.rs b/tests/ui/generic-associated-types/issue-90014-tait.rs index 1ce5cd3198767..ea1a612f30824 100644 --- a/tests/ui/generic-associated-types/issue-90014-tait.rs +++ b/tests/ui/generic-associated-types/issue-90014-tait.rs @@ -1,8 +1,14 @@ //! This test is reporting the wrong error. We need //! more inherent associated type tests that use opaque types //! in general. Some variant of this test should compile successfully. + // known-bug: unknown // edition:2018 +// failure-status: 101 +// normalize-stderr-test "note: .*\n\n" -> "" +// normalize-stderr-test "thread 'rustc' panicked.*\n.*\n" -> "" +// normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " +// rustc-env:RUST_BACKTRACE=0 #![feature(impl_trait_in_assoc_type, inherent_associated_types)] #![allow(incomplete_features)] diff --git a/tests/ui/generic-associated-types/issue-90014-tait.stderr b/tests/ui/generic-associated-types/issue-90014-tait.stderr index b86e2a204b047..fdf0f3e09daf0 100644 --- a/tests/ui/generic-associated-types/issue-90014-tait.stderr +++ b/tests/ui/generic-associated-types/issue-90014-tait.stderr @@ -1,22 +1,38 @@ -error[E0308]: mismatched types - --> $DIR/issue-90014-tait.rs:18:9 +error: internal compiler error: no errors encountered even though `delay_span_bug` issued + +error: internal compiler error[E0391]: cycle detected when computing function signature of `::make_fut` + --> $DIR/issue-90014-tait.rs:23:5 | -LL | type Fut<'a> = impl Future; - | ------------------------ the expected future -LL | LL | fn make_fut<'a>(&'a self) -> Self::Fut<'a> { - | ------------- expected `Foo<'_>::Fut<'a>` because of return type -LL | async { () } - | ^^^^^^^^^^^^ expected future, found `async` block + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: ...which requires computing the variances of `Foo`... + --> $DIR/issue-90014-tait.rs:18:1 + | +LL | struct Foo<'a>(&'a mut ()); + | ^^^^^^^^^^^^^^ + = note: ...which requires computing the variances for items in this crate... + = note: ...which again requires computing function signature of `::make_fut`, completing the cycle +note: cycle used when collecting item types in top-level module + --> $DIR/issue-90014-tait.rs:1:1 | - = note: expected opaque type `Foo<'_>::Fut<'a>` - found `async` block `{async block@$DIR/issue-90014-tait.rs:18:9: 18:21}` -note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/issue-90014-tait.rs:17:8 +LL | / //! This test is reporting the wrong error. We need +LL | | //! more inherent associated type tests that use opaque types +LL | | //! in general. Some variant of this test should compile successfully. +LL | | +... | +LL | | +LL | | fn main() {} + | |____________^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information +note: delayed at compiler/rustc_query_system/src/query/job.rs:602:16 - disabled backtrace + --> $DIR/issue-90014-tait.rs:23:5 | LL | fn make_fut<'a>(&'a self) -> Self::Fut<'a> { - | ^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to previous error +query stack during panic: +end of query stack +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/lint/issue-99387.rs b/tests/ui/lint/issue-99387.rs index 571d4194fe78f..d2766c78e5210 100644 --- a/tests/ui/lint/issue-99387.rs +++ b/tests/ui/lint/issue-99387.rs @@ -1,5 +1,4 @@ -//! Test that we don't follow through projections to find -//! opaque types. +// check-pass #![feature(type_alias_impl_trait)] #![allow(private_interfaces)] @@ -19,7 +18,6 @@ impl<'a> Tr for &'a () { } pub fn ohno<'a>() -> <&'a () as Tr>::Item { - //~^ ERROR item constrains opaque type that is not in its signature None.into_iter() } diff --git a/tests/ui/lint/issue-99387.stderr b/tests/ui/lint/issue-99387.stderr deleted file mode 100644 index 3a46ce7e1952d..0000000000000 --- a/tests/ui/lint/issue-99387.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: item constrains opaque type that is not in its signature - --> $DIR/issue-99387.rs:21:22 - | -LL | pub fn ohno<'a>() -> <&'a () as Tr>::Item { - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: this item must mention the opaque type in its signature in order to be able to register hidden types -note: this item must mention the opaque type in its signature in order to be able to register hidden types - --> $DIR/issue-99387.rs:21:8 - | -LL | pub fn ohno<'a>() -> <&'a () as Tr>::Item { - | ^^^^ - -error: aborting due to previous error - diff --git a/tests/ui/type-alias-impl-trait/hidden_behind_projection_behind_struct_field.rs b/tests/ui/type-alias-impl-trait/hidden_behind_projection_behind_struct_field.rs index eb19b49c7e213..be00bbacc7d50 100644 --- a/tests/ui/type-alias-impl-trait/hidden_behind_projection_behind_struct_field.rs +++ b/tests/ui/type-alias-impl-trait/hidden_behind_projection_behind_struct_field.rs @@ -1,8 +1,4 @@ -//! This test shows that a field type that is a projection that resolves to an opaque, -//! is not a defining use. While we could substitute the struct generics, that would -//! mean we would have to walk all substitutions of an `Foo`, which can quickly -//! degenerate into looking at an exponential number of types depending on the complexity -//! of a program. +// check-pass #![feature(impl_trait_in_assoc_type)] @@ -17,7 +13,6 @@ impl Trait for Bar { type Assoc = impl std::fmt::Debug; fn foo() -> Foo { Foo { field: () } - //~^ ERROR: mismatched types } } diff --git a/tests/ui/type-alias-impl-trait/hidden_behind_projection_behind_struct_field.stderr b/tests/ui/type-alias-impl-trait/hidden_behind_projection_behind_struct_field.stderr deleted file mode 100644 index 648efd1cbfe7c..0000000000000 --- a/tests/ui/type-alias-impl-trait/hidden_behind_projection_behind_struct_field.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/hidden_behind_projection_behind_struct_field.rs:19:22 - | -LL | type Assoc = impl std::fmt::Debug; - | -------------------- the expected opaque type -LL | fn foo() -> Foo { -LL | Foo { field: () } - | ^^ expected opaque type, found `()` - | - = note: expected opaque type `::Assoc` - found unit type `()` -note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/hidden_behind_projection_behind_struct_field.rs:18:8 - | -LL | fn foo() -> Foo { - | ^^^ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type-alias-impl-trait/higher_kinded_params2.rs b/tests/ui/type-alias-impl-trait/higher_kinded_params2.rs index f011e5b214813..9a872ebb933a2 100644 --- a/tests/ui/type-alias-impl-trait/higher_kinded_params2.rs +++ b/tests/ui/type-alias-impl-trait/higher_kinded_params2.rs @@ -1,5 +1,4 @@ -//! This test checks the behaviour of walking into binders -//! and normalizing something behind them actually works. +// check-pass // edition: 2021 @@ -24,7 +23,6 @@ type Successors<'a> = impl std::fmt::Debug + 'a; impl Terminator { fn successors(&self, mut f: for<'x> fn(&'x ()) -> <&'x A as B>::C) -> Successors<'_> { f = g; - //~^ ERROR item constrains opaque type that is not in its signature } } diff --git a/tests/ui/type-alias-impl-trait/higher_kinded_params2.stderr b/tests/ui/type-alias-impl-trait/higher_kinded_params2.stderr deleted file mode 100644 index 39f584dd49ca3..0000000000000 --- a/tests/ui/type-alias-impl-trait/higher_kinded_params2.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: item constrains opaque type that is not in its signature - --> $DIR/higher_kinded_params2.rs:26:13 - | -LL | f = g; - | ^ - | - = note: this item must mention the opaque type in its signature in order to be able to register hidden types -note: this item must mention the opaque type in its signature in order to be able to register hidden types - --> $DIR/higher_kinded_params2.rs:25:8 - | -LL | fn successors(&self, mut f: for<'x> fn(&'x ()) -> <&'x A as B>::C) -> Successors<'_> { - | ^^^^^^^^^^ - -error: aborting due to previous error - diff --git a/tests/ui/type-alias-impl-trait/higher_kinded_params3.rs b/tests/ui/type-alias-impl-trait/higher_kinded_params3.rs index 6edfccaf7d179..51921c98fa37c 100644 --- a/tests/ui/type-alias-impl-trait/higher_kinded_params3.rs +++ b/tests/ui/type-alias-impl-trait/higher_kinded_params3.rs @@ -25,7 +25,6 @@ impl Terminator { fn successors(&self, mut f: for<'x> fn(&'x ()) -> <&'x A as B>::C) -> Successors<'_> { f = g; //~^ ERROR mismatched types - //~| ERROR item constrains opaque type that is not in its signature } } diff --git a/tests/ui/type-alias-impl-trait/higher_kinded_params3.stderr b/tests/ui/type-alias-impl-trait/higher_kinded_params3.stderr index 14372d8f3e64d..aaba9ad5ca704 100644 --- a/tests/ui/type-alias-impl-trait/higher_kinded_params3.stderr +++ b/tests/ui/type-alias-impl-trait/higher_kinded_params3.stderr @@ -1,16 +1,3 @@ -error: item constrains opaque type that is not in its signature - --> $DIR/higher_kinded_params3.rs:26:13 - | -LL | f = g; - | ^ - | - = note: this item must mention the opaque type in its signature in order to be able to register hidden types -note: this item must mention the opaque type in its signature in order to be able to register hidden types - --> $DIR/higher_kinded_params3.rs:25:8 - | -LL | fn successors(&self, mut f: for<'x> fn(&'x ()) -> <&'x A as B>::C) -> Successors<'_> { - | ^^^^^^^^^^ - error[E0308]: mismatched types --> $DIR/higher_kinded_params3.rs:26:9 | @@ -23,6 +10,6 @@ LL | f = g; = note: expected fn pointer `for<'x> fn(&'x ()) -> Tait<'x>` found fn pointer `for<'a> fn(&'a ()) -> &'a ()` -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type-alias-impl-trait/issue-70121.rs b/tests/ui/type-alias-impl-trait/issue-70121.rs index bfd8d8872e37f..dff0d89d465dd 100644 --- a/tests/ui/type-alias-impl-trait/issue-70121.rs +++ b/tests/ui/type-alias-impl-trait/issue-70121.rs @@ -1,3 +1,5 @@ +// check-pass + #![feature(type_alias_impl_trait)] pub type Successors<'a> = impl Iterator; @@ -15,7 +17,6 @@ impl<'a> Tr for &'a () { } pub fn kazusa<'a>() -> <&'a () as Tr>::Item { - //~^ ERROR item constrains opaque type that is not in its signature None.into_iter() } diff --git a/tests/ui/type-alias-impl-trait/issue-70121.stderr b/tests/ui/type-alias-impl-trait/issue-70121.stderr deleted file mode 100644 index 30c3ddd8659d1..0000000000000 --- a/tests/ui/type-alias-impl-trait/issue-70121.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: item constrains opaque type that is not in its signature - --> $DIR/issue-70121.rs:17:24 - | -LL | pub fn kazusa<'a>() -> <&'a () as Tr>::Item { - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: this item must mention the opaque type in its signature in order to be able to register hidden types -note: this item must mention the opaque type in its signature in order to be able to register hidden types - --> $DIR/issue-70121.rs:17:8 - | -LL | pub fn kazusa<'a>() -> <&'a () as Tr>::Item { - | ^^^^^^ - -error: aborting due to previous error - From 16a8908325381579b6d0d9819f0bec7015236151 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 19 Oct 2023 23:01:29 +0000 Subject: [PATCH 2/3] Track seen types --- compiler/rustc_ty_utils/src/opaque_types.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 0551b17d7b3d6..422fada35dc19 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -27,7 +27,7 @@ struct OpaqueTypeCollector<'tcx> { item: LocalDefId, /// Avoid infinite recursion due to recursive declarations. - seen: FxHashSet, + seen: FxHashSet>, span: Option, @@ -222,13 +222,16 @@ impl<'tcx> TypeVisitor> for OpaqueTypeCollector<'tcx> { #[instrument(skip(self), ret, level = "trace")] fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { + // Erase all free and escaping bound regions, to make sure that + // we're not walking into a type that contains itself modulo + // regions. + if !self.seen.insert(self.tcx.fold_regions(t, |_, _| self.tcx.lifetimes.re_erased)) { + return ControlFlow::Continue(()); + } + t.super_visit_with(self)?; match t.kind() { ty::Alias(ty::Opaque, alias_ty) if alias_ty.def_id.is_local() => { - if !self.seen.insert(alias_ty.def_id.expect_local()) { - return ControlFlow::Continue(()); - } - // TAITs outside their defining scopes are ignored. let origin = self.tcx.opaque_type_origin(alias_ty.def_id.expect_local()); trace!(?origin); From 2509374a88106e25e3b4c6987906f36c7c27dc21 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 20 Oct 2023 16:09:29 +0000 Subject: [PATCH 3/3] Consider all mentions of TAIT as defining for now --- compiler/rustc_middle/src/ty/util.rs | 25 +-------- compiler/rustc_ty_utils/src/opaque_types.rs | 56 +++---------------- .../issue-88595.stderr | 12 ++-- .../type-alias-impl-trait/bound_reduction2.rs | 1 - .../bound_reduction2.stderr | 16 +----- .../generic_duplicate_lifetime_param.rs | 1 - .../generic_duplicate_lifetime_param.stderr | 16 +----- .../generic_duplicate_param_use.rs | 3 - .../generic_duplicate_param_use.stderr | 44 ++------------- .../generic_nondefining_use.rs | 3 - .../generic_nondefining_use.stderr | 44 ++------------- tests/ui/type-alias-impl-trait/issue-60564.rs | 1 - .../type-alias-impl-trait/issue-60564.stderr | 16 +----- .../issue-68368-non-defining-use-2.rs | 3 +- .../issue-68368-non-defining-use-2.stderr | 14 +---- .../issue-68368-non-defining-use.rs | 1 - .../issue-68368-non-defining-use.stderr | 14 +---- tests/ui/type-alias-impl-trait/multi-error.rs | 2 +- .../type-alias-impl-trait/multi-error.stderr | 15 ++--- .../non-defining-method.rs | 2 +- .../non-defining-method.stderr | 14 ++--- 21 files changed, 48 insertions(+), 255 deletions(-) diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index b26a7e94dbe98..5319dcde5c80a 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -38,9 +38,6 @@ pub enum CheckRegions { /// Only permit early bound regions. This is useful for Adts which /// can never have late bound regions. OnlyEarlyBound, - /// Permit both late bound and early bound regions. Use this for functions, - /// which frequently have late bound regions. - Bound, } #[derive(Copy, Clone, Debug)] @@ -464,33 +461,15 @@ impl<'tcx> TyCtxt<'tcx> { ignore_regions: CheckRegions, ) -> Result<(), NotUniqueParam<'tcx>> { let mut seen = GrowableBitSet::default(); - let mut seen_late = FxHashSet::default(); for arg in args { match arg.unpack() { GenericArgKind::Lifetime(lt) => match (ignore_regions, lt.kind()) { - ( - CheckRegions::Bound, - ty::ReFree(ty::FreeRegion { - bound_region: ty::BoundRegionKind::BrNamed(def_id, _), - .. - }) - | ty::ReLateBound( - _, - ty::BoundRegion { - kind: ty::BoundRegionKind::BrNamed(def_id, _), .. - }, - ), - ) => { - if !seen_late.insert(def_id) { - return Err(NotUniqueParam::DuplicateParam(lt.into())); - } - } - (CheckRegions::OnlyEarlyBound | CheckRegions::Bound, ty::ReEarlyBound(p)) => { + (CheckRegions::OnlyEarlyBound, ty::ReEarlyBound(p)) => { if !seen.insert(p.index) { return Err(NotUniqueParam::DuplicateParam(lt.into())); } } - (CheckRegions::OnlyEarlyBound | CheckRegions::Bound, _) => { + (CheckRegions::OnlyEarlyBound, _) => { return Err(NotUniqueParam::NotParam(lt.into())); } (CheckRegions::No, _) => {} diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 422fada35dc19..14c5fb64af696 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -7,7 +7,6 @@ use rustc_infer::infer::{InferOk, TyCtxtInferExt}; use rustc_infer::traits::{TraitEngine, TraitEngineExt as _}; use rustc_middle::query::Providers; use rustc_middle::traits::ObligationCause; -use rustc_middle::ty::util::{CheckRegions, NotUniqueParam}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{TypeFoldable, TypeSuperVisitable, TypeVisitableExt, TypeVisitor}; use rustc_span::{ErrorGuaranteed, Span}; @@ -16,8 +15,6 @@ use rustc_trait_selection::traits::project::with_replaced_escaping_bound_vars; use rustc_trait_selection::traits::{NormalizeExt, TraitEngineExt as _}; use std::ops::ControlFlow; -use crate::errors::{DuplicateArg, NotParam}; - struct OpaqueTypeCollector<'tcx> { tcx: TyCtxt<'tcx>, @@ -46,12 +43,6 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { } } - fn span(&self) -> Span { - self.span.unwrap_or_else(|| { - self.tcx.def_ident_span(self.item).unwrap_or_else(|| self.tcx.def_span(self.item)) - }) - } - fn visit_spanned_after_normalizing( &mut self, span: Span, @@ -265,49 +256,19 @@ impl<'tcx> TypeVisitor> for OpaqueTypeCollector<'tcx> { self.opaques.push(alias_ty.def_id.expect_local()); - match self.tcx.uses_unique_generic_params(alias_ty.args, CheckRegions::Bound) { - Ok(()) => { - // FIXME: implement higher kinded lifetime bounds on nested opaque types. They are not - // supported at all, so this is sound to do, but once we want to support them, you'll - // start seeing the error below. - - // Collect opaque types nested within the associated type bounds of this opaque type. - for (pred, span) in self - .tcx - .explicit_item_bounds(alias_ty.def_id) - .iter_instantiated_copied(self.tcx, alias_ty.args) - { - trace!(?pred); - self.visit_spanned_after_normalizing(span, pred); - } - } - Err(NotUniqueParam::NotParam(arg)) => { - self.tcx.sess.emit_err(NotParam { - arg, - span: self.span(), - opaque_span: self.tcx.def_span(alias_ty.def_id), - }); - } - Err(NotUniqueParam::DuplicateParam(arg)) => { - self.tcx.sess.emit_err(DuplicateArg { - arg, - span: self.span(), - opaque_span: self.tcx.def_span(alias_ty.def_id), - }); - } + // Collect opaque types nested within the associated type bounds of this opaque type. + for (pred, span) in self + .tcx + .explicit_item_bounds(alias_ty.def_id) + .iter_instantiated_copied(self.tcx, alias_ty.args) + { + trace!(?pred); + self.visit_spanned_after_normalizing(span, pred); } } ty::Adt(def, args) if def.did().is_local() => { for variant in def.variants().iter() { for field in variant.fields.iter() { - // Don't use the `ty::Adt` args, we either - // * found the opaque in the args - // * will find the opaque in the unsubstituted fields - // The only other situation that can occur is that after substituting, - // some projection resolves to an opaque that we would have otherwise - // not found. While we could substitute and walk those, that would mean we - // would have to walk all substitutions of an Adt, which can quickly - // degenerate into looking at an exponential number of types. let ty = self.tcx.type_of(field.did).instantiate(self.tcx, args); self.visit_spanned_after_normalizing(self.tcx.def_span(field.did), ty); } @@ -315,6 +276,7 @@ impl<'tcx> TypeVisitor> for OpaqueTypeCollector<'tcx> { } _ => trace!(kind=?t.kind()), } + ControlFlow::Continue(()) } } diff --git a/tests/ui/generic-associated-types/issue-88595.stderr b/tests/ui/generic-associated-types/issue-88595.stderr index 2b1a25acfa430..79d3479af8c8f 100644 --- a/tests/ui/generic-associated-types/issue-88595.stderr +++ b/tests/ui/generic-associated-types/issue-88595.stderr @@ -1,14 +1,16 @@ error: non-defining opaque type use in defining scope - --> $DIR/issue-88595.rs:21:23 + --> $DIR/issue-88595.rs:21:35 | LL | fn a(&'a self) -> Self::B<'a> {} - | ^^^^^^^^^^^ generic argument `'a` used twice + | ^^ | -note: for this opaque type - --> $DIR/issue-88595.rs:19:18 +note: lifetime used multiple times + --> $DIR/issue-88595.rs:18:6 | +LL | impl<'a> A<'a> for C { + | ^^ LL | type B<'b> = impl Clone; - | ^^^^^^^^^^ + | ^^ error: aborting due to previous error diff --git a/tests/ui/type-alias-impl-trait/bound_reduction2.rs b/tests/ui/type-alias-impl-trait/bound_reduction2.rs index 4e9f65d88a129..0bcc9e002ca04 100644 --- a/tests/ui/type-alias-impl-trait/bound_reduction2.rs +++ b/tests/ui/type-alias-impl-trait/bound_reduction2.rs @@ -13,7 +13,6 @@ trait Trait {} impl Trait for () {} fn foo_desugared(_: T) -> Foo { - //~^ ERROR non-defining opaque type use () //~^ ERROR expected generic type parameter, found `::Assoc` } diff --git a/tests/ui/type-alias-impl-trait/bound_reduction2.stderr b/tests/ui/type-alias-impl-trait/bound_reduction2.stderr index 14f9dbbdb4e93..3c259bd9e97cc 100644 --- a/tests/ui/type-alias-impl-trait/bound_reduction2.stderr +++ b/tests/ui/type-alias-impl-trait/bound_reduction2.stderr @@ -1,17 +1,5 @@ -error[E0792]: non-defining opaque type use in defining scope - --> $DIR/bound_reduction2.rs:15:46 - | -LL | fn foo_desugared(_: T) -> Foo { - | ^^^^^^^^^^^^^ argument `::Assoc` is not a generic parameter - | -note: for this opaque type - --> $DIR/bound_reduction2.rs:9:15 - | -LL | type Foo = impl Trait; - | ^^^^^^^^^^^^^ - error[E0792]: expected generic type parameter, found `::Assoc` - --> $DIR/bound_reduction2.rs:17:5 + --> $DIR/bound_reduction2.rs:16:5 | LL | type Foo = impl Trait; | - this generic parameter must be used with a generic type parameter @@ -19,6 +7,6 @@ LL | type Foo = impl Trait; LL | () | ^^ -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs index 169d4f8d50941..e1e830bb577c7 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs @@ -5,7 +5,6 @@ fn main() {} type Two<'a, 'b> = impl std::fmt::Debug; fn one<'a>(t: &'a ()) -> Two<'a, 'a> { - //~^ ERROR non-defining opaque type use t //~^ ERROR non-defining opaque type use } diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr index b03bf2466e60c..bcae0fd2c6cf5 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr @@ -1,17 +1,5 @@ error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_lifetime_param.rs:7:26 - | -LL | fn one<'a>(t: &'a ()) -> Two<'a, 'a> { - | ^^^^^^^^^^^ generic argument `'a` used twice - | -note: for this opaque type - --> $DIR/generic_duplicate_lifetime_param.rs:5:20 - | -LL | type Two<'a, 'b> = impl std::fmt::Debug; - | ^^^^^^^^^^^^^^^^^^^^ - -error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_lifetime_param.rs:9:5 + --> $DIR/generic_duplicate_lifetime_param.rs:8:5 | LL | t | ^ @@ -22,5 +10,5 @@ note: lifetime used multiple times LL | type Two<'a, 'b> = impl std::fmt::Debug; | ^^ ^^ -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.rs index e3c6f4d874bcb..dd24dafe40118 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.rs +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.rs @@ -19,19 +19,16 @@ type TwoLifetimes<'a, 'b> = impl Debug; type TwoConsts = impl Debug; fn one_ty(t: T) -> TwoTys { - //~^ ERROR non-defining opaque type use in defining scope t //~^ ERROR non-defining opaque type use in defining scope } fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> { - //~^ ERROR non-defining opaque type use in defining scope t //~^ ERROR non-defining opaque type use in defining scope } fn one_const(t: *mut [u8; N]) -> TwoConsts { - //~^ ERROR non-defining opaque type use in defining scope t //~^ ERROR non-defining opaque type use in defining scope } diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr index 495308a6cace1..f4fef77514406 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr @@ -1,17 +1,5 @@ error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_param_use.rs:21:30 - | -LL | fn one_ty(t: T) -> TwoTys { - | ^^^^^^^^^^^^ generic argument `T` used twice - | -note: for this opaque type - --> $DIR/generic_duplicate_param_use.rs:15:21 - | -LL | type TwoTys = impl Debug; - | ^^^^^^^^^^ - -error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_param_use.rs:23:5 + --> $DIR/generic_duplicate_param_use.rs:22:5 | LL | t | ^ @@ -23,19 +11,7 @@ LL | type TwoTys = impl Debug; | ^ ^ error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_param_use.rs:27:36 - | -LL | fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> { - | ^^^^^^^^^^^^^^^^^^^^ generic argument `'a` used twice - | -note: for this opaque type - --> $DIR/generic_duplicate_param_use.rs:17:29 - | -LL | type TwoLifetimes<'a, 'b> = impl Debug; - | ^^^^^^^^^^ - -error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_param_use.rs:29:5 + --> $DIR/generic_duplicate_param_use.rs:27:5 | LL | t | ^ @@ -47,19 +23,7 @@ LL | type TwoLifetimes<'a, 'b> = impl Debug; | ^^ ^^ error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_param_use.rs:33:50 - | -LL | fn one_const(t: *mut [u8; N]) -> TwoConsts { - | ^^^^^^^^^^^^^^^ generic argument `N` used twice - | -note: for this opaque type - --> $DIR/generic_duplicate_param_use.rs:19:50 - | -LL | type TwoConsts = impl Debug; - | ^^^^^^^^^^ - -error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_param_use.rs:35:5 + --> $DIR/generic_duplicate_param_use.rs:32:5 | LL | t | ^ @@ -70,5 +34,5 @@ note: constant used multiple times LL | type TwoConsts = impl Debug; | ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ -error: aborting due to 6 previous errors +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 68f4c6923ae18..f0bb1c75dcd39 100644 --- a/tests/ui/type-alias-impl-trait/generic_nondefining_use.rs +++ b/tests/ui/type-alias-impl-trait/generic_nondefining_use.rs @@ -13,19 +13,16 @@ type OneConst = impl Debug; // Not defining uses, because they doesn't define *all* possible generics. fn concrete_ty() -> OneTy { - //~^ ERROR: non-defining opaque type use in defining scope 5u32 //~^ ERROR: expected generic type parameter, found `u32` } fn concrete_lifetime() -> OneLifetime<'static> { - //~^ ERROR: non-defining opaque type use in defining scope 6u32 //~^ ERROR: expected generic lifetime parameter, found `'static` } fn concrete_const() -> OneConst<{ 123 }> { - //~^ ERROR: non-defining opaque type use in defining scope 7u32 //~^ ERROR: expected generic constant parameter, found `123` } diff --git a/tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr b/tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr index e3b7b1a76b09d..966fe823f024d 100644 --- a/tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr +++ b/tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr @@ -1,17 +1,5 @@ -error[E0792]: non-defining opaque type use in defining scope - --> $DIR/generic_nondefining_use.rs:15:21 - | -LL | fn concrete_ty() -> OneTy { - | ^^^^^^^^^^ argument `u32` is not a generic parameter - | -note: for this opaque type - --> $DIR/generic_nondefining_use.rs:7:17 - | -LL | type OneTy = impl Debug; - | ^^^^^^^^^^ - error[E0792]: expected generic type parameter, found `u32` - --> $DIR/generic_nondefining_use.rs:17:5 + --> $DIR/generic_nondefining_use.rs:16:5 | LL | type OneTy = impl Debug; | - this generic parameter must be used with a generic type parameter @@ -19,20 +7,8 @@ LL | type OneTy = impl Debug; LL | 5u32 | ^^^^ -error[E0792]: non-defining opaque type use in defining scope - --> $DIR/generic_nondefining_use.rs:21:27 - | -LL | fn concrete_lifetime() -> OneLifetime<'static> { - | ^^^^^^^^^^^^^^^^^^^^ argument `'static` is not a generic parameter - | -note: for this opaque type - --> $DIR/generic_nondefining_use.rs:9:24 - | -LL | type OneLifetime<'a> = impl Debug; - | ^^^^^^^^^^ - error[E0792]: expected generic lifetime parameter, found `'static` - --> $DIR/generic_nondefining_use.rs:23:5 + --> $DIR/generic_nondefining_use.rs:21: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 @@ -40,20 +16,8 @@ LL | type OneLifetime<'a> = impl Debug; LL | 6u32 | ^^^^ -error[E0792]: non-defining opaque type use in defining scope - --> $DIR/generic_nondefining_use.rs:27:24 - | -LL | fn concrete_const() -> OneConst<{ 123 }> { - | ^^^^^^^^^^^^^^^^^ argument `123` is not a generic parameter - | -note: for this opaque type - --> $DIR/generic_nondefining_use.rs:11:33 - | -LL | type OneConst = impl Debug; - | ^^^^^^^^^^ - error[E0792]: expected generic constant parameter, found `123` - --> $DIR/generic_nondefining_use.rs:29:5 + --> $DIR/generic_nondefining_use.rs:26:5 | LL | type OneConst = impl Debug; | -------------- this generic parameter must be used with a generic constant parameter @@ -61,6 +25,6 @@ LL | type OneConst = impl Debug; LL | 7u32 | ^^^^ -error: aborting due to 6 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/issue-60564.rs b/tests/ui/type-alias-impl-trait/issue-60564.rs index 48bd70bcca950..c2f4c37080746 100644 --- a/tests/ui/type-alias-impl-trait/issue-60564.rs +++ b/tests/ui/type-alias-impl-trait/issue-60564.rs @@ -17,7 +17,6 @@ where { type BitsIter = IterBitsIter; fn iter_bits(self, n: u8) -> Self::BitsIter { - //~^ ERROR non-defining opaque type use (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap()) //~^ ERROR expected generic type parameter, found `u8` } diff --git a/tests/ui/type-alias-impl-trait/issue-60564.stderr b/tests/ui/type-alias-impl-trait/issue-60564.stderr index d42495e934d33..f8fdb004d0989 100644 --- a/tests/ui/type-alias-impl-trait/issue-60564.stderr +++ b/tests/ui/type-alias-impl-trait/issue-60564.stderr @@ -1,17 +1,5 @@ -error[E0792]: non-defining opaque type use in defining scope - --> $DIR/issue-60564.rs:19:34 - | -LL | fn iter_bits(self, n: u8) -> Self::BitsIter { - | ^^^^^^^^^^^^^^ argument `u8` is not a generic parameter - | -note: for this opaque type - --> $DIR/issue-60564.rs:8:30 - | -LL | type IterBitsIter = impl std::iter::Iterator; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error[E0792]: expected generic type parameter, found `u8` - --> $DIR/issue-60564.rs:21:9 + --> $DIR/issue-60564.rs:20:9 | LL | type IterBitsIter = impl std::iter::Iterator; | - this generic parameter must be used with a generic type parameter @@ -19,6 +7,6 @@ LL | type IterBitsIter = impl std::iter::Iterator; LL | (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs index 9dcdb578568aa..5e0a82a72868a 100644 --- a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs +++ b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs @@ -7,8 +7,7 @@ trait Trait {} type Alias<'a, U> = impl Trait; fn f<'a>() -> Alias<'a, ()> {} -//~^ ERROR non-defining opaque type use -//~| ERROR expected generic type parameter, found `()` +//~^ ERROR expected generic type parameter, found `()` fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr index 085bffe907b4b..271743a4010c8 100644 --- a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr +++ b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr @@ -1,15 +1,3 @@ -error[E0792]: non-defining opaque type use in defining scope - --> $DIR/issue-68368-non-defining-use-2.rs:9:15 - | -LL | fn f<'a>() -> Alias<'a, ()> {} - | ^^^^^^^^^^^^^ argument `()` is not a generic parameter - | -note: for this opaque type - --> $DIR/issue-68368-non-defining-use-2.rs:7:21 - | -LL | type Alias<'a, U> = impl Trait; - | ^^^^^^^^^^^^^ - error[E0792]: expected generic type parameter, found `()` --> $DIR/issue-68368-non-defining-use-2.rs:9:29 | @@ -19,6 +7,6 @@ LL | LL | fn f<'a>() -> Alias<'a, ()> {} | ^^ -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs index dfe2ee8204c75..3b32260c96fe1 100644 --- a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs +++ b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs @@ -8,7 +8,6 @@ type Alias<'a, U> = impl Trait; fn f<'a>() -> Alias<'a, ()> {} //~^ ERROR expected generic type parameter, found `()` -//~| ERROR non-defining opaque type use fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr index ea704ffff97ab..4d9a8d6eef915 100644 --- a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr +++ b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr @@ -1,15 +1,3 @@ -error[E0792]: non-defining opaque type use in defining scope - --> $DIR/issue-68368-non-defining-use.rs:9:15 - | -LL | fn f<'a>() -> Alias<'a, ()> {} - | ^^^^^^^^^^^^^ argument `()` is not a generic parameter - | -note: for this opaque type - --> $DIR/issue-68368-non-defining-use.rs:7:21 - | -LL | type Alias<'a, U> = impl Trait; - | ^^^^^^^^^^^^^ - error[E0792]: expected generic type parameter, found `()` --> $DIR/issue-68368-non-defining-use.rs:9:29 | @@ -19,6 +7,6 @@ LL | LL | fn f<'a>() -> Alias<'a, ()> {} | ^^ -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/multi-error.rs b/tests/ui/type-alias-impl-trait/multi-error.rs index b5ff06572d06e..a2de9789483f5 100644 --- a/tests/ui/type-alias-impl-trait/multi-error.rs +++ b/tests/ui/type-alias-impl-trait/multi-error.rs @@ -15,8 +15,8 @@ impl Foo for () { type Bar = impl Sized; type Baz = impl Sized; fn foo() -> (Self::Bar, Self::Baz) { - //~^ ERROR non-defining opaque type use ((), ()) + //~^ ERROR expected generic type parameter, found `u32` } } diff --git a/tests/ui/type-alias-impl-trait/multi-error.stderr b/tests/ui/type-alias-impl-trait/multi-error.stderr index b2de2effea662..15a343da02331 100644 --- a/tests/ui/type-alias-impl-trait/multi-error.stderr +++ b/tests/ui/type-alias-impl-trait/multi-error.stderr @@ -1,14 +1,11 @@ -error[E0792]: non-defining opaque type use in defining scope - --> $DIR/multi-error.rs:17:17 - | -LL | fn foo() -> (Self::Bar, Self::Baz) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument `u32` is not a generic parameter - | -note: for this opaque type - --> $DIR/multi-error.rs:15:19 +error[E0792]: expected generic type parameter, found `u32` + --> $DIR/multi-error.rs:18:9 | LL | type Bar = impl Sized; - | ^^^^^^^^^^ + | - this generic parameter must be used with a generic type parameter +... +LL | ((), ()) + | ^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/type-alias-impl-trait/non-defining-method.rs b/tests/ui/type-alias-impl-trait/non-defining-method.rs index 2f4a7052f7221..02e3d0e08830a 100644 --- a/tests/ui/type-alias-impl-trait/non-defining-method.rs +++ b/tests/ui/type-alias-impl-trait/non-defining-method.rs @@ -14,7 +14,7 @@ trait Foo { impl Foo for () { type Bar = impl Sized; fn foo() -> Self::Bar {} - //~^ ERROR non-defining opaque type use + //~^ ERROR expected generic type parameter, found `u32` fn bar() -> Self::Bar {} } diff --git a/tests/ui/type-alias-impl-trait/non-defining-method.stderr b/tests/ui/type-alias-impl-trait/non-defining-method.stderr index ed5590f9d7174..b34847a400842 100644 --- a/tests/ui/type-alias-impl-trait/non-defining-method.stderr +++ b/tests/ui/type-alias-impl-trait/non-defining-method.stderr @@ -1,14 +1,10 @@ -error[E0792]: non-defining opaque type use in defining scope - --> $DIR/non-defining-method.rs:16:17 - | -LL | fn foo() -> Self::Bar {} - | ^^^^^^^^^^^^^^ argument `u32` is not a generic parameter - | -note: for this opaque type - --> $DIR/non-defining-method.rs:15:19 +error[E0792]: expected generic type parameter, found `u32` + --> $DIR/non-defining-method.rs:16:32 | LL | type Bar = impl Sized; - | ^^^^^^^^^^ + | - this generic parameter must be used with a generic type parameter +LL | fn foo() -> Self::Bar {} + | ^^ error: aborting due to previous error