Skip to content

Commit

Permalink
Rollup merge of rust-lang#121991 - oli-obk:merge_opaque_types_defined…
Browse files Browse the repository at this point in the history
…_by_queries, r=compiler-errors

Merge impl_trait_in_assoc_types_defined_by query back into `opaque_types_defined_by`

Instead, when we're collecting opaques for associated items, we choose the right collection mode depending on whether we're collecting for an associated item of a trait impl or not.

r? `@compiler-errors`

follow up to rust-lang#121838
  • Loading branch information
matthiaskrgr authored Mar 5, 2024
2 parents d08dcea + da35734 commit 9e3f983
Show file tree
Hide file tree
Showing 7 changed files with 35 additions and 53 deletions.
28 changes: 8 additions & 20 deletions compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,7 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type(
for &assoc_id in tcx.associated_item_def_ids(impl_def_id) {
let assoc = tcx.associated_item(assoc_id);
match assoc.kind {
ty::AssocKind::Const | ty::AssocKind::Fn => {
locator.check(assoc_id.expect_local(), ImplTraitSource::AssocTy)
}
ty::AssocKind::Const | ty::AssocKind::Fn => locator.check(assoc_id.expect_local()),
// Associated types don't have bodies, so they can't constrain hidden types
ty::AssocKind::Type => {}
}
Expand Down Expand Up @@ -182,15 +180,9 @@ struct TaitConstraintLocator<'tcx> {
typeck_types: Vec<ty::OpaqueHiddenType<'tcx>>,
}

#[derive(Debug)]
enum ImplTraitSource {
AssocTy,
TyAlias,
}

impl TaitConstraintLocator<'_> {
#[instrument(skip(self), level = "debug")]
fn check(&mut self, item_def_id: LocalDefId, source: ImplTraitSource) {
fn check(&mut self, item_def_id: LocalDefId) {
// Don't try to check items that cannot possibly constrain the type.
if !self.tcx.has_typeck_results(item_def_id) {
debug!("no constraint: no typeck results");
Expand Down Expand Up @@ -242,12 +234,8 @@ impl TaitConstraintLocator<'_> {
continue;
}
constrained = true;
let opaque_types_defined_by = match source {
ImplTraitSource::AssocTy => {
self.tcx.impl_trait_in_assoc_types_defined_by(item_def_id)
}
ImplTraitSource::TyAlias => self.tcx.opaque_types_defined_by(item_def_id),
};
let opaque_types_defined_by = self.tcx.opaque_types_defined_by(item_def_id);

if !opaque_types_defined_by.contains(&self.def_id) {
self.tcx.dcx().emit_err(TaitForwardCompat {
span: hidden_type.span,
Expand Down Expand Up @@ -308,29 +296,29 @@ impl<'tcx> intravisit::Visitor<'tcx> for TaitConstraintLocator<'tcx> {
}
fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
if let hir::ExprKind::Closure(closure) = ex.kind {
self.check(closure.def_id, ImplTraitSource::TyAlias);
self.check(closure.def_id);
}
intravisit::walk_expr(self, ex);
}
fn visit_item(&mut self, it: &'tcx Item<'tcx>) {
trace!(?it.owner_id);
// The opaque type itself or its children are not within its reveal scope.
if it.owner_id.def_id != self.def_id {
self.check(it.owner_id.def_id, ImplTraitSource::TyAlias);
self.check(it.owner_id.def_id);
intravisit::walk_item(self, it);
}
}
fn visit_impl_item(&mut self, it: &'tcx ImplItem<'tcx>) {
trace!(?it.owner_id);
// The opaque type itself or its children are not within its reveal scope.
if it.owner_id.def_id != self.def_id {
self.check(it.owner_id.def_id, ImplTraitSource::TyAlias);
self.check(it.owner_id.def_id);
intravisit::walk_impl_item(self, it);
}
}
fn visit_trait_item(&mut self, it: &'tcx TraitItem<'tcx>) {
trace!(?it.owner_id);
self.check(it.owner_id.def_id, ImplTraitSource::TyAlias);
self.check(it.owner_id.def_id);
intravisit::walk_trait_item(self, it);
}
fn visit_foreign_item(&mut self, it: &'tcx hir::ForeignItem<'tcx>) {
Expand Down
9 changes: 0 additions & 9 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,15 +344,6 @@ rustc_queries! {
}
}

query impl_trait_in_assoc_types_defined_by(
key: LocalDefId
) -> &'tcx ty::List<LocalDefId> {
desc {
|tcx| "computing the opaque types defined by `{}`",
tcx.def_path_str(key.to_def_id())
}
}

/// Returns the list of bounds that can be used for
/// `SelectionCandidate::ProjectionCandidate(_)` and
/// `ProjectionTyCandidate::TraitDef`.
Expand Down
21 changes: 7 additions & 14 deletions compiler/rustc_ty_utils/src/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@ enum CollectionMode {
}

impl<'tcx> OpaqueTypeCollector<'tcx> {
fn new(tcx: TyCtxt<'tcx>, item: LocalDefId, mode: CollectionMode) -> Self {
fn new(tcx: TyCtxt<'tcx>, item: LocalDefId) -> Self {
let mode = match tcx.def_kind(tcx.local_parent(item)) {
DefKind::Impl { of_trait: true } => CollectionMode::ImplTraitInAssocTypes,
_ => CollectionMode::TypeAliasImplTraitTransition,
};
Self { tcx, opaques: Vec::new(), item, seen: Default::default(), span: None, mode }
}

Expand Down Expand Up @@ -287,23 +291,13 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
}
}

fn impl_trait_in_assoc_types_defined_by<'tcx>(
tcx: TyCtxt<'tcx>,
item: LocalDefId,
) -> &'tcx ty::List<LocalDefId> {
let mut collector = OpaqueTypeCollector::new(tcx, item, CollectionMode::ImplTraitInAssocTypes);
super::sig_types::walk_types(tcx, item, &mut collector);
tcx.mk_local_def_ids(&collector.opaques)
}

fn opaque_types_defined_by<'tcx>(
tcx: TyCtxt<'tcx>,
item: LocalDefId,
) -> &'tcx ty::List<LocalDefId> {
let kind = tcx.def_kind(item);
trace!(?kind);
let mut collector =
OpaqueTypeCollector::new(tcx, item, CollectionMode::TypeAliasImplTraitTransition);
let mut collector = OpaqueTypeCollector::new(tcx, item);
super::sig_types::walk_types(tcx, item, &mut collector);
match kind {
DefKind::AssocFn
Expand Down Expand Up @@ -346,6 +340,5 @@ fn opaque_types_defined_by<'tcx>(
}

pub(super) fn provide(providers: &mut Providers) {
*providers =
Providers { opaque_types_defined_by, impl_trait_in_assoc_types_defined_by, ..*providers };
*providers = Providers { opaque_types_defined_by, ..*providers };
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ impl Trait for Bar {
type Assoc = impl std::fmt::Debug;
fn foo() -> Foo {
Foo { field: () }
//~^ ERROR: item constrains opaque type that is not in its signature
//~^ ERROR: mismatched types
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
error: item constrains opaque type that is not in its signature
error[E0308]: mismatched types
--> $DIR/hidden_behind_struct_field2.rs:17:22
|
LL | type Assoc = impl std::fmt::Debug;
| -------------------- the expected opaque type
LL | fn foo() -> Foo {
LL | Foo { field: () }
| ^^
| ^^ expected opaque type, found `()`
|
= 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
= note: expected opaque type `<Bar as Trait>::Assoc`
found unit type `()`
note: this item must have the opaque type in its signature in order to be able to register hidden types
--> $DIR/hidden_behind_struct_field2.rs:16:8
|
LL | fn foo() -> Foo {
| ^^^

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0308`.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ impl Trait for Bar {
type Assoc = impl Iterator<Item = Foo>;
fn foo() -> Self::Assoc {
vec![Foo { field: () }].into_iter()
//~^ ERROR item constrains opaque type that is not in its signature
//~^ ERROR mismatched types
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
error: item constrains opaque type that is not in its signature
error[E0308]: mismatched types
--> $DIR/hidden_behind_struct_field3.rs:19:27
|
LL | type Assoc2 = impl std::fmt::Debug;
| -------------------- the expected opaque type
...
LL | vec![Foo { field: () }].into_iter()
| ^^
| ^^ expected opaque type, found `()`
|
= 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
= note: expected opaque type `<Bar as Trait>::Assoc2`
found unit type `()`
note: this item must have the opaque type in its signature in order to be able to register hidden types
--> $DIR/hidden_behind_struct_field3.rs:18:8
|
LL | fn foo() -> Self::Assoc {
| ^^^

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0308`.

0 comments on commit 9e3f983

Please sign in to comment.