summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_hir_analysis/src/check/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_hir_analysis/src/check/mod.rs')
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs62
1 files changed, 42 insertions, 20 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 3971a4c01..ce2da7cb1 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -188,7 +188,7 @@ fn missing_items_err(
full_impl_span: Span,
) {
let missing_items =
- missing_items.iter().filter(|trait_item| tcx.opt_rpitit_info(trait_item.def_id).is_none());
+ missing_items.iter().filter(|trait_item| trait_item.opt_rpitit_info.is_none());
let missing_items_msg = missing_items
.clone()
@@ -296,7 +296,7 @@ fn default_body_is_unstable(
/// Re-sugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
fn bounds_from_generic_predicates<'tcx>(
tcx: TyCtxt<'tcx>,
- predicates: impl IntoIterator<Item = (ty::Predicate<'tcx>, Span)>,
+ predicates: impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>,
) -> (String, String) {
let mut types: FxHashMap<Ty<'tcx>, Vec<DefId>> = FxHashMap::default();
let mut projections = vec![];
@@ -304,7 +304,7 @@ fn bounds_from_generic_predicates<'tcx>(
debug!("predicate {:?}", predicate);
let bound_predicate = predicate.kind();
match bound_predicate.skip_binder() {
- ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) => {
+ ty::ClauseKind::Trait(trait_predicate) => {
let entry = types.entry(trait_predicate.self_ty()).or_default();
let def_id = trait_predicate.def_id();
if Some(def_id) != tcx.lang_items().sized_trait() {
@@ -313,7 +313,7 @@ fn bounds_from_generic_predicates<'tcx>(
entry.push(trait_predicate.def_id());
}
}
- ty::PredicateKind::Clause(ty::Clause::Projection(projection_pred)) => {
+ ty::ClauseKind::Projection(projection_pred) => {
projections.push(bound_predicate.rebind(projection_pred));
}
_ => {}
@@ -362,7 +362,7 @@ fn fn_sig_suggestion<'tcx>(
tcx: TyCtxt<'tcx>,
sig: ty::FnSig<'tcx>,
ident: Ident,
- predicates: impl IntoIterator<Item = (ty::Predicate<'tcx>, Span)>,
+ predicates: impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>,
assoc: ty::AssocItem,
) -> String {
let args = sig
@@ -403,7 +403,30 @@ fn fn_sig_suggestion<'tcx>(
.flatten()
.collect::<Vec<String>>()
.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.as_projection_clause()?.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 unsafety = sig.unsafety.prefix_str();
@@ -414,7 +437,9 @@ fn fn_sig_suggestion<'tcx>(
// 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
// 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> {
@@ -443,19 +468,16 @@ fn suggestion_signature<'tcx>(
);
match assoc.kind {
- ty::AssocKind::Fn => {
- // We skip the binder here because the binder would deanonymize all
- // late-bound regions, and we don't want method signatures to show up
- // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
- // regions just fine, showing `fn(&MyType)`.
- fn_sig_suggestion(
- tcx,
- tcx.fn_sig(assoc.def_id).subst(tcx, substs).skip_binder(),
- assoc.ident(tcx),
- tcx.predicates_of(assoc.def_id).instantiate_own(tcx, substs),
- assoc,
- )
- }
+ ty::AssocKind::Fn => fn_sig_suggestion(
+ tcx,
+ tcx.liberate_late_bound_regions(
+ assoc.def_id,
+ tcx.fn_sig(assoc.def_id).subst(tcx, substs),
+ ),
+ assoc.ident(tcx),
+ tcx.predicates_of(assoc.def_id).instantiate_own(tcx, substs),
+ assoc,
+ ),
ty::AssocKind::Type => {
let (generics, where_clauses) = bounds_from_generic_predicates(
tcx,