about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-07-28 19:51:15 +0200
committerGitHub <noreply@github.com>2023-07-28 19:51:15 +0200
commit06eebbe6e72f30a2db1c5cdb220daf66f54fb06f (patch)
tree2394539e04eb126e0161526077bf299e3ac7d59c
parent3aa8da1474daedd4c063403ecdf9a808354b4486 (diff)
parentea2f8b346b09c474d620ada38e4a0cb9f75e0b5f (diff)
downloadrust-06eebbe6e72f30a2db1c5cdb220daf66f54fb06f.tar.gz
rust-06eebbe6e72f30a2db1c5cdb220daf66f54fb06f.zip
Rollup merge of #114146 - compiler-errors:dont-report-rpitit-name, r=spastorino
Skip reporting item name when checking RPITIT GAT's associated type bounds hold

Doesn't really make sense to label an item that has a name that users can't really mention. Fixes #114145. Also fixes #113794.

r? `@spastorino`
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note.rs18
-rw-r--r--compiler/rustc_ty_utils/src/assoc.rs12
-rw-r--r--tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs11
-rw-r--r--tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr33
-rw-r--r--tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.rs25
-rw-r--r--tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.stderr30
6 files changed, 121 insertions, 8 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs
index 7144084c78e..8cd1b82130b 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs
@@ -243,12 +243,18 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             }
             infer::CheckAssociatedTypeBounds { impl_item_def_id, trait_item_def_id, parent } => {
                 let mut err = self.report_concrete_failure(*parent, sub, sup);
-                let trait_item_span = self.tcx.def_span(trait_item_def_id);
-                let item_name = self.tcx.item_name(impl_item_def_id.to_def_id());
-                err.span_label(
-                    trait_item_span,
-                    format!("definition of `{}` from trait", item_name),
-                );
+
+                // Don't mention the item name if it's an RPITIT, since that'll just confuse
+                // folks.
+                if !self.tcx.is_impl_trait_in_trait(impl_item_def_id.to_def_id()) {
+                    let trait_item_span = self.tcx.def_span(trait_item_def_id);
+                    let item_name = self.tcx.item_name(impl_item_def_id.to_def_id());
+                    err.span_label(
+                        trait_item_span,
+                        format!("definition of `{}` from trait", item_name),
+                    );
+                }
+
                 self.suggest_copy_trait_method_bounds(
                     trait_item_def_id,
                     impl_item_def_id,
diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs
index 4a544232174..780f7ea426f 100644
--- a/compiler/rustc_ty_utils/src/assoc.rs
+++ b/compiler/rustc_ty_utils/src/assoc.rs
@@ -346,8 +346,16 @@ fn associated_type_for_impl_trait_in_impl(
 ) -> LocalDefId {
     let impl_local_def_id = tcx.local_parent(impl_fn_def_id);
 
-    // FIXME fix the span, we probably want the def_id of the return type of the function
-    let span = tcx.def_span(impl_fn_def_id);
+    let decl = tcx
+        .hir()
+        .find_by_def_id(impl_fn_def_id)
+        .expect("expected item")
+        .fn_decl()
+        .expect("expected decl");
+    let span = match decl.output {
+        hir::FnRetTy::DefaultReturn(_) => tcx.def_span(impl_fn_def_id),
+        hir::FnRetTy::Return(ty) => ty.span,
+    };
     let impl_assoc_ty = tcx.at(span).create_def(impl_local_def_id, DefPathData::ImplTraitAssocTy);
 
     let local_def_id = impl_assoc_ty.def_id();
diff --git a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs
new file mode 100644
index 00000000000..3a93dfee57f
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs
@@ -0,0 +1,11 @@
+// issue: 114146
+
+#![feature(return_position_impl_trait_in_trait)]
+
+trait Foo {
+    fn bar<'other: 'a>() -> impl Sized + 'a {}
+    //~^ ERROR use of undeclared lifetime name `'a`
+    //~| ERROR use of undeclared lifetime name `'a`
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr
new file mode 100644
index 00000000000..3a1f8f90837
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr
@@ -0,0 +1,33 @@
+error[E0261]: use of undeclared lifetime name `'a`
+  --> $DIR/bad-item-bound-within-rpitit-2.rs:6:20
+   |
+LL |     fn bar<'other: 'a>() -> impl Sized + 'a {}
+   |                    ^^ undeclared lifetime
+   |
+help: consider introducing lifetime `'a` here
+   |
+LL |     fn bar<'a, 'other: 'a>() -> impl Sized + 'a {}
+   |            +++
+help: consider introducing lifetime `'a` here
+   |
+LL | trait Foo<'a> {
+   |          ++++
+
+error[E0261]: use of undeclared lifetime name `'a`
+  --> $DIR/bad-item-bound-within-rpitit-2.rs:6:42
+   |
+LL |     fn bar<'other: 'a>() -> impl Sized + 'a {}
+   |                                          ^^ undeclared lifetime
+   |
+help: consider introducing lifetime `'a` here
+   |
+LL |     fn bar<'a, 'other: 'a>() -> impl Sized + 'a {}
+   |            +++
+help: consider introducing lifetime `'a` here
+   |
+LL | trait Foo<'a> {
+   |          ++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0261`.
diff --git a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.rs b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.rs
new file mode 100644
index 00000000000..8b97336fe0c
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.rs
@@ -0,0 +1,25 @@
+// issue: 114145
+
+#![feature(return_position_impl_trait_in_trait)]
+
+trait Iterable {
+    type Item<'a>
+    where
+        Self: 'a;
+
+    fn iter(&self) -> impl '_ + Iterator<Item = Self::Item<'_>>;
+}
+
+impl<'a, I: 'a + Iterable> Iterable for &'a I {
+    type Item<'b> = I::Item<'a>
+    where
+        'b: 'a;
+    //~^ ERROR impl has stricter requirements than trait
+
+    fn iter(&self) -> impl 'a + Iterator<Item = I::Item<'a>> {
+        //~^ ERROR the type `&'a I` does not fulfill the required lifetime
+        (*self).iter()
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.stderr b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.stderr
new file mode 100644
index 00000000000..54a08c5b516
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.stderr
@@ -0,0 +1,30 @@
+error[E0276]: impl has stricter requirements than trait
+  --> $DIR/bad-item-bound-within-rpitit.rs:16:13
+   |
+LL |     type Item<'a>
+   |     ------------- definition of `Item` from trait
+...
+LL |         'b: 'a;
+   |             ^^ impl has extra requirement `'b: 'a`
+   |
+help: copy the `where` clause predicates from the trait
+   |
+LL |     where Self: 'b;
+   |     ~~~~~~~~~~~~~~
+
+error[E0477]: the type `&'a I` does not fulfill the required lifetime
+  --> $DIR/bad-item-bound-within-rpitit.rs:19:23
+   |
+LL |     fn iter(&self) -> impl 'a + Iterator<Item = I::Item<'a>> {
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: type must outlive the anonymous lifetime as defined here
+  --> $DIR/bad-item-bound-within-rpitit.rs:10:28
+   |
+LL |     fn iter(&self) -> impl '_ + Iterator<Item = Self::Item<'_>>;
+   |                            ^^
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0276, E0477.
+For more information about an error, try `rustc --explain E0276`.