Skip to content

Commit c2d4667

Browse files
Add missing diagnostics and flesh out tests
1 parent ae3d610 commit c2d4667

22 files changed

+502
-14
lines changed

compiler/rustc_ast_lowering/src/lib.rs

+5
Original file line numberDiff line numberDiff line change
@@ -494,9 +494,14 @@ enum AllowReturnTypeNotation {
494494
}
495495

496496
enum GenericArgsMode {
497+
// Allow paren sugar, don't allow RTN.
497498
ParenSugar,
499+
// Allow RTN, don't allow paren sugar.
498500
ReturnTypeNotation,
501+
// Error if parenthesized generics or RTN are encountered.
499502
Err,
503+
// Silence errors when lowering generics. Only used with `Res::Err`.
504+
Silence,
500505
}
501506

502507
impl<'a, 'hir> LoweringContext<'a, 'hir> {

compiler/rustc_ast_lowering/src/path.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
111111
}
112112
}
113113
// Avoid duplicated errors.
114-
Res::Err => GenericArgsMode::ParenSugar,
114+
Res::Err => GenericArgsMode::Silence,
115115
// An error
116116
_ => GenericArgsMode::Err,
117117
};
@@ -288,11 +288,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
288288
false,
289289
)
290290
}
291-
GenericArgsMode::ParenSugar => self.lower_parenthesized_parameter_data(
292-
data,
293-
itctx,
294-
bound_modifier_allowed_features,
295-
),
291+
GenericArgsMode::ParenSugar | GenericArgsMode::Silence => self
292+
.lower_parenthesized_parameter_data(
293+
data,
294+
itctx,
295+
bound_modifier_allowed_features,
296+
),
296297
GenericArgsMode::Err => {
297298
// Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
298299
let sub = if !data.inputs.is_empty() {
@@ -330,7 +331,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
330331
},
331332
GenericArgs::ParenthesizedElided(span) => {
332333
match generic_args_mode {
333-
GenericArgsMode::ReturnTypeNotation => {
334+
GenericArgsMode::ReturnTypeNotation | GenericArgsMode::Silence => {
334335
// Ok
335336
}
336337
GenericArgsMode::ParenSugar | GenericArgsMode::Err => {

compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -1903,10 +1903,11 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
19031903
)
19041904
}) =>
19051905
{
1906-
let Res::Def(DefKind::AssocFn, item_def_id) = path.res else {
1907-
bug!();
1908-
};
1909-
(vec![], item_def_id, item_segment)
1906+
match path.res {
1907+
Res::Err => return,
1908+
Res::Def(DefKind::AssocFn, item_def_id) => (vec![], item_def_id, item_segment),
1909+
_ => bug!("only expected method resolution for fully qualified RTN"),
1910+
}
19101911
}
19111912

19121913
// If we have a type-dependent path, then we do need to do some lookup.

compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs

+24-3
Original file line numberDiff line numberDiff line change
@@ -486,8 +486,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
486486
let _ =
487487
self.prohibit_generic_args(mod_segments.iter(), GenericsArgsErrExtend::None);
488488

489-
let Res::Def(DefKind::AssocFn, item_def_id) = path.res else {
490-
bug!("expected RTN to resolve to associated fn");
489+
let item_def_id = match path.res {
490+
Res::Def(DefKind::AssocFn, item_def_id) => item_def_id,
491+
Res::Err => {
492+
return Ty::new_error_with_message(
493+
tcx,
494+
hir_ty.span,
495+
"failed to resolve RTN",
496+
);
497+
}
498+
_ => bug!("only expected method resolution for fully qualified RTN"),
491499
};
492500
let trait_def_id = tcx.parent(item_def_id);
493501

@@ -604,7 +612,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
604612
assoc_ident,
605613
span,
606614
)?,
607-
_ => todo!(),
615+
_ => {
616+
if let Err(reported) = qself_ty.error_reported() {
617+
return Err(reported);
618+
} else {
619+
// FIXME(return_type_notation): Provide some structured suggestion here.
620+
let err = struct_span_code_err!(
621+
self.dcx(),
622+
span,
623+
E0223,
624+
"ambiguous associated function"
625+
);
626+
return Err(err.emit());
627+
}
628+
}
608629
};
609630

610631
// Don't let `T::method` resolve to some `for<'a> <T as Tr<'a>>::method`,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#![feature(return_type_notation)]
2+
//~^ WARN the feature `return_type_notation` is incomplete
3+
4+
trait A {
5+
fn method() -> impl Sized;
6+
}
7+
trait B {
8+
fn method() -> impl Sized;
9+
}
10+
11+
fn ambiguous<T: A + B>()
12+
where
13+
T::method(..): Send,
14+
//~^ ERROR ambiguous associated function `method` in bounds of `T`
15+
{
16+
}
17+
18+
trait Sub: A + B {}
19+
20+
fn ambiguous_via_supertrait<T: Sub>()
21+
where
22+
T::method(..): Send,
23+
//~^ ERROR ambiguous associated function `method` in bounds of `T`
24+
{
25+
}
26+
27+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/path-ambiguous.rs:1:12
3+
|
4+
LL | #![feature(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[E0221]: ambiguous associated function `method` in bounds of `T`
11+
--> $DIR/path-ambiguous.rs:13:5
12+
|
13+
LL | fn method() -> impl Sized;
14+
| -------------------------- ambiguous `method` from `A`
15+
...
16+
LL | fn method() -> impl Sized;
17+
| -------------------------- ambiguous `method` from `B`
18+
...
19+
LL | T::method(..): Send,
20+
| ^^^^^^^^^^^^^ ambiguous associated function `method`
21+
|
22+
help: use fully-qualified syntax to disambiguate
23+
|
24+
LL | <T as B>::method(..): Send,
25+
| ~~~~~~~~~~
26+
help: use fully-qualified syntax to disambiguate
27+
|
28+
LL | <T as A>::method(..): Send,
29+
| ~~~~~~~~~~
30+
31+
error[E0221]: ambiguous associated function `method` in bounds of `T`
32+
--> $DIR/path-ambiguous.rs:22:5
33+
|
34+
LL | fn method() -> impl Sized;
35+
| -------------------------- ambiguous `method` from `A`
36+
...
37+
LL | fn method() -> impl Sized;
38+
| -------------------------- ambiguous `method` from `B`
39+
...
40+
LL | T::method(..): Send,
41+
| ^^^^^^^^^^^^^ ambiguous associated function `method`
42+
|
43+
help: use fully-qualified syntax to disambiguate
44+
|
45+
LL | <T as B>::method(..): Send,
46+
| ~~~~~~~~~~
47+
help: use fully-qualified syntax to disambiguate
48+
|
49+
LL | <T as A>::method(..): Send,
50+
| ~~~~~~~~~~
51+
52+
error: aborting due to 2 previous errors; 1 warning emitted
53+
54+
For more information about this error, try `rustc --explain E0221`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#![feature(return_type_notation)]
2+
//~^ WARN the feature `return_type_notation` is incomplete
3+
4+
trait A<'a> {
5+
fn method() -> impl Sized;
6+
}
7+
trait B: for<'a> A<'a> {}
8+
9+
fn higher_ranked<T>()
10+
where
11+
T: for<'a> A<'a>,
12+
T::method(..): Send,
13+
//~^ ERROR cannot use the associated function of a trait with uninferred generic parameters
14+
{
15+
}
16+
17+
fn higher_ranked_via_supertrait<T>()
18+
where
19+
T: B,
20+
T::method(..): Send,
21+
//~^ ERROR cannot use the associated function of a trait with uninferred generic parameters
22+
{
23+
}
24+
25+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/path-higher-ranked.rs:1:12
3+
|
4+
LL | #![feature(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[E0212]: cannot use the associated function of a trait with uninferred generic parameters
11+
--> $DIR/path-higher-ranked.rs:12:5
12+
|
13+
LL | T::method(..): Send,
14+
| ^^^^^^^^^^^^^
15+
|
16+
help: use a fully qualified path with inferred lifetimes
17+
|
18+
LL | <T as A<'_>>::method(..): Send,
19+
| ~~~~~~~~~~~~~~
20+
21+
error[E0212]: cannot use the associated function of a trait with uninferred generic parameters
22+
--> $DIR/path-higher-ranked.rs:20:5
23+
|
24+
LL | T::method(..): Send,
25+
| ^^^^^^^^^^^^^
26+
|
27+
help: use a fully qualified path with inferred lifetimes
28+
|
29+
LL | <T as A<'_>>::method(..): Send,
30+
| ~~~~~~~~~~~~~~
31+
32+
error: aborting due to 2 previous errors; 1 warning emitted
33+
34+
For more information about this error, try `rustc --explain E0212`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#![feature(return_type_notation)]
2+
//~^ WARN the feature `return_type_notation` is incomplete
3+
4+
trait A {
5+
#[allow(non_camel_case_types)]
6+
type bad;
7+
}
8+
9+
fn fully_qualified<T: A>()
10+
where
11+
<T as A>::method(..): Send,
12+
//~^ ERROR cannot find method or associated constant `method` in trait `A`
13+
<T as A>::bad(..): Send,
14+
//~^ ERROR expected method or associated constant, found associated type `A::bad`
15+
{
16+
}
17+
18+
fn type_dependent<T: A>()
19+
where
20+
T::method(..): Send,
21+
//~^ associated function `method` not found for `T`
22+
{
23+
}
24+
25+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
error[E0576]: cannot find method or associated constant `method` in trait `A`
2+
--> $DIR/path-missing.rs:11:15
3+
|
4+
LL | <T as A>::method(..): Send,
5+
| ^^^^^^ not found in `A`
6+
7+
error[E0575]: expected method or associated constant, found associated type `A::bad`
8+
--> $DIR/path-missing.rs:13:5
9+
|
10+
LL | <T as A>::bad(..): Send,
11+
| ^^^^^^^^^^^^^^^^^
12+
|
13+
= note: can't use a type alias as a constructor
14+
15+
warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
16+
--> $DIR/path-missing.rs:1:12
17+
|
18+
LL | #![feature(return_type_notation)]
19+
| ^^^^^^^^^^^^^^^^^^^^
20+
|
21+
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
22+
= note: `#[warn(incomplete_features)]` on by default
23+
24+
error[E0220]: associated function `method` not found for `T`
25+
--> $DIR/path-missing.rs:20:8
26+
|
27+
LL | T::method(..): Send,
28+
| ^^^^^^ associated function `method` not found
29+
30+
error: aborting due to 3 previous errors; 1 warning emitted
31+
32+
Some errors have detailed explanations: E0220, E0575, E0576.
33+
For more information about an error, try `rustc --explain E0220`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![feature(return_type_notation)]
2+
//~^ WARN the feature `return_type_notation` is incomplete
3+
4+
trait Trait {
5+
fn method() -> impl Sized;
6+
}
7+
8+
fn test()
9+
where
10+
Trait::method(..): Send,
11+
//~^ ERROR ambiguous associated type
12+
{
13+
}
14+
15+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/path-no-qself.rs:1:12
3+
|
4+
LL | #![feature(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[E0223]: ambiguous associated type
11+
--> $DIR/path-no-qself.rs:10:5
12+
|
13+
LL | Trait::method(..): Send,
14+
| ^^^^^^^^^^^^^^^^^
15+
|
16+
help: if there were a type named `Example` that implemented `Trait`, you could use the fully-qualified path
17+
|
18+
LL | <Example as Trait>::method: Send,
19+
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
20+
21+
error: aborting due to 1 previous error; 1 warning emitted
22+
23+
For more information about this error, try `rustc --explain E0223`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#![feature(return_type_notation)]
2+
//~^ WARN the feature `return_type_notation` is incomplete
3+
4+
trait Trait {
5+
fn method() -> impl Sized;
6+
}
7+
8+
struct Adt;
9+
10+
fn non_param_qself()
11+
where
12+
<()>::method(..): Send,
13+
//~^ ERROR ambiguous associated function
14+
i32::method(..): Send,
15+
//~^ ERROR ambiguous associated function
16+
Adt::method(..): Send,
17+
//~^ ERROR ambiguous associated function
18+
{
19+
}
20+
21+
fn main() {}

0 commit comments

Comments
 (0)