@@ -1725,24 +1725,41 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
17251725pub fn recursive_type_with_infinite_size_error (
17261726 tcx : TyCtxt < ' tcx > ,
17271727 type_def_id : DefId ,
1728- ) -> DiagnosticBuilder < ' tcx > {
1728+ spans : Vec < Span > ,
1729+ ) {
17291730 assert ! ( type_def_id. is_local( ) ) ;
17301731 let span = tcx. hir ( ) . span_if_local ( type_def_id) . unwrap ( ) ;
17311732 let span = tcx. sess . source_map ( ) . guess_head_span ( span) ;
1732- let mut err = struct_span_err ! (
1733- tcx. sess,
1734- span,
1735- E0072 ,
1736- "recursive type `{}` has infinite size" ,
1737- tcx. def_path_str( type_def_id)
1738- ) ;
1733+ let path = tcx. def_path_str ( type_def_id) ;
1734+ let mut err =
1735+ struct_span_err ! ( tcx. sess, span, E0072 , "recursive type `{}` has infinite size" , path) ;
17391736 err. span_label ( span, "recursive type has infinite size" ) ;
1740- err. help ( & format ! (
1741- "insert indirection (e.g., a `Box`, `Rc`, or `&`) \
1742- at some point to make `{}` representable",
1743- tcx. def_path_str( type_def_id)
1744- ) ) ;
1745- err
1737+ for & span in & spans {
1738+ err. span_label ( span, "recursive without indirection" ) ;
1739+ }
1740+ let msg = format ! (
1741+ "insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `{}` representable" ,
1742+ path,
1743+ ) ;
1744+ if spans. len ( ) <= 4 {
1745+ err. multipart_suggestion (
1746+ & msg,
1747+ spans
1748+ . iter ( )
1749+ . flat_map ( |& span| {
1750+ vec ! [
1751+ ( span. shrink_to_lo( ) , "Box<" . to_string( ) ) ,
1752+ ( span. shrink_to_hi( ) , ">" . to_string( ) ) ,
1753+ ]
1754+ . into_iter ( )
1755+ } )
1756+ . collect ( ) ,
1757+ Applicability :: HasPlaceholders ,
1758+ ) ;
1759+ } else {
1760+ err. help ( & msg) ;
1761+ }
1762+ err. emit ( ) ;
17461763}
17471764
17481765/// Summarizes information
0 commit comments