Skip to content

Commit

Permalink
Rollup merge of #111610 - bvanjoi:fix-99597, r=compiler-errors
Browse files Browse the repository at this point in the history
fix(diagnostic): wrap parens for ref impl trait param

Fixes #99597

When parameters are an `impl_trait` which it needed to add trait, and it is a reference, add parentheses to the type of the parameter in the suggestion
  • Loading branch information
matthiaskrgr authored May 16, 2023
2 parents 20f6aa1 + b2b2be1 commit d2e52ea
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 31 deletions.
77 changes: 46 additions & 31 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2633,47 +2633,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Nothing,
}
let ast_generics = hir.get_generics(id.owner.def_id).unwrap();
let (sp, mut introducer) = if let Some(span) =
ast_generics.bounds_span_for_suggestions(def_id)
{
(span, Introducer::Plus)
} else if let Some(colon_span) = param.colon_span {
(colon_span.shrink_to_hi(), Introducer::Nothing)
} else {
(param.span.shrink_to_hi(), Introducer::Colon)
};
if matches!(
param.kind,
hir::GenericParamKind::Type { synthetic: true, .. },
) {
introducer = Introducer::Plus
}
let trait_def_ids: FxHashSet<DefId> = ast_generics
.bounds_for_param(def_id)
.flat_map(|bp| bp.bounds.iter())
.filter_map(|bound| bound.trait_ref()?.trait_def_id())
.collect();
if !candidates.iter().any(|t| trait_def_ids.contains(&t.def_id)) {
err.span_suggestions(
sp,
message(format!(
"restrict type parameter `{}` with",
param.name.ident(),
)),
if candidates.iter().any(|t| trait_def_ids.contains(&t.def_id)) {
return;
}
let msg = message(format!(
"restrict type parameter `{}` with",
param.name.ident(),
));
let bounds_span = ast_generics.bounds_span_for_suggestions(def_id);
if rcvr_ty.is_ref() && param.is_impl_trait() && bounds_span.is_some() {
err.multipart_suggestions(
msg,
candidates.iter().map(|t| {
format!(
"{} {}",
match introducer {
Introducer::Plus => " +",
Introducer::Colon => ":",
Introducer::Nothing => "",
},
self.tcx.def_path_str(t.def_id),
)
vec![
(param.span.shrink_to_lo(), "(".to_string()),
(
bounds_span.unwrap(),
format!(" + {})", self.tcx.def_path_str(t.def_id)),
),
]
}),
Applicability::MaybeIncorrect,
);
return;
}

let (sp, introducer) = if let Some(span) = bounds_span {
(span, Introducer::Plus)
} else if let Some(colon_span) = param.colon_span {
(colon_span.shrink_to_hi(), Introducer::Nothing)
} else if param.is_impl_trait() {
(param.span.shrink_to_hi(), Introducer::Plus)
} else {
(param.span.shrink_to_hi(), Introducer::Colon)
};

err.span_suggestions(
sp,
msg,
candidates.iter().map(|t| {
format!(
"{} {}",
match introducer {
Introducer::Plus => " +",
Introducer::Colon => ":",
Introducer::Nothing => "",
},
self.tcx.def_path_str(t.def_id)
)
}),
Applicability::MaybeIncorrect,
);
return;
}
Node::Item(hir::Item {
Expand Down
15 changes: 15 additions & 0 deletions tests/ui/suggestions/issue-99597.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#![allow(dead_code)]

trait T1 { }

trait T2 {
fn test(&self) { }
}

fn go(s: &impl T1) {
//~^ SUGGESTION (
s.test();
//~^ ERROR no method named `test`
}

fn main() { }
15 changes: 15 additions & 0 deletions tests/ui/suggestions/issue-99597.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error[E0599]: no method named `test` found for reference `&impl T1` in the current scope
--> $DIR/issue-99597.rs:11:7
|
LL | s.test();
| ^^^^ method not found in `&impl T1`
|
= help: items from traits can only be used if the type parameter is bounded by the trait
help: the following trait defines an item `test`, perhaps you need to restrict type parameter `impl T1` with it:
|
LL | fn go(s: &(impl T1 + T2)) {
| + +++++

error: aborting due to previous error

For more information about this error, try `rustc --explain E0599`.

0 comments on commit d2e52ea

Please sign in to comment.