@@ -348,9 +348,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
348
348
let type_param = generics. type_param ( param_type, self . tcx ) ;
349
349
Some ( self . tcx . def_span ( type_param. def_id ) )
350
350
}
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 ( ) ) ) ,
354
352
_ => None ,
355
353
} ;
356
354
@@ -621,12 +619,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
621
619
// Find all the requirements that come from a local `impl` block.
622
620
let mut skip_list: FxHashSet < _ > = Default :: default ( ) ;
623
621
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
625
623
. iter ( )
626
624
. filter_map ( |( p, parent, c) | c. as_ref ( ) . map ( |c| ( p, parent, c) ) )
627
625
. filter_map ( |( p, parent, c) | match c. code ( ) {
628
626
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) )
630
628
}
631
629
_ => None ,
632
630
} )
@@ -695,9 +693,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
695
693
let _ = format_pred ( * pred) ;
696
694
}
697
695
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) ;
701
699
spans
702
700
} else {
703
701
ident. span . into ( )
@@ -709,7 +707,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
709
707
710
708
// Unmet obligation coming from an `impl`.
711
709
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
+ } ) ,
713
714
span : item_span,
714
715
..
715
716
} ) ) if !matches ! (
@@ -725,14 +726,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
725
726
Some ( ExpnKind :: Macro ( MacroKind :: Derive , _) )
726
727
) =>
727
728
{
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
+ }
728
755
if let Some ( pred) = parent_p {
729
756
// Done to add the "doesn't satisfy" `span_label`.
730
757
let _ = format_pred ( * pred) ;
731
758
}
732
759
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) ;
736
763
spans
737
764
} else {
738
765
let mut spans = Vec :: with_capacity ( 2 ) ;
0 commit comments