From 4c99872efe97c8e6183dfc9b729bc3a2903ac40b Mon Sep 17 00:00:00 2001 From: Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> Date: Thu, 15 Jun 2023 09:41:14 +0000 Subject: [PATCH 01/11] Require TAITs to be mentioned in the signatures of functions that register hidden types for them --- compiler/rustc_error_messages/src/lib.rs | 3 +- compiler/rustc_hir_analysis/messages.ftl | 3 + .../src/collect/type_of/opaque.rs | 11 +- compiler/rustc_hir_analysis/src/errors.rs | 10 + compiler/rustc_hir_typeck/src/inherited.rs | 2 +- .../infer/error_reporting/note_and_explain.rs | 2 +- .../rustc_trait_selection/src/traits/mod.rs | 2 +- compiler/rustc_ty_utils/src/opaque_types.rs | 224 +++++++++++++++--- .../feature-gate-type_alias_impl_trait.rs | 6 +- .../issue-90014-tait.rs | 23 ++ .../issue-90014-tait.stderr | 22 ++ .../issue-90014-tait2.rs | 46 ++++ .../issue-90014-tait2.stderr | 12 + .../deduce-signature-from-supertrait.rs | 4 +- tests/ui/impl-trait/in-assoc-type.rs | 3 + tests/ui/impl-trait/in-assoc-type.stderr | 4 +- tests/ui/impl-trait/issues/issue-70877.rs | 4 +- tests/ui/impl-trait/issues/issue-70877.stderr | 6 +- tests/ui/impl-trait/issues/issue-74282.rs | 9 +- tests/ui/impl-trait/issues/issue-74282.stderr | 18 +- tests/ui/impl-trait/issues/issue-78722-2.rs | 22 ++ .../ui/impl-trait/issues/issue-78722-2.stderr | 32 +++ tests/ui/impl-trait/issues/issue-78722.rs | 3 +- tests/ui/impl-trait/issues/issue-78722.stderr | 6 +- .../new-solver/dont-remap-tait-substs.rs | 2 +- .../dont-type_of-tait-in-defining-scope.rs | 6 +- tests/ui/traits/new-solver/tait-eq-proj-2.rs | 6 +- tests/ui/traits/new-solver/tait-eq-proj.rs | 2 +- tests/ui/traits/new-solver/tait-eq-tait.rs | 9 +- .../type-alias-impl-trait/bound_reduction2.rs | 1 + .../bound_reduction2.stderr | 16 +- .../ui/type-alias-impl-trait/closure_args.rs | 11 +- .../ui/type-alias-impl-trait/closure_args2.rs | 23 +- .../declared_but_not_defined_in_scope.stderr | 5 + .../different_defining_uses_never_type-2.rs | 3 +- ...ifferent_defining_uses_never_type-2.stderr | 6 +- .../different_defining_uses_never_type-3.rs | 3 +- .../generic_duplicate_lifetime_param.rs | 1 + .../generic_duplicate_lifetime_param.stderr | 16 +- .../generic_duplicate_param_use.rs | 12 +- .../generic_duplicate_param_use.stderr | 50 +++- .../generic_nondefining_use.rs | 9 +- .../generic_nondefining_use.stderr | 44 +++- .../generic_type_does_not_live_long_enough.rs | 12 +- ...eric_type_does_not_live_long_enough.stderr | 20 +- .../higher_kinded_params.rs | 28 +++ .../higher_kinded_params2.rs | 36 +++ .../higher_kinded_params3.rs | 3 +- .../higher_kinded_params3.stderr | 19 +- .../type-alias-impl-trait/inference-cycle.rs | 4 +- .../issue-53678-generator-and-const-fn.rs | 21 +- .../issue-53678-generator-and-const-fn.stderr | 8 - tests/ui/type-alias-impl-trait/issue-57961.rs | 4 +- tests/ui/type-alias-impl-trait/issue-60564.rs | 1 + .../type-alias-impl-trait/issue-60564.stderr | 16 +- .../issue-63263-closure-return.rs | 5 +- ...sue-65679-inst-opaque-ty-from-val-twice.rs | 4 +- .../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 +- ...ssue-69136-inner-lifetime-resolve-error.rs | 7 +- ...-69136-inner-lifetime-resolve-error.stderr | 16 +- tests/ui/type-alias-impl-trait/issue-77179.rs | 2 +- .../nested_type_alias_impl_trait.rs | 4 +- ...o_revealing_outside_defining_module.stderr | 10 + .../ui/type-alias-impl-trait/reveal_local.rs | 4 +- .../type-alias-impl-trait/reveal_local.stderr | 6 +- .../ui/type-alias-impl-trait/type_of_a_let.rs | 8 +- .../type_of_a_let.stderr | 6 +- 70 files changed, 795 insertions(+), 183 deletions(-) create mode 100644 tests/ui/generic-associated-types/issue-90014-tait.rs create mode 100644 tests/ui/generic-associated-types/issue-90014-tait.stderr create mode 100644 tests/ui/generic-associated-types/issue-90014-tait2.rs create mode 100644 tests/ui/generic-associated-types/issue-90014-tait2.stderr create mode 100644 tests/ui/impl-trait/issues/issue-78722-2.rs create mode 100644 tests/ui/impl-trait/issues/issue-78722-2.stderr create mode 100644 tests/ui/type-alias-impl-trait/higher_kinded_params.rs create mode 100644 tests/ui/type-alias-impl-trait/higher_kinded_params2.rs delete mode 100644 tests/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.stderr diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index f3ee83fd4d218..51e1fe531dd1f 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -226,7 +226,7 @@ fn register_functions(bundle: &mut FluentBundle) { pub type LazyFallbackBundle = Lrc<Lazy<FluentBundle, impl FnOnce() -> FluentBundle>>; /// Return the default `FluentBundle` with standard "en-US" diagnostic messages. -#[instrument(level = "trace")] +#[instrument(level = "trace", skip(resources))] pub fn fallback_fluent_bundle( resources: Vec<&'static str>, with_directionality_markers: bool, @@ -242,7 +242,6 @@ pub fn fallback_fluent_bundle( for resource in resources { let resource = FluentResource::try_new(resource.to_string()) .expect("failed to parse fallback fluent resource"); - trace!(?resource); fallback_bundle.add_resource_overriding(resource); } diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 0738961d6ce48..166760166c108 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -248,6 +248,9 @@ hir_analysis_static_specialize = cannot specialize on `'static` lifetime hir_analysis_substs_on_overridden_impl = could not resolve substs on overridden impl +hir_analysis_tait_forward_compat = item constrains opaque type that is not in its signature + .note = this item must mention the opaque type in its signature in order to be able to register hidden types + 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 current 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 f4779a3f26533..957a6bb348109 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -6,7 +6,7 @@ use rustc_middle::hir::nested_filter; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::DUMMY_SP; -use crate::errors::UnconstrainedOpaqueType; +use crate::errors::{TaitForwardCompat, UnconstrainedOpaqueType}; /// Checks "defining uses" of opaque `impl Trait` types to ensure that they meet the restrictions /// laid for "higher-order pattern unification". @@ -139,6 +139,15 @@ impl TaitConstraintLocator<'_> { continue; } constrained = true; + if !self.tcx.opaque_types_defined_by(item_def_id).contains(&self.def_id) { + self.tcx.sess.emit_err(TaitForwardCompat { + span: hidden_type.span, + item_span: self + .tcx + .def_ident_span(item_def_id) + .unwrap_or_else(|| self.tcx.def_span(item_def_id)), + }); + } let concrete_type = self.tcx.erase_regions(hidden_type.remap_generic_params_to_declaration_params( opaque_type_key, diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 205e26d0edaac..c2d2e5f7e50f6 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -184,6 +184,16 @@ pub struct UnconstrainedOpaqueType { pub what: &'static str, } +#[derive(Diagnostic)] +#[diag(hir_analysis_tait_forward_compat)] +#[note] +pub struct TaitForwardCompat { + #[primary_span] + pub span: Span, + #[note] + pub item_span: Span, +} + pub struct MissingTypeParams { pub span: Span, pub def_span: Span, diff --git a/compiler/rustc_hir_typeck/src/inherited.rs b/compiler/rustc_hir_typeck/src/inherited.rs index 05e5db9f0f3a3..d5619af2aae17 100644 --- a/compiler/rustc_hir_typeck/src/inherited.rs +++ b/compiler/rustc_hir_typeck/src/inherited.rs @@ -80,7 +80,7 @@ impl<'tcx> Inherited<'tcx> { let infcx = tcx .infer_ctxt() .ignoring_regions() - .with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)) + .with_opaque_type_inference(DefiningAnchor::Bind(def_id)) .build(); let typeck_results = RefCell::new(ty::TypeckResults::new(hir_owner)); diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index c9a8f8131dffb..63613b59020fb 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -257,7 +257,7 @@ impl<T> Trait<T> for X { ); } } - (ty::Alias(ty::Opaque, alias), _) | (_, ty::Alias(ty::Opaque, alias)) if alias.def_id.is_local() && matches!(tcx.def_kind(body_owner_def_id), DefKind::AssocFn | DefKind::AssocConst) => { + (ty::Alias(ty::Opaque, alias), _) | (_, ty::Alias(ty::Opaque, alias)) if alias.def_id.is_local() && matches!(tcx.def_kind(body_owner_def_id), DefKind::Fn | DefKind::Static(_) | DefKind::Const | DefKind::AssocFn | DefKind::AssocConst) => { if tcx.is_type_alias_impl_trait(alias.def_id) { if !tcx.opaque_types_defined_by(body_owner_def_id.expect_local()).contains(&alias.def_id.expect_local()) { let sp = tcx.def_ident_span(body_owner_def_id).unwrap_or_else(|| tcx.def_span(body_owner_def_id)); diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index e2ee347b639a1..1af8323b6e993 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -11,7 +11,7 @@ mod fulfill; pub mod misc; mod object_safety; pub mod outlives_bounds; -mod project; +pub mod project; pub mod query; #[cfg_attr(not(bootstrap), allow(hidden_glob_reexports))] mod select; diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 29de8bf0e53f5..bc002cdce71a0 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -1,11 +1,17 @@ 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::TyCtxtInferExt; 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::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; +use rustc_span::def_id::CRATE_DEF_ID; use rustc_span::Span; use rustc_trait_selection::traits::check_substs_compatible; +use rustc_trait_selection::traits::ObligationCtxt; use std::ops::ControlFlow; use crate::errors::{DuplicateArg, NotParam}; @@ -19,12 +25,21 @@ struct OpaqueTypeCollector<'tcx> { /// Avoid infinite recursion due to recursive declarations. seen: FxHashSet<LocalDefId>, + universes: Vec<Option<ty::UniverseIndex>>, + span: Option<Span>, } 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(), + universes: vec![], + span: None, + } } fn span(&self) -> Span { @@ -51,7 +66,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { fn parent(&self) -> Option<LocalDefId> { match self.tcx.def_kind(self.item) { - DefKind::Fn => None, + DefKind::AnonConst | DefKind::InlineConst | DefKind::Fn | DefKind::TyAlias => None, DefKind::AssocFn | DefKind::AssocTy | DefKind::AssocConst => { Some(self.tcx.local_parent(self.item)) } @@ -61,9 +76,53 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { ), } } + + /// Returns `true` if `opaque_hir_id` is a sibling or a child of a sibling of `self.item`. + /// + /// Example: + /// ```ignore UNSOLVED (is this a bug?) + /// # #![feature(type_alias_impl_trait)] + /// pub mod foo { + /// pub mod bar { + /// pub trait Bar { /* ... */ } + /// pub type Baz = impl Bar; + /// + /// # impl Bar for () {} + /// fn f1() -> Baz { /* ... */ } + /// } + /// fn f2() -> bar::Baz { /* ... */ } + /// } + /// ``` + /// + /// and `opaque_def_id` is the `DefId` of the definition of the opaque type `Baz`. + /// For the above example, this function returns `true` for `f1` and `false` for `f2`. + #[instrument(level = "trace", skip(self), ret)] + fn check_tait_defining_scope(&self, opaque_def_id: LocalDefId) -> bool { + let mut hir_id = self.tcx.hir().local_def_id_to_hir_id(self.item); + let opaque_hir_id = self.tcx.hir().local_def_id_to_hir_id(opaque_def_id); + + // Named opaque types can be defined by any siblings or children of siblings. + let scope = self.tcx.hir().get_defining_scope(opaque_hir_id); + // We walk up the node tree until we hit the root or the scope of the opaque type. + while hir_id != scope && hir_id != CRATE_HIR_ID { + hir_id = self.tcx.hir().get_parent_item(hir_id).into(); + } + // Syntactically, we are allowed to define the concrete type if: + hir_id == scope + } } impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> { + fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>( + &mut self, + t: &ty::Binder<'tcx, T>, + ) -> ControlFlow<!> { + self.universes.push(None); + let t = t.super_visit_with(self); + self.universes.pop(); + t + } + #[instrument(skip(self), ret, level = "trace")] fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<!> { t.super_visit_with(self)?; @@ -73,6 +132,34 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> { 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); + match origin { + rustc_hir::OpaqueTyOrigin::FnReturn(_) + | rustc_hir::OpaqueTyOrigin::AsyncFn(_) => {} + rustc_hir::OpaqueTyOrigin::TyAlias { in_assoc_ty } => { + if in_assoc_ty { + // Only associated items can be defining for opaque types in associated types. + if let Some(parent) = self.parent() { + let mut current = alias_ty.def_id.expect_local(); + while current != parent && current != CRATE_DEF_ID { + current = self.tcx.local_parent(current); + } + if current != parent { + return ControlFlow::Continue(()); + } + } else { + return ControlFlow::Continue(()); + } + } else { + if !self.check_tait_defining_scope(alias_ty.def_id.expect_local()) { + return ControlFlow::Continue(()); + } + } + } + } + self.opaques.push(alias_ty.def_id.expect_local()); match self.tcx.uses_unique_generic_params(alias_ty.substs, CheckRegions::Bound) { @@ -159,6 +246,28 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> { } } } + + // Normalize trivial projections. + let mut infcx = self.tcx.infer_ctxt(); + let infcx = infcx.build(); + let t = if t.has_escaping_bound_vars() { + let (t, _mapped_regions, _mapped_types, _mapped_consts) = + rustc_trait_selection::traits::project::BoundVarReplacer::replace_bound_vars( + &infcx, + &mut self.universes, + t, + ); + t + } else { + t + }; + let ocx = ObligationCtxt::new(&infcx); + let cause = ObligationCause::dummy_with_span(self.span()); + let normalized = ocx.normalize(&cause, self.tcx.param_env(self.item), t); + trace!(?normalized); + if normalized != t { + normalized.visit_with(self)?; + } } ty::Adt(def, _) if def.did().is_local() => { if !self.seen.insert(def.did().expect_local()) { @@ -188,29 +297,71 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> { fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [LocalDefId] { let kind = tcx.def_kind(item); trace!(?kind); - // FIXME(type_alias_impl_trait): This is definitely still wrong except for RPIT and impl trait in assoc types. match kind { // We're also doing this for `AssocTy` for the wf checks in `check_opaque_meets_bounds` - DefKind::Fn | DefKind::AssocFn | DefKind::AssocTy | DefKind::AssocConst => { + DefKind::Static(_) + | DefKind::Const + | DefKind::TyAlias + | DefKind::Fn + | DefKind::OpaqueTy + | DefKind::AnonConst + | DefKind::InlineConst + | DefKind::AssocFn + | DefKind::AssocTy + | DefKind::AssocConst => { let mut collector = OpaqueTypeCollector::new(tcx, item); 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).subst_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()); - for (hir, ty) in hir_sig.decl.inputs.iter().zip(ty_sig.inputs().iter()) { - collector.visit_spanned(hir.span, ty.map_bound(|x| *x)); + DefKind::Static(_) + | DefKind::Const + | DefKind::AssocConst + | DefKind::AssocFn + | DefKind::AnonConst + | DefKind::InlineConst + | DefKind::Fn => { + 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).subst_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()); + for (hir, ty) in hir_sig.decl.inputs.iter().zip(ty_sig.inputs().iter()) + { + collector.visit_spanned(hir.span, ty.map_bound(|x| *x)); + } + } + // Walk over the type of the item to find opaques. + DefKind::Static(_) + | DefKind::Const + | DefKind::AssocConst + | DefKind::AnonConst + | DefKind::InlineConst => { + let span = match tcx.hir().get_by_def_id(item).ty() { + Some(ty) => ty.span, + _ => tcx.def_span(item), + }; + collector.visit_spanned(span, tcx.type_of(item).subst_identity()); + } + _ => unreachable!(), + } + // Look at all where bounds. + tcx.predicates_of(item).instantiate_identity(tcx).visit_with(&mut collector); + // An item is allowed to constrain opaques declared within its own body (but not nested within + // nested functions). + for id in find_taits_declared_in_body(tcx, item) { + if let DefKind::TyAlias = tcx.def_kind(id) { + collector.opaques.extend(tcx.opaque_types_defined_by(id)) + } } } - // Walk over the type of the item to find opaques. - DefKind::AssocTy | DefKind::AssocConst => { - let span = match tcx.hir().get_by_def_id(item).ty() { - Some(ty) => ty.span, - _ => tcx.def_span(item), - }; - collector.visit_spanned(span, tcx.type_of(item).subst_identity()); + DefKind::TyAlias | DefKind::AssocTy => { + tcx.type_of(item).subst_identity().visit_with(&mut collector); + } + DefKind::OpaqueTy => { + for (pred, span) in tcx.explicit_item_bounds(item).subst_identity_iter_copied() + { + collector.visit_spanned(span, pred); + } } _ => unreachable!(), } @@ -222,31 +373,44 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [ | DefKind::Enum | DefKind::Variant | DefKind::Trait - | DefKind::TyAlias | DefKind::ForeignTy | DefKind::TraitAlias | DefKind::TyParam - | DefKind::Const | DefKind::ConstParam - | DefKind::Static(_) | DefKind::Ctor(_, _) | DefKind::Macro(_) | DefKind::ExternCrate | DefKind::Use | DefKind::ForeignMod - | DefKind::AnonConst - | DefKind::InlineConst - | DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder | DefKind::Field | DefKind::LifetimeParam | DefKind::GlobalAsm - | DefKind::Impl { .. } - | DefKind::Closure - | DefKind::Generator => { - span_bug!(tcx.def_span(item), "{kind:?} is type checked as part of its parent") + | DefKind::Impl { .. } => &[], + DefKind::Closure | DefKind::Generator => { + tcx.opaque_types_defined_by(tcx.local_parent(item)) + } + } +} + +fn find_taits_declared_in_body(tcx: TyCtxt<'_>, item: LocalDefId) -> Vec<LocalDefId> { + let body = tcx.hir().body(tcx.hir().body_owned_by(item)).value; + #[derive(Default, Debug)] + struct TaitInBodyFinder { + /// Ids of type aliases found in the body + type_aliases: Vec<LocalDefId>, + } + impl<'v> intravisit::Visitor<'v> for TaitInBodyFinder { + #[instrument(level = "trace")] + fn visit_nested_item(&mut self, id: rustc_hir::ItemId) { + let id = id.owner_id.def_id; + self.type_aliases.push(id); } } + let mut visitor = TaitInBodyFinder::default(); + trace!(?body); + visitor.visit_expr(body); + visitor.type_aliases } pub(super) fn provide(providers: &mut Providers) { diff --git a/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs b/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs index 0d019b1f50206..3f49020bbea38 100644 --- a/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs +++ b/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs @@ -11,7 +11,7 @@ fn define() -> Bar { type Foo2 = impl Debug; -fn define2() { +fn define2(_: Foo2) { let x = || -> Foo2 { 42 }; } @@ -20,13 +20,13 @@ type Foo3 = impl Debug; fn define3(x: Foo3) { let y: i32 = x; } -fn define3_1() { +fn define3_1(_: Foo3) { define3(42) } type Foo4 = impl Debug; -fn define4() { +fn define4(_: Foo4) { let y: Foo4 = 42; } diff --git a/tests/ui/generic-associated-types/issue-90014-tait.rs b/tests/ui/generic-associated-types/issue-90014-tait.rs new file mode 100644 index 0000000000000..bc3a4e1296513 --- /dev/null +++ b/tests/ui/generic-associated-types/issue-90014-tait.rs @@ -0,0 +1,23 @@ +//! 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 + +#![feature(impl_trait_in_assoc_type, inherent_associated_types)] +#![allow(incomplete_features)] + +use std::future::Future; + +struct Foo<'a>(&'a mut ()); + +impl Foo<'_> { + type Fut<'a> = impl Future<Output = ()>; + //^ ERROR: the type `&mut ()` does not fulfill the required lifetime + + fn make_fut<'a>(&'a self) -> Self::Fut<'a> { + async { () } + } +} + +fn main() {} diff --git a/tests/ui/generic-associated-types/issue-90014-tait.stderr b/tests/ui/generic-associated-types/issue-90014-tait.stderr new file mode 100644 index 0000000000000..8330a387ecd55 --- /dev/null +++ b/tests/ui/generic-associated-types/issue-90014-tait.stderr @@ -0,0 +1,22 @@ +error[E0308]: mismatched types + --> $DIR/issue-90014-tait.rs:19:9 + | +LL | type Fut<'a> = impl Future<Output = ()>; + | ------------------------ the expected future +... +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: expected opaque type `Foo<'_>::Fut<'a>` + found `async` block `[async block@$DIR/issue-90014-tait.rs:19:9: 19: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:18:8 + | +LL | fn make_fut<'a>(&'a self) -> Self::Fut<'a> { + | ^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/generic-associated-types/issue-90014-tait2.rs b/tests/ui/generic-associated-types/issue-90014-tait2.rs new file mode 100644 index 0000000000000..dacbc93dec880 --- /dev/null +++ b/tests/ui/generic-associated-types/issue-90014-tait2.rs @@ -0,0 +1,46 @@ +//! This test checks that opaque type collection doesn't try to normalize the projection +//! without respecting its binders (which would ICE). +//! Unfortunately we don't even reach opaque type collection, as we ICE in typeck before that. +// known-bug: #109281 +// failure-status: 101 +// error-pattern:internal compiler error +// normalize-stderr-test "internal compiler error.*" -> "" +// normalize-stderr-test "DefId\([^)]*\)" -> "..." +// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> "" +// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> "" +// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> "" +// normalize-stderr-test "note: compiler flags.*\n\n" -> "" +// normalize-stderr-test "note: rustc.*running on.*\n\n" -> "" +// normalize-stderr-test "thread.*panicked.*\n" -> "" +// normalize-stderr-test "stack backtrace:\n" -> "" +// normalize-stderr-test "\s\d{1,}: .*\n" -> "" +// normalize-stderr-test "\s at .*\n" -> "" +// normalize-stderr-test ".*note: Some details.*\n" -> "" +// normalize-stderr-test "\n\n[ ]*\n" -> "" +// normalize-stderr-test "compiler/.*: projection" -> "projection" +// edition:2018 + +#![feature(type_alias_impl_trait)] +#![allow(incomplete_features)] + +use std::future::Future; + +struct Foo<'a>(&'a mut ()); + +type Fut<'a> = impl Future<Output = ()>; + +trait Trait<'x> { + type Thing; +} + +impl<'x, T: 'x> Trait<'x> for (T,) { + type Thing = T; +} + +impl Foo<'_> { + fn make_fut(&self) -> Box<dyn for<'a> Trait<'a, Thing = Fut<'a>>> { + Box::new((async { () },)) + } +} + +fn main() {} diff --git a/tests/ui/generic-associated-types/issue-90014-tait2.stderr b/tests/ui/generic-associated-types/issue-90014-tait2.stderr new file mode 100644 index 0000000000000..3187be3334c5f --- /dev/null +++ b/tests/ui/generic-associated-types/issue-90014-tait2.stderr @@ -0,0 +1,12 @@ +error: + --> $DIR/issue-90014-tait2.rs:41:27 + | +LL | fn make_fut(&self) -> Box<dyn for<'a> Trait<'a, Thing = Fut<'a>>> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^query stack during panic: +#0 [typeck] type-checking `<impl at $DIR/issue-90014-tait2.rs:40:1: 40:13>::make_fut` +#1 [type_of] computing type of `Fut::{opaque#0}` +#2 [check_mod_item_types] checking item types in top-level module +#3 [analysis] running analysis passes on this crate +end of query stack +error: aborting due to previous error + diff --git a/tests/ui/impl-trait/deduce-signature-from-supertrait.rs b/tests/ui/impl-trait/deduce-signature-from-supertrait.rs index d2c3479203573..7a51aac44e2e8 100644 --- a/tests/ui/impl-trait/deduce-signature-from-supertrait.rs +++ b/tests/ui/impl-trait/deduce-signature-from-supertrait.rs @@ -8,8 +8,10 @@ impl<T: Fn(i32)> SuperExpectation for T {} type Foo = impl SuperExpectation; -fn main() { +fn bop(_: Foo) { let _: Foo = |x| { let _ = x.to_string(); }; } + +fn main() {} diff --git a/tests/ui/impl-trait/in-assoc-type.rs b/tests/ui/impl-trait/in-assoc-type.rs index 36c54bdd6de34..38ad2fa6f02ee 100644 --- a/tests/ui/impl-trait/in-assoc-type.rs +++ b/tests/ui/impl-trait/in-assoc-type.rs @@ -1,3 +1,6 @@ +//! This test checks that we don't allow registering hidden types for +//! opaque types from other impls. + #![feature(impl_trait_in_assoc_type)] trait Foo<T> { diff --git a/tests/ui/impl-trait/in-assoc-type.stderr b/tests/ui/impl-trait/in-assoc-type.stderr index ab3f3a14410d0..af60da07cac31 100644 --- a/tests/ui/impl-trait/in-assoc-type.stderr +++ b/tests/ui/impl-trait/in-assoc-type.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/in-assoc-type.rs:17:22 + --> $DIR/in-assoc-type.rs:20:22 | LL | type Bar = impl std::fmt::Debug; | -------------------- the expected opaque type @@ -12,7 +12,7 @@ LL | fn foo(&self) -> <Self as Foo<()>>::Bar {} = note: expected opaque type `<() as Foo<()>>::Bar` found unit type `()` note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/in-assoc-type.rs:17:8 + --> $DIR/in-assoc-type.rs:20:8 | LL | fn foo(&self) -> <Self as Foo<()>>::Bar {} | ^^^ diff --git a/tests/ui/impl-trait/issues/issue-70877.rs b/tests/ui/impl-trait/issues/issue-70877.rs index 8169cfafac711..df7722986744d 100644 --- a/tests/ui/impl-trait/issues/issue-70877.rs +++ b/tests/ui/impl-trait/issues/issue-70877.rs @@ -25,12 +25,12 @@ fn ham() -> Foo { Bar(1) } -fn oof() -> impl std::fmt::Debug { +fn oof(_: Foo) -> impl std::fmt::Debug { let mut bar = ham(); let func = bar.next().unwrap(); return func(&"oof"); //~ ERROR opaque type's hidden type cannot be another opaque type } fn main() { - let _ = oof(); + let _ = oof(ham()); } diff --git a/tests/ui/impl-trait/issues/issue-70877.stderr b/tests/ui/impl-trait/issues/issue-70877.stderr index 8813bff3c353e..ee140e6f6c43d 100644 --- a/tests/ui/impl-trait/issues/issue-70877.stderr +++ b/tests/ui/impl-trait/issues/issue-70877.stderr @@ -5,10 +5,10 @@ LL | return func(&"oof"); | ^^^^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope | note: opaque type whose hidden type is being assigned - --> $DIR/issue-70877.rs:28:13 + --> $DIR/issue-70877.rs:28:19 | -LL | fn oof() -> impl std::fmt::Debug { - | ^^^^^^^^^^^^^^^^^^^^ +LL | fn oof(_: Foo) -> impl std::fmt::Debug { + | ^^^^^^^^^^^^^^^^^^^^ note: opaque type being used as hidden type --> $DIR/issue-70877.rs:4:15 | diff --git a/tests/ui/impl-trait/issues/issue-74282.rs b/tests/ui/impl-trait/issues/issue-74282.rs index 654de0cd0253c..51bd5f67ed574 100644 --- a/tests/ui/impl-trait/issues/issue-74282.rs +++ b/tests/ui/impl-trait/issues/issue-74282.rs @@ -3,9 +3,12 @@ type Closure = impl Fn() -> u64; struct Anonymous(Closure); -fn main() { +fn bop(_: Closure) { let y = || -> Closure { || 3 }; - Anonymous(|| { //~ ERROR mismatched types - 3 //~^ ERROR mismatched types + Anonymous(|| { + //~^ ERROR mismatched types + 3 //~^^ ERROR mismatched types }) } + +fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-74282.stderr b/tests/ui/impl-trait/issues/issue-74282.stderr index 724f3c5d6747c..d43e9fee0b359 100644 --- a/tests/ui/impl-trait/issues/issue-74282.stderr +++ b/tests/ui/impl-trait/issues/issue-74282.stderr @@ -8,6 +8,7 @@ LL | Anonymous(|| { | _____---------_^ | | | | | arguments to this struct are incorrect +LL | | LL | | 3 LL | | }) | |_____^ expected opaque type, found closure @@ -25,15 +26,20 @@ LL | struct Anonymous(Closure); error[E0308]: mismatched types --> $DIR/issue-74282.rs:8:5 | -LL | fn main() { - | - expected `()` because of default return type -LL | let y = || -> Closure { || 3 }; LL | / Anonymous(|| { +LL | | LL | | 3 LL | | }) - | | ^- help: consider using a semicolon here: `;` - | |______| - | expected `()`, found `Anonymous` + | |______^ expected `()`, found `Anonymous` + | +help: consider using a semicolon here + | +LL | }); + | + +help: try adding a return type + | +LL | fn bop(_: Closure) -> Anonymous { + | ++++++++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/impl-trait/issues/issue-78722-2.rs b/tests/ui/impl-trait/issues/issue-78722-2.rs new file mode 100644 index 0000000000000..cf5361e1e602c --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-78722-2.rs @@ -0,0 +1,22 @@ +//! test that we cannot register hidden types for opaque types +//! declared outside an anonymous constant. +// edition:2018 + +#![feature(type_alias_impl_trait)] + +type F = impl core::future::Future<Output = u8>; + +struct Bug { + V1: [(); { + fn concrete_use() -> F { + //~^ ERROR future that resolves to `u8`, but it resolves to `()` + async {} + } + let f: F = async { 1 }; + //~^ ERROR item constrains opaque type that is not in its signature + //~| ERROR `async` blocks are not allowed in constants + 1 + }], +} + +fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-78722-2.stderr b/tests/ui/impl-trait/issues/issue-78722-2.stderr new file mode 100644 index 0000000000000..6db603e775175 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-78722-2.stderr @@ -0,0 +1,32 @@ +error[E0658]: `async` blocks are not allowed in constants + --> $DIR/issue-78722-2.rs:15:20 + | +LL | let f: F = async { 1 }; + | ^^^^^^^^^^^ + | + = note: see issue #85368 <https://github.com/rust-lang/rust/issues/85368> for more information + = help: add `#![feature(const_async_blocks)]` to the crate attributes to enable + +error[E0271]: expected `[async block@$DIR/issue-78722-2.rs:13:13: 13:21]` to be a future that resolves to `u8`, but it resolves to `()` + --> $DIR/issue-78722-2.rs:11:30 + | +LL | fn concrete_use() -> F { + | ^ expected `()`, found `u8` + +error: item constrains opaque type that is not in its signature + --> $DIR/issue-78722-2.rs:15:20 + | +LL | let f: F = async { 1 }; + | ^^^^^^^^^^^ + | + = 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-78722-2.rs:15:20 + | +LL | let f: F = async { 1 }; + | ^^^^^^^^^^^ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0271, E0658. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/impl-trait/issues/issue-78722.rs b/tests/ui/impl-trait/issues/issue-78722.rs index 7b5ab5f229835..75ccc8d8e8a9a 100644 --- a/tests/ui/impl-trait/issues/issue-78722.rs +++ b/tests/ui/impl-trait/issues/issue-78722.rs @@ -2,10 +2,9 @@ #![feature(type_alias_impl_trait)] -type F = impl core::future::Future<Output = u8>; - struct Bug { V1: [(); { + type F = impl core::future::Future<Output = u8>; fn concrete_use() -> F { //~^ ERROR to be a future that resolves to `u8`, but it resolves to `()` async {} diff --git a/tests/ui/impl-trait/issues/issue-78722.stderr b/tests/ui/impl-trait/issues/issue-78722.stderr index 05a2c135cf7c7..36340a0bab41a 100644 --- a/tests/ui/impl-trait/issues/issue-78722.stderr +++ b/tests/ui/impl-trait/issues/issue-78722.stderr @@ -1,5 +1,5 @@ error[E0658]: `async` blocks are not allowed in constants - --> $DIR/issue-78722.rs:13:20 + --> $DIR/issue-78722.rs:12:20 | LL | let f: F = async { 1 }; | ^^^^^^^^^^^ @@ -7,8 +7,8 @@ LL | let f: F = async { 1 }; = note: see issue #85368 <https://github.com/rust-lang/rust/issues/85368> for more information = help: add `#![feature(const_async_blocks)]` to the crate attributes to enable -error[E0271]: expected `[async block@$DIR/issue-78722.rs:11:13: 11:21]` to be a future that resolves to `u8`, but it resolves to `()` - --> $DIR/issue-78722.rs:9:30 +error[E0271]: expected `[async block@$DIR/issue-78722.rs:10:13: 10:21]` to be a future that resolves to `u8`, but it resolves to `()` + --> $DIR/issue-78722.rs:8:30 | LL | fn concrete_use() -> F { | ^ expected `()`, found `u8` diff --git a/tests/ui/traits/new-solver/dont-remap-tait-substs.rs b/tests/ui/traits/new-solver/dont-remap-tait-substs.rs index 028222f4e6dba..309bee8aa8c2c 100644 --- a/tests/ui/traits/new-solver/dont-remap-tait-substs.rs +++ b/tests/ui/traits/new-solver/dont-remap-tait-substs.rs @@ -12,7 +12,7 @@ type Foo<T: Send, U> = impl NeedsSend<T>; trait NeedsSend<T> {} impl<T: Send> NeedsSend<T> for T {} -fn define<A, B: Send>(a: A, b: B) { +fn define<A, B: Send>(a: A, b: B, _: Foo<B, A>) { let y: Option<Foo<B, A>> = Some(b); } diff --git a/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.rs b/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.rs index 5a0dcd0e8ccea..08f14d7494d79 100644 --- a/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.rs +++ b/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.rs @@ -12,11 +12,13 @@ type Foo = impl Sized; fn needs_send<T: Send>() {} -fn test() { +fn test(_: Foo) { needs_send::<Foo>(); //[not_send]~^ ERROR type annotations needed: cannot satisfy `Foo: Send` } -fn main() { +fn defines(_: Foo) { let _: Foo = (); } + +fn main() {} diff --git a/tests/ui/traits/new-solver/tait-eq-proj-2.rs b/tests/ui/traits/new-solver/tait-eq-proj-2.rs index 99a3d02bd1aea..77ea8bc246e64 100644 --- a/tests/ui/traits/new-solver/tait-eq-proj-2.rs +++ b/tests/ui/traits/new-solver/tait-eq-proj-2.rs @@ -8,9 +8,11 @@ type Tait = impl Iterator<Item = impl Sized>; -fn mk<T>() -> T { todo!() } +fn mk<T>() -> T { + todo!() +} -fn a() { +fn a(_: Tait) { let x: Tait = mk(); let mut array = mk(); let mut z = IntoIterator::into_iter(array); diff --git a/tests/ui/traits/new-solver/tait-eq-proj.rs b/tests/ui/traits/new-solver/tait-eq-proj.rs index 01141b2819a8d..01ef2ec953aeb 100644 --- a/tests/ui/traits/new-solver/tait-eq-proj.rs +++ b/tests/ui/traits/new-solver/tait-eq-proj.rs @@ -28,7 +28,7 @@ goals together. Essentially: */ -fn a() { +fn a(_: Tait) { let _: Tait = IntoIterator::into_iter([0i32; 32]); } diff --git a/tests/ui/traits/new-solver/tait-eq-tait.rs b/tests/ui/traits/new-solver/tait-eq-tait.rs index 532c4c39bd499..70d9dc0eaa8ae 100644 --- a/tests/ui/traits/new-solver/tait-eq-tait.rs +++ b/tests/ui/traits/new-solver/tait-eq-tait.rs @@ -6,12 +6,13 @@ #![feature(type_alias_impl_trait)] -type Tait = impl Sized; -type Tait2 = impl Sized; - -fn mk<T>() -> T { todo!() } +fn mk<T>() -> T { + todo!() +} fn main() { + type Tait = impl Sized; + type Tait2 = impl Sized; let x: Tait = 1u32; let y: Tait2 = x; } diff --git a/tests/ui/type-alias-impl-trait/bound_reduction2.rs b/tests/ui/type-alias-impl-trait/bound_reduction2.rs index 0bcc9e002ca04..4e9f65d88a129 100644 --- a/tests/ui/type-alias-impl-trait/bound_reduction2.rs +++ b/tests/ui/type-alias-impl-trait/bound_reduction2.rs @@ -13,6 +13,7 @@ trait Trait<U> {} impl<W> Trait<W> for () {} fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> { + //~^ ERROR non-defining opaque type use () //~^ ERROR expected generic type parameter, found `<T as TraitWithAssoc>::Assoc` } diff --git a/tests/ui/type-alias-impl-trait/bound_reduction2.stderr b/tests/ui/type-alias-impl-trait/bound_reduction2.stderr index 3c259bd9e97cc..14f9dbbdb4e93 100644 --- a/tests/ui/type-alias-impl-trait/bound_reduction2.stderr +++ b/tests/ui/type-alias-impl-trait/bound_reduction2.stderr @@ -1,5 +1,17 @@ +error[E0792]: non-defining opaque type use in defining scope + --> $DIR/bound_reduction2.rs:15:46 + | +LL | fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> { + | ^^^^^^^^^^^^^ argument `<T as TraitWithAssoc>::Assoc` is not a generic parameter + | +note: for this opaque type + --> $DIR/bound_reduction2.rs:9:15 + | +LL | type Foo<V> = impl Trait<V>; + | ^^^^^^^^^^^^^ + error[E0792]: expected generic type parameter, found `<T as TraitWithAssoc>::Assoc` - --> $DIR/bound_reduction2.rs:16:5 + --> $DIR/bound_reduction2.rs:17:5 | LL | type Foo<V> = impl Trait<V>; | - this generic parameter must be used with a generic type parameter @@ -7,6 +19,6 @@ LL | type Foo<V> = impl Trait<V>; LL | () | ^^ -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/closure_args.rs b/tests/ui/type-alias-impl-trait/closure_args.rs index c5e7af81d3dd0..243f9cd6d4f4c 100644 --- a/tests/ui/type-alias-impl-trait/closure_args.rs +++ b/tests/ui/type-alias-impl-trait/closure_args.rs @@ -11,6 +11,13 @@ fn run<F: FnOnce(Input) -> ()>(f: F, i: Input) { f(i); } -fn main() { - run(|x: u32| {println!("{x}");}, 0); +fn bop(_: Input) { + run( + |x: u32| { + println!("{x}"); + }, + 0, + ); } + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/closure_args2.rs b/tests/ui/type-alias-impl-trait/closure_args2.rs index 82386c280a8e3..1dd5c3e40cda6 100644 --- a/tests/ui/type-alias-impl-trait/closure_args2.rs +++ b/tests/ui/type-alias-impl-trait/closure_args2.rs @@ -1,10 +1,12 @@ -// run-pass +// check-pass #![feature(type_alias_impl_trait)] trait Foo { // This was reachable in https://github.com/rust-lang/rust/issues/100800 - fn foo(&self) { unreachable!() } + fn foo(&self) { + unreachable!() + } } impl<T> Foo for T {} @@ -14,10 +16,17 @@ impl B { } type Input = impl Foo; -fn run1<F: FnOnce(Input)>(f: F, i: Input) {f(i)} -fn run2<F: FnOnce(B)>(f: F, i: B) {f(i)} +fn run1<F: FnOnce(Input)>(f: F, i: Input) { + f(i) +} +fn run2<F: FnOnce(B)>(f: F, i: B) { + f(i) +} -fn main() { - run1(|x: B| {x.foo()}, B); - run2(|x: B| {x.foo()}, B); +fn bop() -> Input { + run1(|x: B| x.foo(), B); + run2(|x: B| x.foo(), B); + panic!() } + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr b/tests/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr index fbfa0ccf1e8d9..d60f1ffbccc2d 100644 --- a/tests/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr +++ b/tests/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr @@ -19,6 +19,11 @@ LL | "" | = note: expected opaque type `Boo` found reference `&'static str` +note: this item must have the opaque type in its signature in order to be able to register hidden types + --> $DIR/declared_but_not_defined_in_scope.rs:10:4 + | +LL | fn bomp() -> boo::Boo { + | ^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs index e5bfbfdae91fd..b2842df150a3f 100644 --- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs +++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs @@ -2,7 +2,7 @@ type Tait<'a> = impl Sized + 'a; -fn foo<'a, 'b>() { +fn foo<'a, 'b>() -> Tait<'a> { if false { if { return } { let y: Tait<'b> = 1i32; @@ -10,6 +10,7 @@ fn foo<'a, 'b>() { } } let x: Tait<'a> = (); + x } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr index f2eb7bc4dc79b..b138f9d5c45ab 100644 --- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr +++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr @@ -5,10 +5,10 @@ LL | let y: Tait<'b> = 1i32; | ^^^^ expected `()`, got `i32` | note: previous use here - --> $DIR/different_defining_uses_never_type-2.rs:12:23 + --> $DIR/different_defining_uses_never_type-2.rs:7:14 | -LL | let x: Tait<'a> = (); - | ^^ +LL | if { return } { + | ^^^^^^ error: aborting due to previous error diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.rs b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.rs index 2b30a9cd57cf6..a4ac27378e1d8 100644 --- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.rs +++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.rs @@ -2,7 +2,7 @@ type Tait<T> = impl Sized; -fn foo<T, U>() { +fn foo<T, U>() -> Tait<T> { if false { if { return } { let y: Tait<U> = 1i32; @@ -10,6 +10,7 @@ fn foo<T, U>() { } } let x: Tait<T> = (); + x } fn main() {} 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 9d938a61600f5..14ced3418542a 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 @@ -9,6 +9,7 @@ impl<'a, T: ?Sized> Captures<'a> for T {} type Two<'a, 'b> = impl std::fmt::Debug + Captures<'a> + Captures<'b>; 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 72e1ef4b4923b..4da69a705c07c 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,5 +1,17 @@ error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_lifetime_param.rs:12:5 + --> $DIR/generic_duplicate_lifetime_param.rs:11: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:9:20 + | +LL | type Two<'a, 'b> = impl std::fmt::Debug + Captures<'a> + Captures<'b>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: non-defining opaque type use in defining scope + --> $DIR/generic_duplicate_lifetime_param.rs:13:5 | LL | t | ^ @@ -10,5 +22,5 @@ note: lifetime used multiple times LL | type Two<'a, 'b> = impl std::fmt::Debug + Captures<'a> + Captures<'b>; | ^^ ^^ -error: aborting due to previous error +error: aborting due to 2 previous errors 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 80462f8ac046c..1e391b55a4fac 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 @@ -1,5 +1,12 @@ #![feature(type_alias_impl_trait)] +//! This test checks various cases where we are using the same +//! generic parameter twice in the parameter list of a TAIT. +//! Within defining scopes that is not legal, because the hidden type +//! is not fully defined then. This could cause us to have a TAIT +//! that doesn't have a hidden type for all possible combinations of generic +//! parameters passed to it. + use std::fmt::Debug; fn main() {} @@ -7,7 +14,6 @@ fn main() {} // test that unused generic parameters are ok type TwoTys<T, U> = impl Debug; - pub trait Captures<'a> {} impl<'a, T: ?Sized> Captures<'a> for T {} @@ -16,18 +22,20 @@ type TwoLifetimes<'a, 'b> = impl Debug + Captures<'a> + Captures<'b>; type TwoConsts<const X: usize, const Y: usize> = impl Debug; - fn one_ty<T: Debug>(t: T) -> TwoTys<T, T> { + //~^ 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<const N: usize>(t: *mut [u8; N]) -> TwoConsts<N, N> { + //~^ 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 98e4bfea10d63..d8330771d301d 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,38 +1,74 @@ error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_param_use.rs:21:5 + --> $DIR/generic_duplicate_param_use.rs:25:30 + | +LL | fn one_ty<T: Debug>(t: T) -> TwoTys<T, T> { + | ^^^^^^^^^^^^ generic argument `T` used twice + | +note: for this opaque type + --> $DIR/generic_duplicate_param_use.rs:15:21 + | +LL | type TwoTys<T, U> = impl Debug; + | ^^^^^^^^^^ + +error: non-defining opaque type use in defining scope + --> $DIR/generic_duplicate_param_use.rs:27:5 | LL | t | ^ | note: type used multiple times - --> $DIR/generic_duplicate_param_use.rs:8:13 + --> $DIR/generic_duplicate_param_use.rs:15:13 | LL | type TwoTys<T, U> = impl Debug; | ^ ^ error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_param_use.rs:26:5 + --> $DIR/generic_duplicate_param_use.rs:31: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:21:29 + | +LL | type TwoLifetimes<'a, 'b> = impl Debug + Captures<'a> + Captures<'b>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: non-defining opaque type use in defining scope + --> $DIR/generic_duplicate_param_use.rs:33:5 | LL | t | ^ | note: lifetime used multiple times - --> $DIR/generic_duplicate_param_use.rs:15:19 + --> $DIR/generic_duplicate_param_use.rs:21:19 | LL | type TwoLifetimes<'a, 'b> = impl Debug + Captures<'a> + Captures<'b>; | ^^ ^^ error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_param_use.rs:31:5 + --> $DIR/generic_duplicate_param_use.rs:37:50 + | +LL | fn one_const<const N: usize>(t: *mut [u8; N]) -> TwoConsts<N, N> { + | ^^^^^^^^^^^^^^^ generic argument `N` used twice + | +note: for this opaque type + --> $DIR/generic_duplicate_param_use.rs:23:50 + | +LL | type TwoConsts<const X: usize, const Y: usize> = impl Debug; + | ^^^^^^^^^^ + +error: non-defining opaque type use in defining scope + --> $DIR/generic_duplicate_param_use.rs:39:5 | LL | t | ^ | note: constant used multiple times - --> $DIR/generic_duplicate_param_use.rs:17:16 + --> $DIR/generic_duplicate_param_use.rs:23:16 | LL | type TwoConsts<const X: usize, const Y: usize> = impl Debug; | ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 6 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 e7b8567b9a217..68f4c6923ae18 100644 --- a/tests/ui/type-alias-impl-trait/generic_nondefining_use.rs +++ b/tests/ui/type-alias-impl-trait/generic_nondefining_use.rs @@ -13,16 +13,19 @@ type OneConst<const X: usize> = impl Debug; // Not defining uses, because they doesn't define *all* possible generics. fn concrete_ty() -> OneTy<u32> { + //~^ ERROR: non-defining opaque type use in defining scope 5u32 - //~^ ERROR expected generic type parameter, found `u32` + //~^ 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` + //~^ 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` + //~^ 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 966fe823f024d..e3b7b1a76b09d 100644 --- a/tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr +++ b/tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr @@ -1,5 +1,17 @@ +error[E0792]: non-defining opaque type use in defining scope + --> $DIR/generic_nondefining_use.rs:15:21 + | +LL | fn concrete_ty() -> OneTy<u32> { + | ^^^^^^^^^^ argument `u32` is not a generic parameter + | +note: for this opaque type + --> $DIR/generic_nondefining_use.rs:7:17 + | +LL | type OneTy<T> = impl Debug; + | ^^^^^^^^^^ + error[E0792]: expected generic type parameter, found `u32` - --> $DIR/generic_nondefining_use.rs:16:5 + --> $DIR/generic_nondefining_use.rs:17:5 | LL | type OneTy<T> = impl Debug; | - this generic parameter must be used with a generic type parameter @@ -7,8 +19,20 @@ LL | type OneTy<T> = 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:21:5 + --> $DIR/generic_nondefining_use.rs:23: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 @@ -16,8 +40,20 @@ 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<const X: usize> = impl Debug; + | ^^^^^^^^^^ + error[E0792]: expected generic constant parameter, found `123` - --> $DIR/generic_nondefining_use.rs:26:5 + --> $DIR/generic_nondefining_use.rs:29:5 | LL | type OneConst<const X: usize> = impl Debug; | -------------- this generic parameter must be used with a generic constant parameter @@ -25,6 +61,6 @@ LL | type OneConst<const X: usize> = impl Debug; LL | 7u32 | ^^^^ -error: aborting due to 3 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs b/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs index cdd8f6f1976a5..c60f5c11cd18c 100644 --- a/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs +++ b/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs @@ -5,12 +5,12 @@ fn main() { let x = wrong_generic(&y); let z: i32 = x; //~^ ERROR expected generic type parameter, found `&i32` -} -type WrongGeneric<T> = impl 'static; -//~^ ERROR: at least one trait must be specified + type WrongGeneric<T> = impl 'static; + //~^ ERROR: at least one trait must be specified -fn wrong_generic<T>(t: T) -> WrongGeneric<T> { - t - //~^ ERROR the parameter type `T` may not live long enough + fn wrong_generic<T>(t: T) -> WrongGeneric<T> { + t + //~^ ERROR the parameter type `T` may not live long enough + } } diff --git a/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr b/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr index fa79e51e9f79f..8c3a25dbfe7de 100644 --- a/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr +++ b/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr @@ -1,8 +1,8 @@ error: at least one trait must be specified - --> $DIR/generic_type_does_not_live_long_enough.rs:10:24 + --> $DIR/generic_type_does_not_live_long_enough.rs:9:28 | -LL | type WrongGeneric<T> = impl 'static; - | ^^^^^^^^^^^^ +LL | type WrongGeneric<T> = impl 'static; + | ^^^^^^^^^^^^ error[E0792]: expected generic type parameter, found `&i32` --> $DIR/generic_type_does_not_live_long_enough.rs:6:18 @@ -10,19 +10,19 @@ error[E0792]: expected generic type parameter, found `&i32` LL | let z: i32 = x; | ^ ... -LL | type WrongGeneric<T> = impl 'static; - | - this generic parameter must be used with a generic type parameter +LL | type WrongGeneric<T> = impl 'static; + | - this generic parameter must be used with a generic type parameter error[E0310]: the parameter type `T` may not live long enough - --> $DIR/generic_type_does_not_live_long_enough.rs:14:5 + --> $DIR/generic_type_does_not_live_long_enough.rs:13:9 | -LL | t - | ^ ...so that the type `T` will meet its required lifetime bounds +LL | t + | ^ ...so that the type `T` will meet its required lifetime bounds | help: consider adding an explicit lifetime bound... | -LL | fn wrong_generic<T: 'static>(t: T) -> WrongGeneric<T> { - | +++++++++ +LL | fn wrong_generic<T: 'static>(t: T) -> WrongGeneric<T> { + | +++++++++ error: aborting due to 3 previous errors diff --git a/tests/ui/type-alias-impl-trait/higher_kinded_params.rs b/tests/ui/type-alias-impl-trait/higher_kinded_params.rs new file mode 100644 index 0000000000000..db1a3a1c7a9d0 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/higher_kinded_params.rs @@ -0,0 +1,28 @@ +//! This test checks that walking into binders +//! during opaque type collection does not ICE or raise errors. + +// edition: 2021 + +// check-pass + +#![feature(type_alias_impl_trait)] + +trait B { + type C; +} + +struct A; + +impl<'a> B for &'a A { + type C = (); +} + +struct Terminator; + +type Successors<'a> = impl std::fmt::Debug + 'a; + +impl Terminator { + fn successors(&self, _: for<'x> fn(&'x ()) -> <&'x A as B>::C) -> Successors<'_> {} +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/higher_kinded_params2.rs b/tests/ui/type-alias-impl-trait/higher_kinded_params2.rs new file mode 100644 index 0000000000000..d5030e60c63cc --- /dev/null +++ b/tests/ui/type-alias-impl-trait/higher_kinded_params2.rs @@ -0,0 +1,36 @@ +//! This test checks the behaviour of walking into binders +//! and normalizing something behind them actually works. + +// edition: 2021 + +// check-pass + +#![feature(type_alias_impl_trait)] + +trait B { + type C; +} + +struct A; + +impl<'a> B for &'a A { + type C = Tait; +} + +type Tait = impl std::fmt::Debug; + +struct Terminator; + +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; + } +} + +fn g(_: &()) -> String { + String::new() +} + +fn main() {} 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 839a611cb71a9..a6a7ffce507a6 100644 --- a/tests/ui/type-alias-impl-trait/higher_kinded_params3.rs +++ b/tests/ui/type-alias-impl-trait/higher_kinded_params3.rs @@ -23,8 +23,9 @@ 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<'_> { + //~^ ERROR non-defining opaque type use in defining scope f = g; - //~^ ERROR: mismatched types + //~^ ERROR mismatched types } } 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 aaba9ad5ca704..8f6bee7d29e61 100644 --- a/tests/ui/type-alias-impl-trait/higher_kinded_params3.stderr +++ b/tests/ui/type-alias-impl-trait/higher_kinded_params3.stderr @@ -1,5 +1,17 @@ +error[E0792]: non-defining opaque type use in defining scope + --> $DIR/higher_kinded_params3.rs:25:33 + | +LL | fn successors(&self, mut f: for<'x> fn(&'x ()) -> <&'x A as B>::C) -> Successors<'_> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument `'x` is not a generic parameter + | +note: for this opaque type + --> $DIR/higher_kinded_params3.rs:18:17 + | +LL | type Tait<'a> = impl std::fmt::Debug + 'a; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0308]: mismatched types - --> $DIR/higher_kinded_params3.rs:26:9 + --> $DIR/higher_kinded_params3.rs:27:9 | LL | type Tait<'a> = impl std::fmt::Debug + 'a; | ------------------------- the expected opaque type @@ -10,6 +22,7 @@ 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 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0308, E0792. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/type-alias-impl-trait/inference-cycle.rs b/tests/ui/type-alias-impl-trait/inference-cycle.rs index 093afc25249a7..20175a4feca00 100644 --- a/tests/ui/type-alias-impl-trait/inference-cycle.rs +++ b/tests/ui/type-alias-impl-trait/inference-cycle.rs @@ -17,8 +17,8 @@ mod m { //~^ ERROR: cannot check whether the hidden type of `inference_cycle[4ecc]::m::Foo::{opaque#0}` satisfies auto traits } - fn baz() { - let f: Foo = (); + fn baz() -> Foo { + () } fn is_send<T: Send>(_: T) {} diff --git a/tests/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs b/tests/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs index a3f126d56cf20..a213dbba4ea01 100644 --- a/tests/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs +++ b/tests/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs @@ -1,19 +1,22 @@ #![feature(generators, generator_trait, rustc_attrs)] #![feature(type_alias_impl_trait)] -use std::ops::Generator; +// check-pass -type GenOnce<Y, R> = impl Generator<Yield = Y, Return = R>; +mod gen { + use std::ops::Generator; -const fn const_generator<Y, R>(yielding: Y, returning: R) -> GenOnce<Y, R> { - move || { - yield yielding; + pub type GenOnce<Y, R> = impl Generator<Yield = Y, Return = R>; - return returning; + pub const fn const_generator<Y, R>(yielding: Y, returning: R) -> GenOnce<Y, R> { + move || { + yield yielding; + + return returning; + } } } -const FOO: GenOnce<usize, usize> = const_generator(10, 100); +const FOO: gen::GenOnce<usize, usize> = gen::const_generator(10, 100); -#[rustc_error] -fn main() {} //~ ERROR +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.stderr b/tests/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.stderr deleted file mode 100644 index eb1c9603a60d6..0000000000000 --- a/tests/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: fatal error triggered by #[rustc_error] - --> $DIR/issue-53678-generator-and-const-fn.rs:19:1 - | -LL | fn main() {} - | ^^^^^^^^^ - -error: aborting due to previous error - diff --git a/tests/ui/type-alias-impl-trait/issue-57961.rs b/tests/ui/type-alias-impl-trait/issue-57961.rs index 4aa5966ff25d4..61af7a0f62500 100644 --- a/tests/ui/type-alias-impl-trait/issue-57961.rs +++ b/tests/ui/type-alias-impl-trait/issue-57961.rs @@ -11,8 +11,8 @@ impl Foo for () { //~^ ERROR expected `IntoIter<u32>` to be an iterator that yields `X`, but it yields `u32` } -fn incoherent() { - let f: X = 22_i32; +fn incoherent() -> X { + 22_i32 } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-60564.rs b/tests/ui/type-alias-impl-trait/issue-60564.rs index c2f4c37080746..48bd70bcca950 100644 --- a/tests/ui/type-alias-impl-trait/issue-60564.rs +++ b/tests/ui/type-alias-impl-trait/issue-60564.rs @@ -17,6 +17,7 @@ where { type BitsIter = IterBitsIter<T, E, u8>; 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 f8fdb004d0989..d42495e934d33 100644 --- a/tests/ui/type-alias-impl-trait/issue-60564.stderr +++ b/tests/ui/type-alias-impl-trait/issue-60564.stderr @@ -1,5 +1,17 @@ +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<T, E, I> = impl std::iter::Iterator<Item = I>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0792]: expected generic type parameter, found `u8` - --> $DIR/issue-60564.rs:20:9 + --> $DIR/issue-60564.rs:21:9 | LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>; | - this generic parameter must be used with a generic type parameter @@ -7,6 +19,6 @@ LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>; LL | (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/issue-63263-closure-return.rs b/tests/ui/type-alias-impl-trait/issue-63263-closure-return.rs index 7414611a74893..ddea7aeb6cda7 100644 --- a/tests/ui/type-alias-impl-trait/issue-63263-closure-return.rs +++ b/tests/ui/type-alias-impl-trait/issue-63263-closure-return.rs @@ -8,6 +8,9 @@ pub type Closure = impl FnOnce(); -fn main() { +fn bop() -> Closure { || -> Closure { || () }; + panic!() } + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs b/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs index b91cbce3727f6..7b3e9e12405c7 100644 --- a/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs +++ b/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs @@ -11,7 +11,9 @@ type T = impl Sized; fn take(_: fn() -> T) {} -fn main() { +fn bop(_: T) { take(|| {}); take(|| {}); } + +fn main() {} 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 5e0a82a72868a..9dcdb578568aa 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,7 +7,8 @@ trait Trait<T> {} type Alias<'a, U> = impl Trait<U>; fn f<'a>() -> Alias<'a, ()> {} -//~^ ERROR expected generic type parameter, found `()` +//~^ ERROR non-defining opaque type use +//~| 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 271743a4010c8..085bffe907b4b 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,3 +1,15 @@ +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<U>; + | ^^^^^^^^^^^^^ + error[E0792]: expected generic type parameter, found `()` --> $DIR/issue-68368-non-defining-use-2.rs:9:29 | @@ -7,6 +19,6 @@ LL | LL | fn f<'a>() -> Alias<'a, ()> {} | ^^ -error: aborting due to previous error +error: aborting due to 2 previous errors 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 3b32260c96fe1..dfe2ee8204c75 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,6 +8,7 @@ type Alias<'a, U> = impl Trait<U>; 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 4d9a8d6eef915..ea704ffff97ab 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,3 +1,15 @@ +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<U>; + | ^^^^^^^^^^^^^ + error[E0792]: expected generic type parameter, found `()` --> $DIR/issue-68368-non-defining-use.rs:9:29 | @@ -7,6 +19,6 @@ LL | LL | fn f<'a>() -> Alias<'a, ()> {} | ^^ -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs b/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs index 7657fe2fb1aee..a0f8e48e268c9 100644 --- a/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs +++ b/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs @@ -1,4 +1,6 @@ -// Regression test for #69136 +//! Regression test for #69136 +//! This test checks that the unknown lifetime `'a` doesn't cause +//! ICEs after emitting the error. #![feature(type_alias_impl_trait)] @@ -17,7 +19,6 @@ impl<T> WithAssoc<T> for () { type Return<A> = impl WithAssoc<A, AssocType = impl SomeTrait + 'a>; //~^ ERROR use of undeclared lifetime name `'a` -fn my_fun() -> Return<()> {} -//~^ ERROR expected generic type parameter, found `()` +fn my_fun<T>() -> Return<T> {} fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.stderr b/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.stderr index d1250786d938c..b7af3f06d0d9a 100644 --- a/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.stderr +++ b/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.stderr @@ -1,5 +1,5 @@ error[E0261]: use of undeclared lifetime name `'a` - --> $DIR/issue-69136-inner-lifetime-resolve-error.rs:17:65 + --> $DIR/issue-69136-inner-lifetime-resolve-error.rs:19:65 | LL | type Return<A> = impl WithAssoc<A, AssocType = impl SomeTrait + 'a>; | ^^ undeclared lifetime @@ -14,16 +14,6 @@ help: consider introducing lifetime `'a` here LL | type Return<'a, A> = impl WithAssoc<A, AssocType = impl SomeTrait + 'a>; | +++ -error[E0792]: expected generic type parameter, found `()` - --> $DIR/issue-69136-inner-lifetime-resolve-error.rs:20:27 - | -LL | type Return<A> = impl WithAssoc<A, AssocType = impl SomeTrait + 'a>; - | - this generic parameter must be used with a generic type parameter -... -LL | fn my_fun() -> Return<()> {} - | ^^ - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0261, E0792. -For more information about an error, try `rustc --explain E0261`. +For more information about this error, try `rustc --explain E0261`. diff --git a/tests/ui/type-alias-impl-trait/issue-77179.rs b/tests/ui/type-alias-impl-trait/issue-77179.rs index 8d818d4a387a6..e7b04a4897559 100644 --- a/tests/ui/type-alias-impl-trait/issue-77179.rs +++ b/tests/ui/type-alias-impl-trait/issue-77179.rs @@ -2,7 +2,7 @@ #![feature(type_alias_impl_trait)] -type Pointer<T> = impl std::ops::Deref<Target=T>; +type Pointer<T> = impl std::ops::Deref<Target = T>; fn test() -> Pointer<_> { //~^ ERROR: the placeholder `_` is not allowed within types diff --git a/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs b/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs index 60b6e1aac6281..07607516cc4bc 100644 --- a/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs +++ b/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs @@ -10,11 +10,11 @@ mod my_mod { 5i32 } - pub fn get_foot() -> Foot { + pub fn get_foot(_: Foo) -> Foot { get_foo() //~ ERROR opaque type's hidden type cannot be another opaque type } } fn main() { - let _: my_mod::Foot = my_mod::get_foot(); + let _: my_mod::Foot = my_mod::get_foot(my_mod::get_foo()); } diff --git a/tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr b/tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr index ae03a5b3e37bf..863282a0ff94d 100644 --- a/tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr +++ b/tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr @@ -11,6 +11,11 @@ LL | let _: &str = bomp(); | = note: expected reference `&str` found opaque type `Boo` +note: this item must have the opaque type in its signature in order to be able to register hidden types + --> $DIR/no_revealing_outside_defining_module.rs:14:4 + | +LL | fn bomp2() { + | ^^^^^ error[E0308]: mismatched types --> $DIR/no_revealing_outside_defining_module.rs:19:5 @@ -25,6 +30,11 @@ LL | "" | = note: expected opaque type `Boo` found reference `&'static str` +note: this item must have the opaque type in its signature in order to be able to register hidden types + --> $DIR/no_revealing_outside_defining_module.rs:18:4 + | +LL | fn bomp() -> boo::Boo { + | ^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/type-alias-impl-trait/reveal_local.rs b/tests/ui/type-alias-impl-trait/reveal_local.rs index 75015e41c3da7..7943bb240f15b 100644 --- a/tests/ui/type-alias-impl-trait/reveal_local.rs +++ b/tests/ui/type-alias-impl-trait/reveal_local.rs @@ -16,7 +16,7 @@ fn not_good() { //~^ ERROR: cannot check whether the hidden type of `reveal_local[9507]::Foo::{opaque#0}` satisfies auto traits } -fn not_gooder() { +fn not_gooder() -> Foo { // Constrain `Foo = u32` let x: Foo = 22_u32; @@ -24,6 +24,8 @@ fn not_gooder() { // need extra roundabout logic to support it. is_send::<Foo>(); //~^ ERROR: cannot check whether the hidden type of `reveal_local[9507]::Foo::{opaque#0}` satisfies auto traits + + x } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/reveal_local.stderr b/tests/ui/type-alias-impl-trait/reveal_local.stderr index 202a87ecbb773..0c5ef4a6fb418 100644 --- a/tests/ui/type-alias-impl-trait/reveal_local.stderr +++ b/tests/ui/type-alias-impl-trait/reveal_local.stderr @@ -78,8 +78,8 @@ LL | type Foo = impl Debug; note: ...which requires type-checking `not_gooder`... --> $DIR/reveal_local.rs:19:1 | -LL | fn not_gooder() { - | ^^^^^^^^^^^^^^^ +LL | fn not_gooder() -> Foo { + | ^^^^^^^^^^^^^^^^^^^^^^ = note: ...which again requires computing type of `Foo::{opaque#0}`, completing the cycle note: cycle used when checking item types in top-level module --> $DIR/reveal_local.rs:1:1 @@ -107,7 +107,7 @@ LL | type Foo = impl Debug; note: this item depends on auto traits of the hidden type, but may also be registering the hidden type. This is not supported right now. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule --> $DIR/reveal_local.rs:19:4 | -LL | fn not_gooder() { +LL | fn not_gooder() -> Foo { | ^^^^^^^^^^ note: required by a bound in `is_send` --> $DIR/reveal_local.rs:10:15 diff --git a/tests/ui/type-alias-impl-trait/type_of_a_let.rs b/tests/ui/type-alias-impl-trait/type_of_a_let.rs index 4e9d1788b94d8..36161171555ca 100644 --- a/tests/ui/type-alias-impl-trait/type_of_a_let.rs +++ b/tests/ui/type-alias-impl-trait/type_of_a_let.rs @@ -5,16 +5,16 @@ use std::fmt::Debug; type Foo = impl Debug; -fn foo1() -> u32 { +fn foo1() -> (u32, Foo) { let x: Foo = 22_u32; - x + (x, todo!()) } -fn foo2() -> u32 { +fn foo2() -> (u32, Foo) { let x: Foo = 22_u32; let y: Foo = x; same_type((x, y)); //~ ERROR use of moved value - y //~ ERROR use of moved value + (y, todo!()) //~ ERROR use of moved value } fn same_type<T>(x: (T, T)) {} diff --git a/tests/ui/type-alias-impl-trait/type_of_a_let.stderr b/tests/ui/type-alias-impl-trait/type_of_a_let.stderr index 1dabe4586c5b9..7d7cad874faec 100644 --- a/tests/ui/type-alias-impl-trait/type_of_a_let.stderr +++ b/tests/ui/type-alias-impl-trait/type_of_a_let.stderr @@ -9,14 +9,14 @@ LL | same_type((x, y)); | ^ value used here after move error[E0382]: use of moved value: `y` - --> $DIR/type_of_a_let.rs:17:5 + --> $DIR/type_of_a_let.rs:17:6 | LL | let y: Foo = x; | - move occurs because `y` has type `Foo`, which does not implement the `Copy` trait LL | same_type((x, y)); | - value moved here -LL | y - | ^ value used here after move +LL | (y, todo!()) + | ^ value used here after move error: aborting due to 2 previous errors From 907f97e4111b1e52cef13203ec4515449ab4ae59 Mon Sep 17 00:00:00 2001 From: Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> Date: Mon, 26 Jun 2023 17:49:35 +0000 Subject: [PATCH 02/11] Remove normalization from `opaque_types_defined_by` --- compiler/rustc_ty_utils/src/opaque_types.rs | 43 +------------------ tests/ui/lint/issue-99387.rs | 4 +- tests/ui/lint/issue-99387.stderr | 15 +++++++ .../higher_kinded_params2.rs | 3 +- .../higher_kinded_params2.stderr | 15 +++++++ .../higher_kinded_params3.rs | 2 +- .../higher_kinded_params3.stderr | 22 +++++----- tests/ui/type-alias-impl-trait/issue-70121.rs | 3 +- .../type-alias-impl-trait/issue-70121.stderr | 15 +++++++ 9 files changed, 64 insertions(+), 58 deletions(-) create mode 100644 tests/ui/lint/issue-99387.stderr create mode 100644 tests/ui/type-alias-impl-trait/higher_kinded_params2.stderr create mode 100644 tests/ui/type-alias-impl-trait/issue-70121.stderr diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index bc002cdce71a0..bf5f1bb747c7b 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -2,16 +2,12 @@ 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::TyCtxtInferExt; use rustc_middle::query::Providers; -use rustc_middle::traits::ObligationCause; use rustc_middle::ty::util::{CheckRegions, NotUniqueParam}; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; -use rustc_span::def_id::CRATE_DEF_ID; use rustc_span::Span; use rustc_trait_selection::traits::check_substs_compatible; -use rustc_trait_selection::traits::ObligationCtxt; use std::ops::ControlFlow; use crate::errors::{DuplicateArg, NotParam}; @@ -139,20 +135,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> { rustc_hir::OpaqueTyOrigin::FnReturn(_) | rustc_hir::OpaqueTyOrigin::AsyncFn(_) => {} rustc_hir::OpaqueTyOrigin::TyAlias { in_assoc_ty } => { - if in_assoc_ty { - // Only associated items can be defining for opaque types in associated types. - if let Some(parent) = self.parent() { - let mut current = alias_ty.def_id.expect_local(); - while current != parent && current != CRATE_DEF_ID { - current = self.tcx.local_parent(current); - } - if current != parent { - return ControlFlow::Continue(()); - } - } else { - return ControlFlow::Continue(()); - } - } else { + if !in_assoc_ty { if !self.check_tait_defining_scope(alias_ty.def_id.expect_local()) { return ControlFlow::Continue(()); } @@ -246,28 +229,6 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> { } } } - - // Normalize trivial projections. - let mut infcx = self.tcx.infer_ctxt(); - let infcx = infcx.build(); - let t = if t.has_escaping_bound_vars() { - let (t, _mapped_regions, _mapped_types, _mapped_consts) = - rustc_trait_selection::traits::project::BoundVarReplacer::replace_bound_vars( - &infcx, - &mut self.universes, - t, - ); - t - } else { - t - }; - let ocx = ObligationCtxt::new(&infcx); - let cause = ObligationCause::dummy_with_span(self.span()); - let normalized = ocx.normalize(&cause, self.tcx.param_env(self.item), t); - trace!(?normalized); - if normalized != t { - normalized.visit_with(self)?; - } } ty::Adt(def, _) if def.did().is_local() => { if !self.seen.insert(def.did().expect_local()) { diff --git a/tests/ui/lint/issue-99387.rs b/tests/ui/lint/issue-99387.rs index 616eb935e93d4..ba5031167e33d 100644 --- a/tests/ui/lint/issue-99387.rs +++ b/tests/ui/lint/issue-99387.rs @@ -1,4 +1,5 @@ -// check-pass +//! Test that we don't follow through projections to find +//! opaque types. #![feature(type_alias_impl_trait)] #![allow(private_in_public)] @@ -18,6 +19,7 @@ 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 new file mode 100644 index 0000000000000..3a46ce7e1952d --- /dev/null +++ b/tests/ui/lint/issue-99387.stderr @@ -0,0 +1,15 @@ +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/higher_kinded_params2.rs b/tests/ui/type-alias-impl-trait/higher_kinded_params2.rs index d5030e60c63cc..f011e5b214813 100644 --- a/tests/ui/type-alias-impl-trait/higher_kinded_params2.rs +++ b/tests/ui/type-alias-impl-trait/higher_kinded_params2.rs @@ -3,8 +3,6 @@ // edition: 2021 -// check-pass - #![feature(type_alias_impl_trait)] trait B { @@ -26,6 +24,7 @@ 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 new file mode 100644 index 0000000000000..39f584dd49ca3 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/higher_kinded_params2.stderr @@ -0,0 +1,15 @@ +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 a6a7ffce507a6..6edfccaf7d179 100644 --- a/tests/ui/type-alias-impl-trait/higher_kinded_params3.rs +++ b/tests/ui/type-alias-impl-trait/higher_kinded_params3.rs @@ -23,9 +23,9 @@ 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<'_> { - //~^ ERROR non-defining opaque type use in defining scope 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 8f6bee7d29e61..14372d8f3e64d 100644 --- a/tests/ui/type-alias-impl-trait/higher_kinded_params3.stderr +++ b/tests/ui/type-alias-impl-trait/higher_kinded_params3.stderr @@ -1,17 +1,18 @@ -error[E0792]: non-defining opaque type use in defining scope - --> $DIR/higher_kinded_params3.rs:25:33 +error: item constrains opaque type that is not in its signature + --> $DIR/higher_kinded_params3.rs:26:13 | -LL | fn successors(&self, mut f: for<'x> fn(&'x ()) -> <&'x A as B>::C) -> Successors<'_> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument `'x` is not a generic parameter +LL | f = g; + | ^ | -note: for this opaque type - --> $DIR/higher_kinded_params3.rs:18:17 + = 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 | type Tait<'a> = impl std::fmt::Debug + 'a; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +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:27:9 + --> $DIR/higher_kinded_params3.rs:26:9 | LL | type Tait<'a> = impl std::fmt::Debug + 'a; | ------------------------- the expected opaque type @@ -24,5 +25,4 @@ LL | f = g; error: aborting due to 2 previous errors -Some errors have detailed explanations: E0308, E0792. -For more information about an error, try `rustc --explain E0308`. +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 dff0d89d465dd..bfd8d8872e37f 100644 --- a/tests/ui/type-alias-impl-trait/issue-70121.rs +++ b/tests/ui/type-alias-impl-trait/issue-70121.rs @@ -1,5 +1,3 @@ -// check-pass - #![feature(type_alias_impl_trait)] pub type Successors<'a> = impl Iterator<Item = &'a ()>; @@ -17,6 +15,7 @@ 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 new file mode 100644 index 0000000000000..30c3ddd8659d1 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/issue-70121.stderr @@ -0,0 +1,15 @@ +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 2f89c963d3777e03d0ff9f0bcfc11b148a4c0af7 Mon Sep 17 00:00:00 2001 From: Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> Date: Mon, 26 Jun 2023 17:50:11 +0000 Subject: [PATCH 03/11] We don't need to track binders if we aren't normalizing --- compiler/rustc_ty_utils/src/opaque_types.rs | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index bf5f1bb747c7b..146f7cd371c44 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -21,21 +21,12 @@ struct OpaqueTypeCollector<'tcx> { /// Avoid infinite recursion due to recursive declarations. seen: FxHashSet<LocalDefId>, - universes: Vec<Option<ty::UniverseIndex>>, - span: Option<Span>, } impl<'tcx> OpaqueTypeCollector<'tcx> { fn new(tcx: TyCtxt<'tcx>, item: LocalDefId) -> Self { - Self { - tcx, - opaques: Vec::new(), - item, - seen: Default::default(), - universes: vec![], - span: None, - } + Self { tcx, opaques: Vec::new(), item, seen: Default::default(), span: None } } fn span(&self) -> Span { @@ -109,16 +100,6 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { } impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> { - fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>( - &mut self, - t: &ty::Binder<'tcx, T>, - ) -> ControlFlow<!> { - self.universes.push(None); - let t = t.super_visit_with(self); - self.universes.pop(); - t - } - #[instrument(skip(self), ret, level = "trace")] fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<!> { t.super_visit_with(self)?; From a3ca139defd6f4d93d8f19e7c73a5c94965cca4f Mon Sep 17 00:00:00 2001 From: Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> Date: Thu, 29 Jun 2023 07:02:29 +0000 Subject: [PATCH 04/11] liar liar find_taits_declared_in_body on fire --- compiler/rustc_ty_utils/src/opaque_types.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 146f7cd371c44..919cbcfc95179 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -291,9 +291,7 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [ // An item is allowed to constrain opaques declared within its own body (but not nested within // nested functions). for id in find_taits_declared_in_body(tcx, item) { - if let DefKind::TyAlias = tcx.def_kind(id) { - collector.opaques.extend(tcx.opaque_types_defined_by(id)) - } + collector.opaques.extend(tcx.opaque_types_defined_by(id)) } } DefKind::TyAlias | DefKind::AssocTy => { @@ -335,22 +333,24 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [ } } +#[instrument(level = "trace", skip(tcx), ret)] fn find_taits_declared_in_body(tcx: TyCtxt<'_>, item: LocalDefId) -> Vec<LocalDefId> { let body = tcx.hir().body(tcx.hir().body_owned_by(item)).value; - #[derive(Default, Debug)] - struct TaitInBodyFinder { + struct TaitInBodyFinder<'tcx> { /// Ids of type aliases found in the body type_aliases: Vec<LocalDefId>, + tcx: TyCtxt<'tcx>, } - impl<'v> intravisit::Visitor<'v> for TaitInBodyFinder { - #[instrument(level = "trace")] + impl<'v> intravisit::Visitor<'v> for TaitInBodyFinder<'_> { + #[instrument(level = "trace", skip(self))] fn visit_nested_item(&mut self, id: rustc_hir::ItemId) { let id = id.owner_id.def_id; - self.type_aliases.push(id); + if let DefKind::TyAlias = self.tcx.def_kind(id) { + self.type_aliases.push(id); + } } } - let mut visitor = TaitInBodyFinder::default(); - trace!(?body); + let mut visitor = TaitInBodyFinder { type_aliases: Default::default(), tcx }; visitor.visit_expr(body); visitor.type_aliases } From af9dcf70be6a7d14619275c9b2d8beebd0743b29 Mon Sep 17 00:00:00 2001 From: Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> Date: Thu, 29 Jun 2023 07:15:27 +0000 Subject: [PATCH 05/11] Remove one layer of nested matching on the same thing --- compiler/rustc_ty_utils/src/opaque_types.rs | 94 +++++++++------------ 1 file changed, 39 insertions(+), 55 deletions(-) diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 919cbcfc95179..245352bfd3b1a 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -239,73 +239,56 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> { fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [LocalDefId] { let kind = tcx.def_kind(item); trace!(?kind); + let mut collector = OpaqueTypeCollector::new(tcx, item); match kind { // We're also doing this for `AssocTy` for the wf checks in `check_opaque_meets_bounds` DefKind::Static(_) | DefKind::Const - | DefKind::TyAlias - | DefKind::Fn - | DefKind::OpaqueTy + | DefKind::AssocConst + | DefKind::AssocFn | DefKind::AnonConst | DefKind::InlineConst - | DefKind::AssocFn - | DefKind::AssocTy - | DefKind::AssocConst => { - let mut collector = OpaqueTypeCollector::new(tcx, item); + | DefKind::Fn => { 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).subst_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()); + for (hir, ty) in hir_sig.decl.inputs.iter().zip(ty_sig.inputs().iter()) { + collector.visit_spanned(hir.span, ty.map_bound(|x| *x)); + } + } + // Walk over the type of the item to find opaques. DefKind::Static(_) | DefKind::Const | DefKind::AssocConst - | DefKind::AssocFn | DefKind::AnonConst - | DefKind::InlineConst - | DefKind::Fn => { - 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).subst_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()); - for (hir, ty) in hir_sig.decl.inputs.iter().zip(ty_sig.inputs().iter()) - { - collector.visit_spanned(hir.span, ty.map_bound(|x| *x)); - } - } - // Walk over the type of the item to find opaques. - DefKind::Static(_) - | DefKind::Const - | DefKind::AssocConst - | DefKind::AnonConst - | DefKind::InlineConst => { - let span = match tcx.hir().get_by_def_id(item).ty() { - Some(ty) => ty.span, - _ => tcx.def_span(item), - }; - collector.visit_spanned(span, tcx.type_of(item).subst_identity()); - } - _ => unreachable!(), - } - // Look at all where bounds. - tcx.predicates_of(item).instantiate_identity(tcx).visit_with(&mut collector); - // An item is allowed to constrain opaques declared within its own body (but not nested within - // nested functions). - for id in find_taits_declared_in_body(tcx, item) { - collector.opaques.extend(tcx.opaque_types_defined_by(id)) - } - } - DefKind::TyAlias | DefKind::AssocTy => { - tcx.type_of(item).subst_identity().visit_with(&mut collector); - } - DefKind::OpaqueTy => { - for (pred, span) in tcx.explicit_item_bounds(item).subst_identity_iter_copied() - { - collector.visit_spanned(span, pred); - } + | DefKind::InlineConst => { + let span = match tcx.hir().get_by_def_id(item).ty() { + Some(ty) => ty.span, + _ => tcx.def_span(item), + }; + collector.visit_spanned(span, tcx.type_of(item).subst_identity()); } _ => unreachable!(), } - tcx.arena.alloc_from_iter(collector.opaques) + // Look at all where bounds. + tcx.predicates_of(item).instantiate_identity(tcx).visit_with(&mut collector); + // An item is allowed to constrain opaques declared within its own body (but not nested within + // nested functions). + for id in find_taits_declared_in_body(tcx, item) { + collector.opaques.extend(tcx.opaque_types_defined_by(id)) + } + } + DefKind::TyAlias | DefKind::AssocTy => { + tcx.type_of(item).subst_identity().visit_with(&mut collector); + } + DefKind::OpaqueTy => { + for (pred, span) in tcx.explicit_item_bounds(item).subst_identity_iter_copied() { + collector.visit_spanned(span, pred); + } } DefKind::Mod | DefKind::Struct @@ -326,11 +309,12 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [ | DefKind::Field | DefKind::LifetimeParam | DefKind::GlobalAsm - | DefKind::Impl { .. } => &[], + | DefKind::Impl { .. } => {} DefKind::Closure | DefKind::Generator => { - tcx.opaque_types_defined_by(tcx.local_parent(item)) + return tcx.opaque_types_defined_by(tcx.local_parent(item)); } } + tcx.arena.alloc_from_iter(collector.opaques) } #[instrument(level = "trace", skip(tcx), ret)] From b07d27c81e0d40c41c26ea37c19eb61211c76095 Mon Sep 17 00:00:00 2001 From: Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> Date: Thu, 29 Jun 2023 07:19:06 +0000 Subject: [PATCH 06/11] Move some logic into a method on `OpaqueTypeCollector` --- compiler/rustc_ty_utils/src/opaque_types.rs | 62 +++++++++++---------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 245352bfd3b1a..7ddbafdb636c9 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -97,6 +97,38 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { // Syntactically, we are allowed to define the concrete type if: hir_id == scope } + + 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); + // An item is allowed to constrain opaques declared within its own body (but not nested within + // nested functions). + for id in self.find_taits_declared_in_body() { + self.opaques.extend(self.tcx.opaque_types_defined_by(id)) + } + } + + #[instrument(level = "trace", skip(self), ret)] + fn find_taits_declared_in_body(&self) -> Vec<LocalDefId> { + let body = self.tcx.hir().body(self.tcx.hir().body_owned_by(self.item)).value; + struct TaitInBodyFinder<'tcx> { + /// Ids of type aliases found in the body + type_aliases: Vec<LocalDefId>, + tcx: TyCtxt<'tcx>, + } + impl<'v> intravisit::Visitor<'v> for TaitInBodyFinder<'_> { + #[instrument(level = "trace", skip(self))] + fn visit_nested_item(&mut self, id: rustc_hir::ItemId) { + let id = id.owner_id.def_id; + if let DefKind::TyAlias = self.tcx.def_kind(id) { + self.type_aliases.push(id); + } + } + } + let mut visitor = TaitInBodyFinder { type_aliases: Default::default(), tcx: self.tcx }; + visitor.visit_expr(body); + visitor.type_aliases + } } impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> { @@ -274,13 +306,7 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [ } _ => unreachable!(), } - // Look at all where bounds. - tcx.predicates_of(item).instantiate_identity(tcx).visit_with(&mut collector); - // An item is allowed to constrain opaques declared within its own body (but not nested within - // nested functions). - for id in find_taits_declared_in_body(tcx, item) { - collector.opaques.extend(tcx.opaque_types_defined_by(id)) - } + collector.collect_body_and_predicate_taits(); } DefKind::TyAlias | DefKind::AssocTy => { tcx.type_of(item).subst_identity().visit_with(&mut collector); @@ -317,28 +343,6 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [ tcx.arena.alloc_from_iter(collector.opaques) } -#[instrument(level = "trace", skip(tcx), ret)] -fn find_taits_declared_in_body(tcx: TyCtxt<'_>, item: LocalDefId) -> Vec<LocalDefId> { - let body = tcx.hir().body(tcx.hir().body_owned_by(item)).value; - struct TaitInBodyFinder<'tcx> { - /// Ids of type aliases found in the body - type_aliases: Vec<LocalDefId>, - tcx: TyCtxt<'tcx>, - } - impl<'v> intravisit::Visitor<'v> for TaitInBodyFinder<'_> { - #[instrument(level = "trace", skip(self))] - fn visit_nested_item(&mut self, id: rustc_hir::ItemId) { - let id = id.owner_id.def_id; - if let DefKind::TyAlias = self.tcx.def_kind(id) { - self.type_aliases.push(id); - } - } - } - let mut visitor = TaitInBodyFinder { type_aliases: Default::default(), tcx }; - visitor.visit_expr(body); - visitor.type_aliases -} - pub(super) fn provide(providers: &mut Providers) { *providers = Providers { opaque_types_defined_by, ..*providers }; } From 18f3d8658815f260909b3485b20baa16ffbddde9 Mon Sep 17 00:00:00 2001 From: Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> Date: Thu, 29 Jun 2023 07:23:11 +0000 Subject: [PATCH 07/11] Collect nested items immediately instead of collecting them into an intermediate `Vec` first --- compiler/rustc_ty_utils/src/opaque_types.rs | 25 +++++++++------------ 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 7ddbafdb636c9..981919b731323 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -103,31 +103,26 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { self.tcx.predicates_of(self.item).instantiate_identity(self.tcx).visit_with(self); // An item is allowed to constrain opaques declared within its own body (but not nested within // nested functions). - for id in self.find_taits_declared_in_body() { - self.opaques.extend(self.tcx.opaque_types_defined_by(id)) - } + self.collect_taits_declared_in_body(); } - #[instrument(level = "trace", skip(self), ret)] - fn find_taits_declared_in_body(&self) -> Vec<LocalDefId> { + #[instrument(level = "trace", skip(self))] + fn collect_taits_declared_in_body(&mut self) { let body = self.tcx.hir().body(self.tcx.hir().body_owned_by(self.item)).value; - struct TaitInBodyFinder<'tcx> { - /// Ids of type aliases found in the body - type_aliases: Vec<LocalDefId>, - tcx: TyCtxt<'tcx>, + struct TaitInBodyFinder<'a, 'tcx> { + collector: &'a mut OpaqueTypeCollector<'tcx>, } - impl<'v> intravisit::Visitor<'v> for TaitInBodyFinder<'_> { + impl<'v> intravisit::Visitor<'v> for TaitInBodyFinder<'_, '_> { #[instrument(level = "trace", skip(self))] fn visit_nested_item(&mut self, id: rustc_hir::ItemId) { let id = id.owner_id.def_id; - if let DefKind::TyAlias = self.tcx.def_kind(id) { - self.type_aliases.push(id); + if let DefKind::TyAlias = self.collector.tcx.def_kind(id) { + let items = self.collector.tcx.opaque_types_defined_by(id); + self.collector.opaques.extend(items); } } } - let mut visitor = TaitInBodyFinder { type_aliases: Default::default(), tcx: self.tcx }; - visitor.visit_expr(body); - visitor.type_aliases + TaitInBodyFinder { collector: self }.visit_expr(body); } } From dcacfe7395cae68ecf8f8efe6803a121f4b74e99 Mon Sep 17 00:00:00 2001 From: Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> Date: Thu, 29 Jun 2023 07:24:04 +0000 Subject: [PATCH 08/11] Only match on the `DefKind` once. --- compiler/rustc_ty_utils/src/opaque_types.rs | 48 ++++++++------------- 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 981919b731323..2a706d72843fd 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -268,41 +268,31 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [ trace!(?kind); let mut collector = OpaqueTypeCollector::new(tcx, item); match kind { - // We're also doing this for `AssocTy` for the wf checks in `check_opaque_meets_bounds` + // Walk over the signature of the function-like to find the opaques. + DefKind::AssocFn | DefKind::Fn => { + let ty_sig = tcx.fn_sig(item).subst_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()); + 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.collect_body_and_predicate_taits(); + } + // Walk over the type of the item to find opaques. DefKind::Static(_) | DefKind::Const | DefKind::AssocConst - | DefKind::AssocFn | DefKind::AnonConst - | DefKind::InlineConst - | DefKind::Fn => { - 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).subst_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()); - for (hir, ty) in hir_sig.decl.inputs.iter().zip(ty_sig.inputs().iter()) { - collector.visit_spanned(hir.span, ty.map_bound(|x| *x)); - } - } - // Walk over the type of the item to find opaques. - DefKind::Static(_) - | DefKind::Const - | DefKind::AssocConst - | DefKind::AnonConst - | DefKind::InlineConst => { - let span = match tcx.hir().get_by_def_id(item).ty() { - Some(ty) => ty.span, - _ => tcx.def_span(item), - }; - collector.visit_spanned(span, tcx.type_of(item).subst_identity()); - } - _ => unreachable!(), - } + | DefKind::InlineConst => { + let span = match tcx.hir().get_by_def_id(item).ty() { + Some(ty) => ty.span, + _ => tcx.def_span(item), + }; + collector.visit_spanned(span, tcx.type_of(item).subst_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).subst_identity().visit_with(&mut collector); } From ef52dc7bb8c14c5663773f70e1353fd53131261c Mon Sep 17 00:00:00 2001 From: Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> Date: Thu, 29 Jun 2023 07:47:29 +0000 Subject: [PATCH 09/11] Add regression test --- .../nested_in_closure.rs | 10 +++++++ .../nested_in_closure.stderr | 28 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 tests/ui/type-alias-impl-trait/nested_in_closure.rs create mode 100644 tests/ui/type-alias-impl-trait/nested_in_closure.stderr diff --git a/tests/ui/type-alias-impl-trait/nested_in_closure.rs b/tests/ui/type-alias-impl-trait/nested_in_closure.rs new file mode 100644 index 0000000000000..3e9453559d504 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/nested_in_closure.rs @@ -0,0 +1,10 @@ +#![feature(type_alias_impl_trait)] + +fn main() { + let x = || { + type Tait = impl Sized; + let y: Tait = (); + //~^ ERROR: item constrains opaque type that is not in its signature + //~| ERROR: item constrains opaque type that is not in its signature + }; +} diff --git a/tests/ui/type-alias-impl-trait/nested_in_closure.stderr b/tests/ui/type-alias-impl-trait/nested_in_closure.stderr new file mode 100644 index 0000000000000..c2e584793ad12 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/nested_in_closure.stderr @@ -0,0 +1,28 @@ +error: item constrains opaque type that is not in its signature + --> $DIR/nested_in_closure.rs:6:23 + | +LL | let y: Tait = (); + | ^^ + | + = note: this item must have the opaque type in its signature in order to be able to register hidden types +note: this item must have the opaque type in its signature in order to be able to register hidden types + --> $DIR/nested_in_closure.rs:3:4 + | +LL | fn main() { + | ^^^^ + +error: item constrains opaque type that is not in its signature + --> $DIR/nested_in_closure.rs:6:23 + | +LL | let y: Tait = (); + | ^^ + | + = note: this item must have the opaque type in its signature in order to be able to register hidden types +note: this item must have the opaque type in its signature in order to be able to register hidden types + --> $DIR/nested_in_closure.rs:4:13 + | +LL | let x = || { + | ^^ + +error: aborting due to 2 previous errors + From b549ba1bd4313990d164bc7152e61aefd68eeacd Mon Sep 17 00:00:00 2001 From: Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> Date: Thu, 29 Jun 2023 07:52:45 +0000 Subject: [PATCH 10/11] Fix one layer of closures not being able to constrain opaque types --- compiler/rustc_ty_utils/src/opaque_types.rs | 5 ++++- .../ui/type-alias-impl-trait/nested_in_closure.rs | 1 - .../nested_in_closure.stderr | 15 +-------------- 3 files changed, 5 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 2a706d72843fd..40d61f47adb39 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -322,7 +322,10 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [ | DefKind::GlobalAsm | DefKind::Impl { .. } => {} DefKind::Closure | DefKind::Generator => { - return tcx.opaque_types_defined_by(tcx.local_parent(item)); + // All items in the signature of the parent are ok + collector.opaques.extend(tcx.opaque_types_defined_by(tcx.local_parent(item))); + // And items in the body of the closure itself + collector.collect_taits_declared_in_body(); } } tcx.arena.alloc_from_iter(collector.opaques) diff --git a/tests/ui/type-alias-impl-trait/nested_in_closure.rs b/tests/ui/type-alias-impl-trait/nested_in_closure.rs index 3e9453559d504..3c15b0708a3a6 100644 --- a/tests/ui/type-alias-impl-trait/nested_in_closure.rs +++ b/tests/ui/type-alias-impl-trait/nested_in_closure.rs @@ -5,6 +5,5 @@ fn main() { type Tait = impl Sized; let y: Tait = (); //~^ ERROR: item constrains opaque type that is not in its signature - //~| ERROR: item constrains opaque type that is not in its signature }; } diff --git a/tests/ui/type-alias-impl-trait/nested_in_closure.stderr b/tests/ui/type-alias-impl-trait/nested_in_closure.stderr index c2e584793ad12..beb670db17129 100644 --- a/tests/ui/type-alias-impl-trait/nested_in_closure.stderr +++ b/tests/ui/type-alias-impl-trait/nested_in_closure.stderr @@ -11,18 +11,5 @@ note: this item must have the opaque type in its signature in order to be able t LL | fn main() { | ^^^^ -error: item constrains opaque type that is not in its signature - --> $DIR/nested_in_closure.rs:6:23 - | -LL | let y: Tait = (); - | ^^ - | - = note: this item must have the opaque type in its signature in order to be able to register hidden types -note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/nested_in_closure.rs:4:13 - | -LL | let x = || { - | ^^ - -error: aborting due to 2 previous errors +error: aborting due to previous error From c3004a7b6523bfe939df0f73b49f63510557e735 Mon Sep 17 00:00:00 2001 From: Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> Date: Thu, 29 Jun 2023 13:32:37 +0000 Subject: [PATCH 11/11] Treat closures as part of their parent --- compiler/rustc_ty_utils/src/opaque_types.rs | 20 +++++++++---------- .../nested_in_closure.rs | 10 +++++++++- .../nested_in_closure.stderr | 15 -------------- 3 files changed, 19 insertions(+), 26 deletions(-) delete mode 100644 tests/ui/type-alias-impl-trait/nested_in_closure.stderr diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 40d61f47adb39..570c3b245cd41 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -121,6 +121,12 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { self.collector.opaques.extend(items); } } + #[instrument(level = "trace", skip(self))] + // Recurse into these, as they are type checked with their parent + fn visit_nested_body(&mut self, id: rustc_hir::BodyId) { + let body = self.collector.tcx.hir().body(id); + self.visit_body(body); + } } TaitInBodyFinder { collector: self }.visit_expr(body); } @@ -280,11 +286,7 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [ collector.collect_body_and_predicate_taits(); } // Walk over the type of the item to find opaques. - DefKind::Static(_) - | DefKind::Const - | DefKind::AssocConst - | DefKind::AnonConst - | DefKind::InlineConst => { + DefKind::Static(_) | DefKind::Const | DefKind::AssocConst | DefKind::AnonConst => { let span = match tcx.hir().get_by_def_id(item).ty() { Some(ty) => ty.span, _ => tcx.def_span(item), @@ -321,11 +323,9 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [ | DefKind::LifetimeParam | DefKind::GlobalAsm | DefKind::Impl { .. } => {} - DefKind::Closure | DefKind::Generator => { - // All items in the signature of the parent are ok - collector.opaques.extend(tcx.opaque_types_defined_by(tcx.local_parent(item))); - // And items in the body of the closure itself - collector.collect_taits_declared_in_body(); + // Closures and generators are type checked with their parent, so there is no difference here. + DefKind::Closure | DefKind::Generator | DefKind::InlineConst => { + return tcx.opaque_types_defined_by(tcx.local_parent(item)); } } tcx.arena.alloc_from_iter(collector.opaques) diff --git a/tests/ui/type-alias-impl-trait/nested_in_closure.rs b/tests/ui/type-alias-impl-trait/nested_in_closure.rs index 3c15b0708a3a6..362f3d53e88bf 100644 --- a/tests/ui/type-alias-impl-trait/nested_in_closure.rs +++ b/tests/ui/type-alias-impl-trait/nested_in_closure.rs @@ -1,9 +1,17 @@ #![feature(type_alias_impl_trait)] +// check-pass fn main() { let x = || { type Tait = impl Sized; let y: Tait = (); - //~^ ERROR: item constrains opaque type that is not in its signature }; + + let y = || { + type Tait = impl std::fmt::Debug; + let y: Tait = (); + y + }; + let mut z = y(); + z = (); } diff --git a/tests/ui/type-alias-impl-trait/nested_in_closure.stderr b/tests/ui/type-alias-impl-trait/nested_in_closure.stderr deleted file mode 100644 index beb670db17129..0000000000000 --- a/tests/ui/type-alias-impl-trait/nested_in_closure.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: item constrains opaque type that is not in its signature - --> $DIR/nested_in_closure.rs:6:23 - | -LL | let y: Tait = (); - | ^^ - | - = note: this item must have the opaque type in its signature in order to be able to register hidden types -note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/nested_in_closure.rs:3:4 - | -LL | fn main() { - | ^^^^ - -error: aborting due to previous error -