about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir/src/definitions.rs6
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs11
-rw-r--r--compiler/rustc_ty_utils/src/assoc.rs35
-rw-r--r--tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs7
-rw-r--r--tests/ui/impl-trait/in-trait/doesnt-satisfy.next.stderr2
-rw-r--r--tests/ui/impl-trait/in-trait/foreign.rs14
-rw-r--r--tests/ui/impl-trait/in-trait/nested-rpitit.rs2
-rw-r--r--tests/ui/rfc-1937-termination-trait/issue-103052-2.current.stderr (renamed from tests/ui/rfc-1937-termination-trait/issue-103052-2.stderr)4
-rw-r--r--tests/ui/rfc-1937-termination-trait/issue-103052-2.next.stderr15
-rw-r--r--tests/ui/rfc-1937-termination-trait/issue-103052-2.rs6
10 files changed, 69 insertions, 33 deletions
diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs
index 3c4fc9cb530..8ceb176491b 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 06a64f0db0e..43e5946f313 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/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs
index bf0bc202852..de1e1a527d5 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<LocalDefId>,
+            struct RPITVisitor<'tcx> {
+                rpits: FxIndexSet<LocalDefId>,
+                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 74f7bc603aa..ffeabe5c2ed 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<Target = impl Sized>;
 }
 
 pub struct Foreign;
-
 impl Foo for Foreign {
-    fn bar() {}
+    fn bar() -> &'static () { &() }
 }
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 bbfa089ceef..f0cd43bcf92 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
 
diff --git a/tests/ui/impl-trait/in-trait/foreign.rs b/tests/ui/impl-trait/in-trait/foreign.rs
index df77372aabd..f4972d948b2 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<String> { Arc::new(String::new()) }
+}
+
 fn main() {
-    // Witness an RPITIT from another crate
-    let () = <rpitit::Foreign as rpitit::Foo>::bar();
+    // Witness an RPITIT from another crate.
+    let &() = <rpitit::Foreign as rpitit::Foo>::bar();
+
+    let x: Arc<String> = <Local as rpitit::Foo>::bar();
 }
diff --git a/tests/ui/impl-trait/in-trait/nested-rpitit.rs b/tests/ui/impl-trait/in-trait/nested-rpitit.rs
index 65285e3a3cc..36020753726 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
index a700c72ea68..f72b3ab0234 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 00000000000..8b01941b4c6
--- /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 fa9182b6dee..ca5fa6df2a6 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
         }
     }