@@ -348,9 +348,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
348348 let type_param = generics. type_param ( param_type, self . tcx ) ;
349349 Some ( self . tcx . def_span ( type_param. def_id ) )
350350 }
351- ty:: Adt ( def, _) if def. did ( ) . is_local ( ) => {
352- tcx. def_ident_span ( def. did ( ) ) . map ( |span| span)
353- }
351+ ty:: Adt ( def, _) if def. did ( ) . is_local ( ) => Some ( tcx. def_span ( def. did ( ) ) ) ,
354352 _ => None ,
355353 } ;
356354
@@ -621,12 +619,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
621619 // Find all the requirements that come from a local `impl` block.
622620 let mut skip_list: FxHashSet < _ > = Default :: default ( ) ;
623621 let mut spanned_predicates: FxHashMap < MultiSpan , _ > = Default :: default ( ) ;
624- for ( data, p, parent_p, impl_def_id, cause_span ) in unsatisfied_predicates
622+ for ( data, p, parent_p, impl_def_id, cause ) in unsatisfied_predicates
625623 . iter ( )
626624 . filter_map ( |( p, parent, c) | c. as_ref ( ) . map ( |c| ( p, parent, c) ) )
627625 . filter_map ( |( p, parent, c) | match c. code ( ) {
628626 ObligationCauseCode :: ImplDerivedObligation ( ref data) => {
629- Some ( ( & data. derived , p, parent, data. impl_def_id , data. span ) )
627+ Some ( ( & data. derived , p, parent, data. impl_def_id , data) )
630628 }
631629 _ => None ,
632630 } )
@@ -695,9 +693,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
695693 let _ = format_pred ( * pred) ;
696694 }
697695 skip_list. insert ( p) ;
698- let mut spans = if cause_span != * item_span {
699- let mut spans: MultiSpan = cause_span . into ( ) ;
700- spans. push_span_label ( cause_span , unsatisfied_msg) ;
696+ let mut spans = if cause . span != * item_span {
697+ let mut spans: MultiSpan = cause . span . into ( ) ;
698+ spans. push_span_label ( cause . span , unsatisfied_msg) ;
701699 spans
702700 } else {
703701 ident. span . into ( )
@@ -709,7 +707,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
709707
710708 // Unmet obligation coming from an `impl`.
711709 Some ( Node :: Item ( hir:: Item {
712- kind : hir:: ItemKind :: Impl ( hir:: Impl { of_trait, self_ty, .. } ) ,
710+ kind :
711+ hir:: ItemKind :: Impl ( hir:: Impl {
712+ of_trait, self_ty, generics, ..
713+ } ) ,
713714 span : item_span,
714715 ..
715716 } ) ) if !matches ! (
@@ -725,14 +726,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
725726 Some ( ExpnKind :: Macro ( MacroKind :: Derive , _) )
726727 ) =>
727728 {
729+ let sized_pred =
730+ unsatisfied_predicates. iter ( ) . any ( |( pred, _, _) | {
731+ match pred. kind ( ) . skip_binder ( ) {
732+ ty:: PredicateKind :: Trait ( pred) => {
733+ Some ( pred. def_id ( ) )
734+ == self . tcx . lang_items ( ) . sized_trait ( )
735+ && pred. polarity == ty:: ImplPolarity :: Positive
736+ }
737+ _ => false ,
738+ }
739+ } ) ;
740+ for param in generics. params {
741+ if param. span == cause. span && sized_pred {
742+ let ( sp, sugg) = match param. colon_span {
743+ Some ( sp) => ( sp. shrink_to_hi ( ) , " ?Sized +" ) ,
744+ None => ( param. span . shrink_to_hi ( ) , ": ?Sized" ) ,
745+ } ;
746+ err. span_suggestion_verbose (
747+ sp,
748+ "consider relaxing the type parameter's implicit \
749+ `Sized` bound",
750+ sugg,
751+ Applicability :: MachineApplicable ,
752+ ) ;
753+ }
754+ }
728755 if let Some ( pred) = parent_p {
729756 // Done to add the "doesn't satisfy" `span_label`.
730757 let _ = format_pred ( * pred) ;
731758 }
732759 skip_list. insert ( p) ;
733- let mut spans = if cause_span != * item_span {
734- let mut spans: MultiSpan = cause_span . into ( ) ;
735- spans. push_span_label ( cause_span , unsatisfied_msg) ;
760+ let mut spans = if cause . span != * item_span {
761+ let mut spans: MultiSpan = cause . span . into ( ) ;
762+ spans. push_span_label ( cause . span , unsatisfied_msg) ;
736763 spans
737764 } else {
738765 let mut spans = Vec :: with_capacity ( 2 ) ;
0 commit comments