From 4c99872efe97c8e6183dfc9b729bc3a2903ac40b Mon Sep 17 00:00:00 2001 From: Oli Scherer 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 f3ee83fd4d21..51e1fe531dd1 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 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 0738961d6ce4..166760166c10 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 f4779a3f2653..957a6bb34810 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 205e26d0edaa..c2d2e5f7e50f 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 05e5db9f0f3a..d5619af2aae1 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 c9a8f8131dff..63613b59020f 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 Trait 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 e2ee347b639a..1af8323b6e99 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 29de8bf0e53f..bc002cdce71a 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, + universes: Vec>, + span: Option, } 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 { 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> for OpaqueTypeCollector<'tcx> { + fn visit_binder>>( + &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> 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> 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> 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 { + 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, + } + 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 0d019b1f5020..3f49020bbea3 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 000000000000..bc3a4e129651 --- /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; + //^ 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 000000000000..8330a387ecd5 --- /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; + | ------------------------ 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 000000000000..dacbc93dec88 --- /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; + +trait Trait<'x> { + type Thing; +} + +impl<'x, T: 'x> Trait<'x> for (T,) { + type Thing = T; +} + +impl Foo<'_> { + fn make_fut(&self) -> Box 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 000000000000..3187be3334c5 --- /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 Trait<'a, Thing = Fut<'a>>> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^query stack during panic: +#0 [typeck] type-checking `::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 d2c347920357..7a51aac44e2e 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 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 36c54bdd6de3..38ad2fa6f02e 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 { diff --git a/tests/ui/impl-trait/in-assoc-type.stderr b/tests/ui/impl-trait/in-assoc-type.stderr index ab3f3a14410d..af60da07cac3 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) -> >::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) -> >::Bar {} | ^^^ diff --git a/tests/ui/impl-trait/issues/issue-70877.rs b/tests/ui/impl-trait/issues/issue-70877.rs index 8169cfafac71..df7722986744 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 8813bff3c353..ee140e6f6c43 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 654de0cd0253..51bd5f67ed57 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 724f3c5d6747..d43e9fee0b35 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 000000000000..cf5361e1e602 --- /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; + +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 000000000000..6db603e77517 --- /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 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 7b5ab5f22983..75ccc8d8e8a9 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; - struct Bug { V1: [(); { + type F = impl core::future::Future; 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 05a2c135cf7c..36340a0bab41 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 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 028222f4e6db..309bee8aa8c2 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 = impl NeedsSend; trait NeedsSend {} impl NeedsSend for T {} -fn define(a: A, b: B) { +fn define(a: A, b: B, _: Foo) { let y: Option> = 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 5a0dcd0e8cce..08f14d7494d7 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() {} -fn test() { +fn test(_: Foo) { needs_send::(); //[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 99a3d02bd1ae..77ea8bc246e6 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; -fn mk() -> T { todo!() } +fn mk() -> 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 01141b2819a8..01ef2ec953ae 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 532c4c39bd49..70d9dc0eaa8a 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 { todo!() } +fn mk() -> 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 0bcc9e002ca0..4e9f65d88a12 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 {} impl Trait for () {} fn foo_desugared(_: T) -> Foo { + //~^ ERROR non-defining opaque type use () //~^ ERROR expected generic type parameter, found `::Assoc` } diff --git a/tests/ui/type-alias-impl-trait/bound_reduction2.stderr b/tests/ui/type-alias-impl-trait/bound_reduction2.stderr index 3c259bd9e97c..14f9dbbdb4e9 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) -> Foo { + | ^^^^^^^^^^^^^ argument `::Assoc` is not a generic parameter + | +note: for this opaque type + --> $DIR/bound_reduction2.rs:9:15 + | +LL | type Foo = impl Trait; + | ^^^^^^^^^^^^^ + error[E0792]: expected generic type parameter, found `::Assoc` - --> $DIR/bound_reduction2.rs:16:5 + --> $DIR/bound_reduction2.rs:17:5 | LL | type Foo = impl Trait; | - this generic parameter must be used with a generic type parameter @@ -7,6 +19,6 @@ LL | type Foo = impl Trait; 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 c5e7af81d3dd..243f9cd6d4f4 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: 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 82386c280a8e..1dd5c3e40cda 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 Foo for T {} @@ -14,10 +16,17 @@ impl B { } type Input = impl Foo; -fn run1(f: F, i: Input) {f(i)} -fn run2(f: F, i: B) {f(i)} +fn run1(f: F, i: Input) { + f(i) +} +fn run2(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 fbfa0ccf1e8d..d60f1ffbccc2 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 e5bfbfdae91f..b2842df150a3 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 f2eb7bc4dc79..b138f9d5c45a 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 2b30a9cd57cf..a4ac27378e1d 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 = impl Sized; -fn foo() { +fn foo() -> Tait { if false { if { return } { let y: Tait = 1i32; @@ -10,6 +10,7 @@ fn foo() { } } let x: Tait = (); + 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 9d938a61600f..14ced3418542 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 72e1ef4b4923..4da69a705c07 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 80462f8ac046..1e391b55a4fa 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 = 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 = impl Debug; - fn one_ty(t: T) -> TwoTys { + //~^ ERROR non-defining opaque type use in defining scope t //~^ ERROR non-defining opaque type use in defining scope } fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> { + //~^ ERROR non-defining opaque type use in defining scope t //~^ ERROR non-defining opaque type use in defining scope } fn one_const(t: *mut [u8; N]) -> TwoConsts { + //~^ ERROR non-defining opaque type use in defining scope t //~^ ERROR non-defining opaque type use in defining scope } diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr index 98e4bfea10d6..d8330771d301 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: T) -> TwoTys { + | ^^^^^^^^^^^^ generic argument `T` used twice + | +note: for this opaque type + --> $DIR/generic_duplicate_param_use.rs:15:21 + | +LL | type TwoTys = impl Debug; + | ^^^^^^^^^^ + +error: non-defining opaque type use in defining scope + --> $DIR/generic_duplicate_param_use.rs: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 = 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(t: *mut [u8; N]) -> TwoConsts { + | ^^^^^^^^^^^^^^^ generic argument `N` used twice + | +note: for this opaque type + --> $DIR/generic_duplicate_param_use.rs:23:50 + | +LL | type TwoConsts = 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 = 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 e7b8567b9a21..68f4c6923ae1 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 = impl Debug; // Not defining uses, because they doesn't define *all* possible generics. fn concrete_ty() -> OneTy { + //~^ ERROR: non-defining opaque type use in defining scope 5u32 - //~^ ERROR expected generic type parameter, found `u32` + //~^ 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 966fe823f024..e3b7b1a76b09 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 { + | ^^^^^^^^^^ argument `u32` is not a generic parameter + | +note: for this opaque type + --> $DIR/generic_nondefining_use.rs:7:17 + | +LL | type OneTy = impl Debug; + | ^^^^^^^^^^ + error[E0792]: expected generic type parameter, found `u32` - --> $DIR/generic_nondefining_use.rs:16:5 + --> $DIR/generic_nondefining_use.rs:17:5 | LL | type OneTy = impl Debug; | - this generic parameter must be used with a generic type parameter @@ -7,8 +19,20 @@ LL | type OneTy = impl Debug; LL | 5u32 | ^^^^ +error[E0792]: non-defining opaque type use in defining scope + --> $DIR/generic_nondefining_use.rs:21:27 + | +LL | fn concrete_lifetime() -> OneLifetime<'static> { + | ^^^^^^^^^^^^^^^^^^^^ argument `'static` is not a generic parameter + | +note: for this opaque type + --> $DIR/generic_nondefining_use.rs:9:24 + | +LL | type OneLifetime<'a> = impl Debug; + | ^^^^^^^^^^ + error[E0792]: expected generic lifetime parameter, found `'static` - --> $DIR/generic_nondefining_use.rs: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 = 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 = impl Debug; | -------------- this generic parameter must be used with a generic constant parameter @@ -25,6 +61,6 @@ LL | type OneConst = 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 cdd8f6f1976a..c60f5c11cd18 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 = impl 'static; -//~^ ERROR: at least one trait must be specified + type WrongGeneric = impl 'static; + //~^ ERROR: at least one trait must be specified -fn wrong_generic(t: T) -> WrongGeneric { - t - //~^ ERROR the parameter type `T` may not live long enough + fn wrong_generic(t: T) -> WrongGeneric { + 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 fa79e51e9f79..8c3a25dbfe7d 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 = impl 'static; - | ^^^^^^^^^^^^ +LL | type WrongGeneric = 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 = impl 'static; - | - this generic parameter must be used with a generic type parameter +LL | type WrongGeneric = 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: T) -> WrongGeneric { - | +++++++++ +LL | fn wrong_generic(t: T) -> WrongGeneric { + | +++++++++ 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 000000000000..db1a3a1c7a9d --- /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 000000000000..d5030e60c63c --- /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 839a611cb71a..a6a7ffce507a 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 aaba9ad5ca70..8f6bee7d29e6 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 093afc25249a..20175a4feca0 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) {} 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 a3f126d56cf2..a213dbba4ea0 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 = impl Generator; +mod gen { + use std::ops::Generator; -const fn const_generator(yielding: Y, returning: R) -> GenOnce { - move || { - yield yielding; + pub type GenOnce = impl Generator; - return returning; + pub const fn const_generator(yielding: Y, returning: R) -> GenOnce { + move || { + yield yielding; + + return returning; + } } } -const FOO: GenOnce = const_generator(10, 100); +const FOO: gen::GenOnce = 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 eb1c9603a60d..000000000000 --- 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 4aa5966ff25d..61af7a0f6250 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` 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 c2f4c3708074..48bd70bcca95 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; 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 f8fdb004d098..d42495e934d3 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 = impl std::iter::Iterator; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0792]: expected generic type parameter, found `u8` - --> $DIR/issue-60564.rs:20:9 + --> $DIR/issue-60564.rs:21:9 | LL | type IterBitsIter = impl std::iter::Iterator; | - this generic parameter must be used with a generic type parameter @@ -7,6 +19,6 @@ LL | type IterBitsIter = impl std::iter::Iterator; LL | (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 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 7414611a7489..ddea7aeb6cda 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 b91cbce3727f..7b3e9e12405c 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 5e0a82a72868..9dcdb578568a 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 {} type Alias<'a, U> = impl Trait; 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 271743a4010c..085bffe907b4 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; + | ^^^^^^^^^^^^^ + 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 3b32260c96fe..dfe2ee8204c7 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; 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 4d9a8d6eef91..ea704ffff97a 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; + | ^^^^^^^^^^^^^ + 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 7657fe2fb1ae..a0f8e48e268c 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 WithAssoc for () { type Return = impl WithAssoc; //~^ ERROR use of undeclared lifetime name `'a` -fn my_fun() -> Return<()> {} -//~^ ERROR expected generic type parameter, found `()` +fn my_fun() -> Return {} 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 d1250786d938..b7af3f06d0d9 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 = impl WithAssoc; | ^^ undeclared lifetime @@ -14,16 +14,6 @@ help: consider introducing lifetime `'a` here LL | type Return<'a, A> = impl WithAssoc; | +++ -error[E0792]: expected generic type parameter, found `()` - --> $DIR/issue-69136-inner-lifetime-resolve-error.rs:20:27 - | -LL | type Return = impl WithAssoc; - | - 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 8d818d4a387a..e7b04a489755 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 = impl std::ops::Deref; +type Pointer = impl std::ops::Deref; 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 60b6e1aac628..07607516cc4b 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 ae03a5b3e37b..863282a0ff94 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 75015e41c3da..7943bb240f15 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::(); //~^ 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 202a87ecbb77..0c5ef4a6fb41 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 4e9d1788b94d..36161171555c 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(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 1dabe4586c5b..7d7cad874fae 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 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 bc002cdce71a..bf5f1bb747c7 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> 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> 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 616eb935e93d..ba5031167e33 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 000000000000..3a46ce7e1952 --- /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 d5030e60c63c..f011e5b21481 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 000000000000..39f584dd49ca --- /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 a6a7ffce507a..6edfccaf7d17 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 8f6bee7d29e6..14372d8f3e64 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 dff0d89d465d..bfd8d8872e37 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; @@ -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 000000000000..30c3ddd8659d --- /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 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 bf5f1bb747c7..146f7cd371c4 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, - universes: Vec>, - span: Option, } 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> for OpaqueTypeCollector<'tcx> { - fn visit_binder>>( - &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 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 146f7cd371c4..919cbcfc9517 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 { 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, + 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 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 919cbcfc9517..245352bfd3b1 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> 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 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 245352bfd3b1..7ddbafdb636c 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 { + 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, + 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> 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 { - 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, - 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 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 7ddbafdb636c..981919b73132 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 { + #[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, - 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 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 981919b73132..2a706d72843f 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 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 000000000000..3e9453559d50 --- /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 000000000000..c2e584793ad1 --- /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 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 2a706d72843f..40d61f47adb3 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 3e9453559d50..3c15b0708a3a 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 c2e584793ad1..beb670db1712 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 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 40d61f47adb3..570c3b245cd4 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 3c15b0708a3a..362f3d53e88b 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 beb670db1712..000000000000 --- 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 -