X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=compiler%2Frustc_typeck%2Fsrc%2Fcheck%2Fmethod%2Fsuggest.rs;h=7bf167426f7480cd5badf1b06051ecc2e1d1455d;hb=1e7d04b23b6e9d177e7d879b05b4ce3f00ee5a0e;hp=4e1a105fc71cc0a308e91f07f3e84eac146e2532;hpb=052495d0017e2b18b781bcf0469a048e5051f5c0;p=rust.git diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 4e1a105fc71..7bf167426f7 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -348,9 +348,7 @@ pub fn report_method_error( let type_param = generics.type_param(param_type, self.tcx); Some(self.tcx.def_span(type_param.def_id)) } - ty::Adt(def, _) if def.did().is_local() => { - tcx.def_ident_span(def.did()).map(|span| span) - } + ty::Adt(def, _) if def.did().is_local() => Some(tcx.def_span(def.did())), _ => None, }; @@ -621,12 +619,12 @@ pub fn report_method_error( // Find all the requirements that come from a local `impl` block. let mut skip_list: FxHashSet<_> = Default::default(); let mut spanned_predicates: FxHashMap = Default::default(); - for (data, p, parent_p, impl_def_id, cause_span) in unsatisfied_predicates + for (data, p, parent_p, impl_def_id, cause) in unsatisfied_predicates .iter() .filter_map(|(p, parent, c)| c.as_ref().map(|c| (p, parent, c))) .filter_map(|(p, parent, c)| match c.code() { ObligationCauseCode::ImplDerivedObligation(ref data) => { - Some((&data.derived, p, parent, data.impl_def_id, data.span)) + Some((&data.derived, p, parent, data.impl_def_id, data)) } _ => None, }) @@ -695,9 +693,9 @@ pub fn report_method_error( let _ = format_pred(*pred); } skip_list.insert(p); - let mut spans = if cause_span != *item_span { - let mut spans: MultiSpan = cause_span.into(); - spans.push_span_label(cause_span, unsatisfied_msg); + let mut spans = if cause.span != *item_span { + let mut spans: MultiSpan = cause.span.into(); + spans.push_span_label(cause.span, unsatisfied_msg); spans } else { ident.span.into() @@ -709,7 +707,10 @@ pub fn report_method_error( // Unmet obligation coming from an `impl`. Some(Node::Item(hir::Item { - kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }), + kind: + hir::ItemKind::Impl(hir::Impl { + of_trait, self_ty, generics, .. + }), span: item_span, .. })) if !matches!( @@ -725,14 +726,40 @@ pub fn report_method_error( Some(ExpnKind::Macro(MacroKind::Derive, _)) ) => { + let sized_pred = + unsatisfied_predicates.iter().any(|(pred, _, _)| { + match pred.kind().skip_binder() { + ty::PredicateKind::Trait(pred) => { + Some(pred.def_id()) + == self.tcx.lang_items().sized_trait() + && pred.polarity == ty::ImplPolarity::Positive + } + _ => false, + } + }); + for param in generics.params { + if param.span == cause.span && sized_pred { + let (sp, sugg) = match param.colon_span { + Some(sp) => (sp.shrink_to_hi(), " ?Sized +"), + None => (param.span.shrink_to_hi(), ": ?Sized"), + }; + err.span_suggestion_verbose( + sp, + "consider relaxing the type parameter's implicit \ + `Sized` bound", + sugg, + Applicability::MachineApplicable, + ); + } + } if let Some(pred) = parent_p { // Done to add the "doesn't satisfy" `span_label`. let _ = format_pred(*pred); } skip_list.insert(p); - let mut spans = if cause_span != *item_span { - let mut spans: MultiSpan = cause_span.into(); - spans.push_span_label(cause_span, unsatisfied_msg); + let mut spans = if cause.span != *item_span { + let mut spans: MultiSpan = cause.span.into(); + spans.push_span_label(cause.span, unsatisfied_msg); spans } else { let mut spans = Vec::with_capacity(2);