about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-05-03 21:09:50 +0000
committerMichael Goulet <michael@errs.io>2023-05-03 21:09:50 +0000
commit76802e31a131d2ac5933b8283a292735b6ab8366 (patch)
treec26232fab7f3123602b04e9dd62454f8ec2aee9c
parentfef2f5b815fd9cf48895063e35054e34c31562d9 (diff)
downloadrust-76802e31a131d2ac5933b8283a292735b6ab8366.tar.gz
rust-76802e31a131d2ac5933b8283a292735b6ab8366.zip
Error message for ambiguous RTN from super bounds
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl4
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs12
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs14
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs6
-rw-r--r--tests/ui/async-await/return-type-notation/super-method-bound-ambig.rs32
-rw-r--r--tests/ui/async-await/return-type-notation/super-method-bound-ambig.stderr19
6 files changed, 84 insertions, 3 deletions
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 703f168b766..2035b256daa 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -194,6 +194,10 @@ hir_analysis_return_type_notation_equality_bound =
 hir_analysis_return_type_notation_missing_method =
     cannot find associated function `{$assoc_name}` for `{$ty_name}`
 
+hir_analysis_return_type_notation_conflicting_bound =
+    ambiguous associated function `{$assoc_name}` for `{$ty_name}`
+    .note = `{$assoc_name}` is declared in two supertraits: `{$first_bound}` and `{$second_bound}`
+
 hir_analysis_placeholder_not_allowed_item_signatures = the placeholder `_` is not allowed within types on item signatures for {$kind}
     .label = not allowed in type signatures
 
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 7880a248cb0..9abb71d8b1a 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -2083,8 +2083,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             }
         };
 
-        if let Some(_conflicting_candidate) = matching_candidates.next() {
-            todo!()
+        if let Some(conflicting_candidate) = matching_candidates.next() {
+            return Err(self.tcx().sess.emit_err(
+                crate::errors::ReturnTypeNotationConflictingBound {
+                    span,
+                    ty_name: ty_name.to_string(),
+                    assoc_name: assoc_name.name,
+                    first_bound: candidate.print_only_trait_path(),
+                    second_bound: conflicting_candidate.print_only_trait_path(),
+                },
+            ));
         }
 
         Ok(candidate)
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 48330a94255..32c66b16fb9 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -6,7 +6,7 @@ use rustc_errors::{
     MultiSpan,
 };
 use rustc_macros::{Diagnostic, Subdiagnostic};
-use rustc_middle::ty::Ty;
+use rustc_middle::ty::{self, print::TraitRefPrintOnlyTraitPath, Ty};
 use rustc_span::{symbol::Ident, Span, Symbol};
 
 #[derive(Diagnostic)]
@@ -517,6 +517,18 @@ pub(crate) struct ReturnTypeNotationMissingMethod {
 }
 
 #[derive(Diagnostic)]
+#[diag(hir_analysis_return_type_notation_conflicting_bound)]
+#[note]
+pub(crate) struct ReturnTypeNotationConflictingBound<'tcx> {
+    #[primary_span]
+    pub span: Span,
+    pub ty_name: String,
+    pub assoc_name: Symbol,
+    pub first_bound: ty::Binder<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
+    pub second_bound: ty::Binder<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
+}
+
+#[derive(Diagnostic)]
 #[diag(hir_analysis_placeholder_not_allowed_item_signatures, code = "E0121")]
 pub(crate) struct PlaceholderNotAllowedItemSignatures {
     #[primary_span]
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 2aced27f7bb..32403d9a5e6 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -2633,6 +2633,12 @@ macro_rules! define_print_and_forward_display {
 #[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift)]
 pub struct TraitRefPrintOnlyTraitPath<'tcx>(ty::TraitRef<'tcx>);
 
+impl<'tcx> rustc_errors::IntoDiagnosticArg for TraitRefPrintOnlyTraitPath<'tcx> {
+    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+        self.to_string().into_diagnostic_arg()
+    }
+}
+
 impl<'tcx> fmt::Debug for TraitRefPrintOnlyTraitPath<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt::Display::fmt(self, f)
diff --git a/tests/ui/async-await/return-type-notation/super-method-bound-ambig.rs b/tests/ui/async-await/return-type-notation/super-method-bound-ambig.rs
new file mode 100644
index 00000000000..028e526b5f5
--- /dev/null
+++ b/tests/ui/async-await/return-type-notation/super-method-bound-ambig.rs
@@ -0,0 +1,32 @@
+// edition:2021
+
+#![feature(async_fn_in_trait, return_type_notation)]
+//~^ WARN the feature `return_type_notation` is incomplete
+
+trait Super1<'a> {
+    async fn test();
+}
+impl Super1<'_> for () {
+    async fn test() {}
+}
+
+trait Super2 {
+    async fn test();
+}
+impl Super2 for () {
+    async fn test() {}
+}
+
+trait Foo: for<'a> Super1<'a> + Super2 {}
+impl Foo for () {}
+
+fn test<T>()
+where
+    T: Foo<test(): Send>,
+    //~^ ERROR ambiguous associated function `test` for `Foo`
+{
+}
+
+fn main() {
+    test::<()>();
+}
diff --git a/tests/ui/async-await/return-type-notation/super-method-bound-ambig.stderr b/tests/ui/async-await/return-type-notation/super-method-bound-ambig.stderr
new file mode 100644
index 00000000000..5bc8dbde4bc
--- /dev/null
+++ b/tests/ui/async-await/return-type-notation/super-method-bound-ambig.stderr
@@ -0,0 +1,19 @@
+warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/super-method-bound-ambig.rs:3:31
+   |
+LL | #![feature(async_fn_in_trait, return_type_notation)]
+   |                               ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: ambiguous associated function `test` for `Foo`
+  --> $DIR/super-method-bound-ambig.rs:25:12
+   |
+LL |     T: Foo<test(): Send>,
+   |            ^^^^^^^^^^^^
+   |
+   = note: `test` is declared in two supertraits: `Super2` and `Super1<'a>`
+
+error: aborting due to previous error; 1 warning emitted
+