Skip to content

Commit 76802e3

Browse files
Error message for ambiguous RTN from super bounds
1 parent fef2f5b commit 76802e3

File tree

6 files changed

+84
-3
lines changed

6 files changed

+84
-3
lines changed

compiler/rustc_hir_analysis/messages.ftl

+4
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,10 @@ hir_analysis_return_type_notation_equality_bound =
194194
hir_analysis_return_type_notation_missing_method =
195195
cannot find associated function `{$assoc_name}` for `{$ty_name}`
196196
197+
hir_analysis_return_type_notation_conflicting_bound =
198+
ambiguous associated function `{$assoc_name}` for `{$ty_name}`
199+
.note = `{$assoc_name}` is declared in two supertraits: `{$first_bound}` and `{$second_bound}`
200+
197201
hir_analysis_placeholder_not_allowed_item_signatures = the placeholder `_` is not allowed within types on item signatures for {$kind}
198202
.label = not allowed in type signatures
199203

compiler/rustc_hir_analysis/src/astconv/mod.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -2083,8 +2083,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
20832083
}
20842084
};
20852085

2086-
if let Some(_conflicting_candidate) = matching_candidates.next() {
2087-
todo!()
2086+
if let Some(conflicting_candidate) = matching_candidates.next() {
2087+
return Err(self.tcx().sess.emit_err(
2088+
crate::errors::ReturnTypeNotationConflictingBound {
2089+
span,
2090+
ty_name: ty_name.to_string(),
2091+
assoc_name: assoc_name.name,
2092+
first_bound: candidate.print_only_trait_path(),
2093+
second_bound: conflicting_candidate.print_only_trait_path(),
2094+
},
2095+
));
20882096
}
20892097

20902098
Ok(candidate)

compiler/rustc_hir_analysis/src/errors.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_errors::{
66
MultiSpan,
77
};
88
use rustc_macros::{Diagnostic, Subdiagnostic};
9-
use rustc_middle::ty::Ty;
9+
use rustc_middle::ty::{self, print::TraitRefPrintOnlyTraitPath, Ty};
1010
use rustc_span::{symbol::Ident, Span, Symbol};
1111

1212
#[derive(Diagnostic)]
@@ -516,6 +516,18 @@ pub(crate) struct ReturnTypeNotationMissingMethod {
516516
pub assoc_name: Symbol,
517517
}
518518

519+
#[derive(Diagnostic)]
520+
#[diag(hir_analysis_return_type_notation_conflicting_bound)]
521+
#[note]
522+
pub(crate) struct ReturnTypeNotationConflictingBound<'tcx> {
523+
#[primary_span]
524+
pub span: Span,
525+
pub ty_name: String,
526+
pub assoc_name: Symbol,
527+
pub first_bound: ty::Binder<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
528+
pub second_bound: ty::Binder<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
529+
}
530+
519531
#[derive(Diagnostic)]
520532
#[diag(hir_analysis_placeholder_not_allowed_item_signatures, code = "E0121")]
521533
pub(crate) struct PlaceholderNotAllowedItemSignatures {

compiler/rustc_middle/src/ty/print/pretty.rs

+6
Original file line numberDiff line numberDiff line change
@@ -2633,6 +2633,12 @@ macro_rules! define_print_and_forward_display {
26332633
#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift)]
26342634
pub struct TraitRefPrintOnlyTraitPath<'tcx>(ty::TraitRef<'tcx>);
26352635

2636+
impl<'tcx> rustc_errors::IntoDiagnosticArg for TraitRefPrintOnlyTraitPath<'tcx> {
2637+
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
2638+
self.to_string().into_diagnostic_arg()
2639+
}
2640+
}
2641+
26362642
impl<'tcx> fmt::Debug for TraitRefPrintOnlyTraitPath<'tcx> {
26372643
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26382644
fmt::Display::fmt(self, f)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// edition:2021
2+
3+
#![feature(async_fn_in_trait, return_type_notation)]
4+
//~^ WARN the feature `return_type_notation` is incomplete
5+
6+
trait Super1<'a> {
7+
async fn test();
8+
}
9+
impl Super1<'_> for () {
10+
async fn test() {}
11+
}
12+
13+
trait Super2 {
14+
async fn test();
15+
}
16+
impl Super2 for () {
17+
async fn test() {}
18+
}
19+
20+
trait Foo: for<'a> Super1<'a> + Super2 {}
21+
impl Foo for () {}
22+
23+
fn test<T>()
24+
where
25+
T: Foo<test(): Send>,
26+
//~^ ERROR ambiguous associated function `test` for `Foo`
27+
{
28+
}
29+
30+
fn main() {
31+
test::<()>();
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/super-method-bound-ambig.rs:3:31
3+
|
4+
LL | #![feature(async_fn_in_trait, return_type_notation)]
5+
| ^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
error: ambiguous associated function `test` for `Foo`
11+
--> $DIR/super-method-bound-ambig.rs:25:12
12+
|
13+
LL | T: Foo<test(): Send>,
14+
| ^^^^^^^^^^^^
15+
|
16+
= note: `test` is declared in two supertraits: `Super2` and `Super1<'a>`
17+
18+
error: aborting due to previous error; 1 warning emitted
19+

0 commit comments

Comments
 (0)