Rollup merge of #121991 - oli-obk:merge_opaque_types_defined_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 https://github.com/rust-lang/rust/pull/121838
This commit is contained in:
commit
3d6b3d0f59
@ -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) {
|
for &assoc_id in tcx.associated_item_def_ids(impl_def_id) {
|
||||||
let assoc = tcx.associated_item(assoc_id);
|
let assoc = tcx.associated_item(assoc_id);
|
||||||
match assoc.kind {
|
match assoc.kind {
|
||||||
ty::AssocKind::Const | ty::AssocKind::Fn => {
|
ty::AssocKind::Const | ty::AssocKind::Fn => locator.check(assoc_id.expect_local()),
|
||||||
locator.check(assoc_id.expect_local(), ImplTraitSource::AssocTy)
|
|
||||||
}
|
|
||||||
// Associated types don't have bodies, so they can't constrain hidden types
|
// Associated types don't have bodies, so they can't constrain hidden types
|
||||||
ty::AssocKind::Type => {}
|
ty::AssocKind::Type => {}
|
||||||
}
|
}
|
||||||
@ -182,15 +180,9 @@ struct TaitConstraintLocator<'tcx> {
|
|||||||
typeck_types: Vec<ty::OpaqueHiddenType<'tcx>>,
|
typeck_types: Vec<ty::OpaqueHiddenType<'tcx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
enum ImplTraitSource {
|
|
||||||
AssocTy,
|
|
||||||
TyAlias,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TaitConstraintLocator<'_> {
|
impl TaitConstraintLocator<'_> {
|
||||||
#[instrument(skip(self), level = "debug")]
|
#[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.
|
// Don't try to check items that cannot possibly constrain the type.
|
||||||
if !self.tcx.has_typeck_results(item_def_id) {
|
if !self.tcx.has_typeck_results(item_def_id) {
|
||||||
debug!("no constraint: no typeck results");
|
debug!("no constraint: no typeck results");
|
||||||
@ -242,12 +234,8 @@ impl TaitConstraintLocator<'_> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
constrained = true;
|
constrained = true;
|
||||||
let opaque_types_defined_by = match source {
|
let opaque_types_defined_by = self.tcx.opaque_types_defined_by(item_def_id);
|
||||||
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),
|
|
||||||
};
|
|
||||||
if !opaque_types_defined_by.contains(&self.def_id) {
|
if !opaque_types_defined_by.contains(&self.def_id) {
|
||||||
self.tcx.dcx().emit_err(TaitForwardCompat {
|
self.tcx.dcx().emit_err(TaitForwardCompat {
|
||||||
span: hidden_type.span,
|
span: hidden_type.span,
|
||||||
@ -308,7 +296,7 @@ impl<'tcx> intravisit::Visitor<'tcx> for TaitConstraintLocator<'tcx> {
|
|||||||
}
|
}
|
||||||
fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
|
fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
|
||||||
if let hir::ExprKind::Closure(closure) = ex.kind {
|
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);
|
intravisit::walk_expr(self, ex);
|
||||||
}
|
}
|
||||||
@ -316,7 +304,7 @@ impl<'tcx> intravisit::Visitor<'tcx> for TaitConstraintLocator<'tcx> {
|
|||||||
trace!(?it.owner_id);
|
trace!(?it.owner_id);
|
||||||
// The opaque type itself or its children are not within its reveal scope.
|
// The opaque type itself or its children are not within its reveal scope.
|
||||||
if it.owner_id.def_id != self.def_id {
|
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);
|
intravisit::walk_item(self, it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -324,13 +312,13 @@ impl<'tcx> intravisit::Visitor<'tcx> for TaitConstraintLocator<'tcx> {
|
|||||||
trace!(?it.owner_id);
|
trace!(?it.owner_id);
|
||||||
// The opaque type itself or its children are not within its reveal scope.
|
// The opaque type itself or its children are not within its reveal scope.
|
||||||
if it.owner_id.def_id != self.def_id {
|
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);
|
intravisit::walk_impl_item(self, it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn visit_trait_item(&mut self, it: &'tcx TraitItem<'tcx>) {
|
fn visit_trait_item(&mut self, it: &'tcx TraitItem<'tcx>) {
|
||||||
trace!(?it.owner_id);
|
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);
|
intravisit::walk_trait_item(self, it);
|
||||||
}
|
}
|
||||||
fn visit_foreign_item(&mut self, it: &'tcx hir::ForeignItem<'tcx>) {
|
fn visit_foreign_item(&mut self, it: &'tcx hir::ForeignItem<'tcx>) {
|
||||||
|
@ -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
|
/// Returns the list of bounds that can be used for
|
||||||
/// `SelectionCandidate::ProjectionCandidate(_)` and
|
/// `SelectionCandidate::ProjectionCandidate(_)` and
|
||||||
/// `ProjectionTyCandidate::TraitDef`.
|
/// `ProjectionTyCandidate::TraitDef`.
|
||||||
|
@ -34,7 +34,11 @@ enum CollectionMode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> OpaqueTypeCollector<'tcx> {
|
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 }
|
Self { tcx, opaques: Vec::new(), item, seen: Default::default(), span: None, mode }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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>(
|
fn opaque_types_defined_by<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
item: LocalDefId,
|
item: LocalDefId,
|
||||||
) -> &'tcx ty::List<LocalDefId> {
|
) -> &'tcx ty::List<LocalDefId> {
|
||||||
let kind = tcx.def_kind(item);
|
let kind = tcx.def_kind(item);
|
||||||
trace!(?kind);
|
trace!(?kind);
|
||||||
let mut collector =
|
let mut collector = OpaqueTypeCollector::new(tcx, item);
|
||||||
OpaqueTypeCollector::new(tcx, item, CollectionMode::TypeAliasImplTraitTransition);
|
|
||||||
super::sig_types::walk_types(tcx, item, &mut collector);
|
super::sig_types::walk_types(tcx, item, &mut collector);
|
||||||
match kind {
|
match kind {
|
||||||
DefKind::AssocFn
|
DefKind::AssocFn
|
||||||
@ -346,6 +340,5 @@ fn opaque_types_defined_by<'tcx>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn provide(providers: &mut Providers) {
|
pub(super) fn provide(providers: &mut Providers) {
|
||||||
*providers =
|
*providers = Providers { opaque_types_defined_by, ..*providers };
|
||||||
Providers { opaque_types_defined_by, impl_trait_in_assoc_types_defined_by, ..*providers };
|
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ impl Trait for Bar {
|
|||||||
type Assoc = impl std::fmt::Debug;
|
type Assoc = impl std::fmt::Debug;
|
||||||
fn foo() -> Foo {
|
fn foo() -> Foo {
|
||||||
Foo { field: () }
|
Foo { field: () }
|
||||||
//~^ ERROR: item constrains opaque type that is not in its signature
|
//~^ ERROR: mismatched types
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
error: item constrains opaque type that is not in its signature
|
error[E0308]: mismatched types
|
||||||
--> $DIR/hidden_behind_struct_field2.rs:17:22
|
--> $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: () }
|
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: expected opaque type `<Bar as Trait>::Assoc`
|
||||||
note: this item must mention the opaque type in its signature in order to be able to register hidden types
|
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
|
--> $DIR/hidden_behind_struct_field2.rs:16:8
|
||||||
|
|
|
|
||||||
LL | fn foo() -> Foo {
|
LL | fn foo() -> Foo {
|
||||||
@ -13,3 +17,4 @@ LL | fn foo() -> Foo {
|
|||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
@ -17,7 +17,7 @@ impl Trait for Bar {
|
|||||||
type Assoc = impl Iterator<Item = Foo>;
|
type Assoc = impl Iterator<Item = Foo>;
|
||||||
fn foo() -> Self::Assoc {
|
fn foo() -> Self::Assoc {
|
||||||
vec![Foo { field: () }].into_iter()
|
vec![Foo { field: () }].into_iter()
|
||||||
//~^ ERROR item constrains opaque type that is not in its signature
|
//~^ ERROR mismatched types
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
error: item constrains opaque type that is not in its signature
|
error[E0308]: mismatched types
|
||||||
--> $DIR/hidden_behind_struct_field3.rs:19:27
|
--> $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()
|
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: expected opaque type `<Bar as Trait>::Assoc2`
|
||||||
note: this item must mention the opaque type in its signature in order to be able to register hidden types
|
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
|
--> $DIR/hidden_behind_struct_field3.rs:18:8
|
||||||
|
|
|
|
||||||
LL | fn foo() -> Self::Assoc {
|
LL | fn foo() -> Self::Assoc {
|
||||||
@ -13,3 +17,4 @@ LL | fn foo() -> Self::Assoc {
|
|||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user