about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2022-09-22 19:36:26 +0000
committerMichael Goulet <michael@errs.io>2022-09-22 19:49:18 +0000
commit79c665b2a321f7d7a8826139171092baa42b0b56 (patch)
tree6eb4bb7d8fb712f05c65432ff24ba781894539b2
parent89e4e1f1b32e2a88cf696337f77e10273142c1a0 (diff)
downloadrust-79c665b2a321f7d7a8826139171092baa42b0b56.tar.gz
rust-79c665b2a321f7d7a8826139171092baa42b0b56.zip
Calculate ProjectionTy::trait_def_id correctly
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs10
-rw-r--r--src/test/ui/impl-trait/in-trait/issue-102140.rs30
-rw-r--r--src/test/ui/impl-trait/in-trait/issue-102140.stderr29
3 files changed, 66 insertions, 3 deletions
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index d2f73f274f8..37a1f2b550c 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -1133,9 +1133,13 @@ pub struct ProjectionTy<'tcx> {
 
 impl<'tcx> ProjectionTy<'tcx> {
     pub fn trait_def_id(&self, tcx: TyCtxt<'tcx>) -> DefId {
-        let parent = tcx.parent(self.item_def_id);
-        assert_eq!(tcx.def_kind(parent), DefKind::Trait);
-        parent
+        match tcx.def_kind(self.item_def_id) {
+            DefKind::AssocTy | DefKind::AssocConst => tcx.parent(self.item_def_id),
+            DefKind::ImplTraitPlaceholder => {
+                tcx.parent(tcx.impl_trait_in_trait_parent(self.item_def_id))
+            }
+            kind => bug!("unexpected DefKind in ProjectionTy: {kind:?}"),
+        }
     }
 
     /// Extracts the underlying trait reference and own substs from this projection.
diff --git a/src/test/ui/impl-trait/in-trait/issue-102140.rs b/src/test/ui/impl-trait/in-trait/issue-102140.rs
new file mode 100644
index 00000000000..be1e012acb1
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/issue-102140.rs
@@ -0,0 +1,30 @@
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+trait Marker {}
+impl Marker for u32 {}
+
+trait MyTrait {
+    fn foo(&self) -> impl Marker
+    where
+        Self: Sized;
+}
+
+struct Outer;
+
+impl MyTrait for Outer {
+    fn foo(&self) -> impl Marker {
+        42
+    }
+}
+
+impl dyn MyTrait {
+    fn other(&self) -> impl Marker {
+        MyTrait::foo(&self)
+        //~^ ERROR the trait bound `&dyn MyTrait: MyTrait` is not satisfied
+        //~| ERROR the trait bound `&dyn MyTrait: MyTrait` is not satisfied
+        //~| ERROR the trait bound `&dyn MyTrait: MyTrait` is not satisfied
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/in-trait/issue-102140.stderr b/src/test/ui/impl-trait/in-trait/issue-102140.stderr
new file mode 100644
index 00000000000..08602185f50
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/issue-102140.stderr
@@ -0,0 +1,29 @@
+error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
+  --> $DIR/issue-102140.rs:23:22
+   |
+LL |         MyTrait::foo(&self)
+   |         ------------ -^^^^
+   |         |            |
+   |         |            the trait `MyTrait` is not implemented for `&dyn MyTrait`
+   |         |            help: consider removing the leading `&`-reference
+   |         required by a bound introduced by this call
+
+error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
+  --> $DIR/issue-102140.rs:23:9
+   |
+LL |         MyTrait::foo(&self)
+   |         ^^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
+   |
+   = help: the trait `MyTrait` is implemented for `Outer`
+
+error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
+  --> $DIR/issue-102140.rs:23:9
+   |
+LL |         MyTrait::foo(&self)
+   |         ^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
+   |
+   = help: the trait `MyTrait` is implemented for `Outer`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0277`.