Suggest correct signature on missing fn returning RPITIT/AFIT
This commit is contained in:
parent
2ca8d358e5
commit
dbee24d949
4 changed files with 88 additions and 2 deletions
|
@ -403,7 +403,32 @@ fn fn_sig_suggestion<'tcx>(
|
||||||
.flatten()
|
.flatten()
|
||||||
.collect::<Vec<String>>()
|
.collect::<Vec<String>>()
|
||||||
.join(", ");
|
.join(", ");
|
||||||
let output = sig.output();
|
let mut output = sig.output();
|
||||||
|
|
||||||
|
let asyncness = if tcx.asyncness(assoc.def_id).is_async() {
|
||||||
|
output = if let ty::Alias(_, alias_ty) = *output.kind() {
|
||||||
|
tcx.explicit_item_bounds(alias_ty.def_id)
|
||||||
|
.subst_iter_copied(tcx, alias_ty.substs)
|
||||||
|
.find_map(|(bound, _)| {
|
||||||
|
bound.to_opt_poly_projection_pred()?.no_bound_vars()?.term.ty()
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
span_bug!(
|
||||||
|
ident.span,
|
||||||
|
"expected async fn to have `impl Future` output, but it returns {output}"
|
||||||
|
)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
span_bug!(
|
||||||
|
ident.span,
|
||||||
|
"expected async fn to have `impl Future` output, but it returns {output}"
|
||||||
|
)
|
||||||
|
};
|
||||||
|
"async "
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
};
|
||||||
|
|
||||||
let output = if !output.is_unit() { format!(" -> {output}") } else { String::new() };
|
let output = if !output.is_unit() { format!(" -> {output}") } else { String::new() };
|
||||||
|
|
||||||
let unsafety = sig.unsafety.prefix_str();
|
let unsafety = sig.unsafety.prefix_str();
|
||||||
|
@ -414,7 +439,9 @@ fn fn_sig_suggestion<'tcx>(
|
||||||
// lifetimes between the `impl` and the `trait`, but this should be good enough to
|
// lifetimes between the `impl` and the `trait`, but this should be good enough to
|
||||||
// fill in a significant portion of the missing code, and other subsequent
|
// fill in a significant portion of the missing code, and other subsequent
|
||||||
// suggestions can help the user fix the code.
|
// suggestions can help the user fix the code.
|
||||||
format!("{unsafety}fn {ident}{generics}({args}){output}{where_clauses} {{ todo!() }}")
|
format!(
|
||||||
|
"{unsafety}{asyncness}fn {ident}{generics}({args}){output}{where_clauses} {{ todo!() }}"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ty_kind_suggestion(ty: Ty<'_>) -> Option<&'static str> {
|
pub fn ty_kind_suggestion(ty: Ty<'_>) -> Option<&'static str> {
|
||||||
|
|
22
tests/ui/impl-trait/in-trait/suggest-missing-item.fixed
Normal file
22
tests/ui/impl-trait/in-trait/suggest-missing-item.fixed
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// edition:2021
|
||||||
|
// run-rustfix
|
||||||
|
|
||||||
|
#![feature(async_fn_in_trait, return_position_impl_trait_in_trait)]
|
||||||
|
|
||||||
|
trait Trait {
|
||||||
|
async fn foo();
|
||||||
|
|
||||||
|
async fn bar() -> i32;
|
||||||
|
|
||||||
|
fn test(&self) -> impl Sized + '_;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct S;
|
||||||
|
|
||||||
|
impl Trait for S {fn test(&self) -> impl Sized + '_ { todo!() }
|
||||||
|
async fn bar() -> i32 { todo!() }
|
||||||
|
async fn foo() { todo!() }
|
||||||
|
}
|
||||||
|
//~^ ERROR not all trait items implemented
|
||||||
|
|
||||||
|
fn main() {}
|
19
tests/ui/impl-trait/in-trait/suggest-missing-item.rs
Normal file
19
tests/ui/impl-trait/in-trait/suggest-missing-item.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// edition:2021
|
||||||
|
// run-rustfix
|
||||||
|
|
||||||
|
#![feature(async_fn_in_trait, return_position_impl_trait_in_trait)]
|
||||||
|
|
||||||
|
trait Trait {
|
||||||
|
async fn foo();
|
||||||
|
|
||||||
|
async fn bar() -> i32;
|
||||||
|
|
||||||
|
fn test(&self) -> impl Sized + '_;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct S;
|
||||||
|
|
||||||
|
impl Trait for S {}
|
||||||
|
//~^ ERROR not all trait items implemented
|
||||||
|
|
||||||
|
fn main() {}
|
18
tests/ui/impl-trait/in-trait/suggest-missing-item.stderr
Normal file
18
tests/ui/impl-trait/in-trait/suggest-missing-item.stderr
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
error[E0046]: not all trait items implemented, missing: `foo`, `bar`, `test`
|
||||||
|
--> $DIR/suggest-missing-item.rs:16:1
|
||||||
|
|
|
||||||
|
LL | async fn foo();
|
||||||
|
| --------------- `foo` from trait
|
||||||
|
LL |
|
||||||
|
LL | async fn bar() -> i32;
|
||||||
|
| ---------------------- `bar` from trait
|
||||||
|
LL |
|
||||||
|
LL | fn test(&self) -> impl Sized + '_;
|
||||||
|
| ---------------------------------- `test` from trait
|
||||||
|
...
|
||||||
|
LL | impl Trait for S {}
|
||||||
|
| ^^^^^^^^^^^^^^^^ missing `foo`, `bar`, `test` in implementation
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0046`.
|
Loading…
Add table
Add a link
Reference in a new issue