From 76b0cf812b70b458cbae480af75d788a29a43adc Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 21 Mar 2023 18:06:04 +0000 Subject: [PATCH 1/3] Walk return-position impl trait in trait deeply in associated_item_def_ids --- compiler/rustc_ty_utils/src/assoc.rs | 35 ++++++++++--------- .../impl-trait/in-trait/auxiliary/rpitit.rs | 7 ++-- tests/ui/impl-trait/in-trait/foreign.rs | 14 ++++++-- 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index bf0bc202852e4..de1e1a527d5a9 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -1,3 +1,4 @@ +use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; @@ -196,20 +197,26 @@ fn associated_types_for_impl_traits_in_associated_fn( match tcx.def_kind(parent_def_id) { DefKind::Trait => { - struct RPITVisitor { - rpits: Vec, + struct RPITVisitor<'tcx> { + rpits: FxIndexSet, + tcx: TyCtxt<'tcx>, } - impl<'v> Visitor<'v> for RPITVisitor { - fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) { - if let hir::TyKind::OpaqueDef(item_id, _, _) = ty.kind { - self.rpits.push(item_id.owner_id.def_id) + impl<'tcx> Visitor<'tcx> for RPITVisitor<'tcx> { + fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) { + if let hir::TyKind::OpaqueDef(item_id, _, _) = ty.kind + && self.rpits.insert(item_id.owner_id.def_id) + { + let opaque_item = self.tcx.hir().expect_item(item_id.owner_id.def_id).expect_opaque_ty(); + for bound in opaque_item.bounds { + intravisit::walk_param_bound(self, bound); + } } intravisit::walk_ty(self, ty) } } - let mut visitor = RPITVisitor { rpits: Vec::new() }; + let mut visitor = RPITVisitor { tcx, rpits: FxIndexSet::default() }; if let Some(output) = tcx.hir().get_fn_output(fn_def_id) { visitor.visit_fn_ret_ty(output); @@ -227,13 +234,9 @@ fn associated_types_for_impl_traits_in_associated_fn( tcx.arena.alloc_from_iter( tcx.associated_types_for_impl_traits_in_associated_fn(trait_fn_def_id).iter().map( - move |trait_assoc_def_id| { - associated_type_for_impl_trait_in_impl( - tcx, - trait_assoc_def_id.expect_local(), - fn_def_id, - ) - .to_def_id() + move |&trait_assoc_def_id| { + associated_type_for_impl_trait_in_impl(tcx, trait_assoc_def_id, fn_def_id) + .to_def_id() }, ), ) @@ -355,7 +358,7 @@ fn associated_type_for_impl_trait_in_trait( /// that inherits properties that we infer from the method and the associated type. fn associated_type_for_impl_trait_in_impl( tcx: TyCtxt<'_>, - trait_assoc_def_id: LocalDefId, + trait_assoc_def_id: DefId, impl_fn_def_id: LocalDefId, ) -> LocalDefId { let impl_local_def_id = tcx.local_parent(impl_fn_def_id); @@ -380,7 +383,7 @@ fn associated_type_for_impl_trait_in_impl( name: kw::Empty, kind: ty::AssocKind::Type, def_id, - trait_item_def_id: Some(trait_assoc_def_id.to_def_id()), + trait_item_def_id: Some(trait_assoc_def_id), container: ty::ImplContainer, fn_has_self_parameter: false, opt_rpitit_info: Some(ImplTraitInTraitData::Impl { fn_def_id: impl_fn_def_id.to_def_id() }), diff --git a/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs b/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs index 74f7bc603aafc..ffeabe5c2edab 100644 --- a/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs +++ b/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs @@ -2,12 +2,13 @@ #![feature(return_position_impl_trait_in_trait)] +use std::ops::Deref; + pub trait Foo { - fn bar() -> impl Sized; + fn bar() -> impl Deref; } pub struct Foreign; - impl Foo for Foreign { - fn bar() {} + fn bar() -> &'static () { &() } } diff --git a/tests/ui/impl-trait/in-trait/foreign.rs b/tests/ui/impl-trait/in-trait/foreign.rs index df77372aabdfc..f4972d948b246 100644 --- a/tests/ui/impl-trait/in-trait/foreign.rs +++ b/tests/ui/impl-trait/in-trait/foreign.rs @@ -5,7 +5,17 @@ extern crate rpitit; +use std::sync::Arc; + +// Implement an RPITIT from another crate. +struct Local; +impl rpitit::Foo for Local { + fn bar() -> Arc { Arc::new(String::new()) } +} + fn main() { - // Witness an RPITIT from another crate - let () = ::bar(); + // Witness an RPITIT from another crate. + let &() = ::bar(); + + let x: Arc = ::bar(); } From 66714658d0bb9cd5b3c10a876275f9646da2148f Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 27 Mar 2023 18:33:04 -0300 Subject: [PATCH 2/3] Properly skip RPITITs from ModChild and give a name in AssocItem --- compiler/rustc_hir/src/definitions.rs | 6 +----- compiler/rustc_metadata/src/rmeta/decoder.rs | 11 ++++++++--- .../ui/impl-trait/in-trait/doesnt-satisfy.next.stderr | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index 3c4fc9cb530a4..8ceb176491b6f 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -404,12 +404,8 @@ impl DefPathData { match *self { TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name), - // We use this name when collecting `ModChild`s. - // FIXME this could probably be removed with some refactoring to the name resolver. - ImplTraitAssocTy => Some(kw::Empty), - Impl | ForeignMod | CrateRoot | Use | GlobalAsm | ClosureExpr | Ctor | AnonConst - | ImplTrait => None, + | ImplTrait | ImplTraitAssocTy => None, } } diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 06a64f0db0e32..43e5946f31354 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1021,7 +1021,9 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } else { // Iterate over all children. for child_index in self.root.tables.children.get(self, id).unwrap().decode(self) { - yield self.get_mod_child(child_index, sess); + if self.root.tables.opt_rpitit_info.get(self, child_index).is_none() { + yield self.get_mod_child(child_index, sess); + } } if let Some(reexports) = self.root.tables.module_reexports.get(self, id) { @@ -1067,8 +1069,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } fn get_associated_item(self, id: DefIndex, sess: &'a Session) -> ty::AssocItem { - let name = self.item_name(id); - + let name = if self.root.tables.opt_rpitit_info.get(self, id).is_some() { + kw::Empty + } else { + self.item_name(id) + }; let (kind, has_self) = match self.def_kind(id) { DefKind::AssocConst => (ty::AssocKind::Const, false), DefKind::AssocFn => (ty::AssocKind::Fn, self.get_fn_has_self_parameter(id, sess)), diff --git a/tests/ui/impl-trait/in-trait/doesnt-satisfy.next.stderr b/tests/ui/impl-trait/in-trait/doesnt-satisfy.next.stderr index bbfa089ceef92..f0cd43bcf9216 100644 --- a/tests/ui/impl-trait/in-trait/doesnt-satisfy.next.stderr +++ b/tests/ui/impl-trait/in-trait/doesnt-satisfy.next.stderr @@ -10,7 +10,7 @@ note: required by a bound in `Foo::{opaque#0}` --> $DIR/doesnt-satisfy.rs:8:22 | LL | fn bar() -> impl std::fmt::Display; - | ^^^^^^^^^^^^^^^^^ required by this bound in `Foo::` + | ^^^^^^^^^^^^^^^^^ required by this bound in `Foo::{opaque#0}` error: aborting due to previous error From 2ca350c776414fb09ca97311b5e0fee929c90902 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 21 Mar 2023 16:52:15 -0300 Subject: [PATCH 3/3] Bless some extra working tests under -Zlower-impl-trait-in-trait-to-assoc-ty --- tests/ui/impl-trait/in-trait/nested-rpitit.rs | 2 ++ ...052-2.stderr => issue-103052-2.current.stderr} | 4 ++-- .../issue-103052-2.next.stderr | 15 +++++++++++++++ .../rfc-1937-termination-trait/issue-103052-2.rs | 6 +++++- 4 files changed, 24 insertions(+), 3 deletions(-) rename tests/ui/rfc-1937-termination-trait/{issue-103052-2.stderr => issue-103052-2.current.stderr} (88%) create mode 100644 tests/ui/rfc-1937-termination-trait/issue-103052-2.next.stderr diff --git a/tests/ui/impl-trait/in-trait/nested-rpitit.rs b/tests/ui/impl-trait/in-trait/nested-rpitit.rs index 65285e3a3ccaf..3602075372657 100644 --- a/tests/ui/impl-trait/in-trait/nested-rpitit.rs +++ b/tests/ui/impl-trait/in-trait/nested-rpitit.rs @@ -1,4 +1,6 @@ // check-pass +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] diff --git a/tests/ui/rfc-1937-termination-trait/issue-103052-2.stderr b/tests/ui/rfc-1937-termination-trait/issue-103052-2.current.stderr similarity index 88% rename from tests/ui/rfc-1937-termination-trait/issue-103052-2.stderr rename to tests/ui/rfc-1937-termination-trait/issue-103052-2.current.stderr index a700c72ea689f..f72b3ab0234e9 100644 --- a/tests/ui/rfc-1937-termination-trait/issue-103052-2.stderr +++ b/tests/ui/rfc-1937-termination-trait/issue-103052-2.current.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `Something: Termination` is not satisfied - --> $DIR/issue-103052-2.rs:12:22 + --> $DIR/issue-103052-2.rs:15:22 | LL | fn main() -> Something { | ^^^^^^^^^ the trait `Termination` is not implemented for `Something` | note: required by a bound in `Main::main::{opaque#0}` - --> $DIR/issue-103052-2.rs:6:27 + --> $DIR/issue-103052-2.rs:9:27 | LL | fn main() -> impl std::process::Termination; | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Main::main::{opaque#0}` diff --git a/tests/ui/rfc-1937-termination-trait/issue-103052-2.next.stderr b/tests/ui/rfc-1937-termination-trait/issue-103052-2.next.stderr new file mode 100644 index 0000000000000..8b01941b4c623 --- /dev/null +++ b/tests/ui/rfc-1937-termination-trait/issue-103052-2.next.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `Something: Termination` is not satisfied + --> $DIR/issue-103052-2.rs:15:22 + | +LL | fn main() -> Something { + | ^^^^^^^^^ the trait `Termination` is not implemented for `Something` + | +note: required by a bound in `Main::{opaque#0}` + --> $DIR/issue-103052-2.rs:9:27 + | +LL | fn main() -> impl std::process::Termination; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Main::{opaque#0}` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfc-1937-termination-trait/issue-103052-2.rs b/tests/ui/rfc-1937-termination-trait/issue-103052-2.rs index fa9182b6deeb7..ca5fa6df2a626 100644 --- a/tests/ui/rfc-1937-termination-trait/issue-103052-2.rs +++ b/tests/ui/rfc-1937-termination-trait/issue-103052-2.rs @@ -1,3 +1,6 @@ +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next + #![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] @@ -9,7 +12,8 @@ mod child { struct Something; impl Main for () { - fn main() -> Something { //~ ERROR the trait bound `Something: Termination` is not satisfied + fn main() -> Something { + //~^ ERROR the trait bound `Something: Termination` is not satisfied Something } }