]> git.lizzy.rs Git - rust.git/commitdiff
On recursive ADT, provide indirection structured suggestion
authorEsteban Küber <esteban@kuber.com.ar>
Fri, 29 May 2020 16:24:59 +0000 (09:24 -0700)
committerEsteban Küber <esteban@kuber.com.ar>
Wed, 10 Jun 2020 21:09:51 +0000 (14:09 -0700)
27 files changed:
src/librustc_errors/diagnostic.rs
src/librustc_errors/diagnostic_builder.rs
src/librustc_middle/ty/util.rs
src/librustc_trait_selection/traits/error_reporting/mod.rs
src/librustc_typeck/check/mod.rs
src/test/ui/infinite/infinite-tag-type-recursion.stderr
src/test/ui/issues/issue-17431-1.stderr
src/test/ui/issues/issue-17431-2.stderr
src/test/ui/issues/issue-17431-3.stderr
src/test/ui/issues/issue-17431-4.stderr
src/test/ui/issues/issue-17431-5.stderr
src/test/ui/issues/issue-17431-6.stderr
src/test/ui/issues/issue-17431-7.stderr
src/test/ui/issues/issue-2718-a.stderr
src/test/ui/issues/issue-3008-1.stderr
src/test/ui/issues/issue-3008-2.stderr
src/test/ui/issues/issue-3008-3.stderr
src/test/ui/issues/issue-32326.stderr
src/test/ui/issues/issue-3779.stderr
src/test/ui/issues/issue-57271.stderr
src/test/ui/recursion/recursive-enum.stderr
src/test/ui/sized-cycle-note.stderr
src/test/ui/span/E0072.stderr
src/test/ui/span/multiline-span-E0072.stderr
src/test/ui/span/recursive-type-field.stderr
src/test/ui/type/type-recursive.stderr
src/test/ui/union/union-nonrepresentable.stderr

index cff83c3d5cda2a7e39e0520b479d8b0f47b93148..acaa26c6ad2fc609b72adbc4c8f79761e3ab902e 100644 (file)
@@ -296,6 +296,29 @@ pub fn multipart_suggestion(
         self
     }
 
+    pub fn multipart_suggestions(
+        &mut self,
+        msg: &str,
+        suggestions: Vec<Vec<(Span, String)>>,
+        applicability: Applicability,
+    ) -> &mut Self {
+        self.suggestions.push(CodeSuggestion {
+            substitutions: suggestions
+                .into_iter()
+                .map(|suggestion| Substitution {
+                    parts: suggestion
+                        .into_iter()
+                        .map(|(span, snippet)| SubstitutionPart { snippet, span })
+                        .collect(),
+                })
+                .collect(),
+            msg: msg.to_owned(),
+            style: SuggestionStyle::ShowCode,
+            applicability,
+        });
+        self
+    }
+
     /// Prints out a message with for a multipart suggestion without showing the suggested code.
     ///
     /// This is intended to be used for suggestions that are obvious in what the changes need to
index 2dbd9f4e52fad36f5633d7faf18fc224771b51d6..22bf8fe34aa155543c72fa41ad11d746ec1c8ee3 100644 (file)
@@ -260,6 +260,19 @@ pub fn multipart_suggestion(
         self
     }
 
+    pub fn multipart_suggestions(
+        &mut self,
+        msg: &str,
+        suggestions: Vec<Vec<(Span, String)>>,
+        applicability: Applicability,
+    ) -> &mut Self {
+        if !self.0.allow_suggestions {
+            return self;
+        }
+        self.0.diagnostic.multipart_suggestions(msg, suggestions, applicability);
+        self
+    }
+
     pub fn tool_only_multipart_suggestion(
         &mut self,
         msg: &str,
index c2b794ca4bdd9e0ed5e3d6a2ca0a16ed795551f6..5cdfa6f90128dabf35cd962f265978431c5010c4 100644 (file)
@@ -827,7 +827,15 @@ fn are_inner_types_recursive<'tcx>(
                     // Find non representable fields with their spans
                     fold_repr(def.all_fields().map(|field| {
                         let ty = field.ty(tcx, substs);
-                        let span = tcx.hir().span_if_local(field.did).unwrap_or(sp);
+                        let span = match field
+                            .did
+                            .as_local()
+                            .map(|id| tcx.hir().as_local_hir_id(id))
+                            .and_then(|id| tcx.hir().find(id))
+                        {
+                            Some(hir::Node::Field(field)) => field.ty.span,
+                            _ => sp,
+                        };
                         match is_type_structurally_recursive(
                             tcx,
                             span,
index 1b72a4bf84f191b363915745594c3bdc550b3b7e..3457f7b4580c5ec8360a0cadd76221b36212c4b7 100644 (file)
@@ -1747,24 +1747,62 @@ fn is_recursive_obligation(
 pub fn recursive_type_with_infinite_size_error(
     tcx: TyCtxt<'tcx>,
     type_def_id: DefId,
-) -> DiagnosticBuilder<'tcx> {
+    spans: Vec<Span>,
+) {
     assert!(type_def_id.is_local());
     let span = tcx.hir().span_if_local(type_def_id).unwrap();
     let span = tcx.sess.source_map().guess_head_span(span);
-    let mut err = struct_span_err!(
-        tcx.sess,
-        span,
-        E0072,
-        "recursive type `{}` has infinite size",
-        tcx.def_path_str(type_def_id)
-    );
+    let path = tcx.def_path_str(type_def_id);
+    let mut err =
+        struct_span_err!(tcx.sess, span, E0072, "recursive type `{}` has infinite size", path);
     err.span_label(span, "recursive type has infinite size");
-    err.help(&format!(
-        "insert indirection (e.g., a `Box`, `Rc`, or `&`) \
-                           at some point to make `{}` representable",
-        tcx.def_path_str(type_def_id)
-    ));
-    err
+    for &span in &spans {
+        err.span_label(span, "recursive without indirection");
+    }
+    let short_msg = format!("insert some indirection to make `{}` representable", path);
+    let msg = format!(
+        "insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `{}` representable",
+        path,
+    );
+    match &spans[..] {
+        [span] => {
+            err.multipart_suggestions(
+                &short_msg,
+                vec![
+                    vec![
+                        (span.shrink_to_lo(), "Box<".to_string()),
+                        (span.shrink_to_hi(), ">".to_string()),
+                    ],
+                    vec![
+                        (span.shrink_to_lo(), "Rc<".to_string()),
+                        (span.shrink_to_hi(), ">".to_string()),
+                    ],
+                    vec![(span.shrink_to_lo(), "&".to_string())],
+                ],
+                Applicability::HasPlaceholders,
+            );
+        }
+        _ if spans.len() <= 4 => {
+            err.multipart_suggestion(
+                &msg,
+                spans
+                    .iter()
+                    .flat_map(|&span| {
+                        vec![
+                            (span.shrink_to_lo(), "Box<".to_string()),
+                            (span.shrink_to_hi(), ">".to_string()),
+                        ]
+                        .into_iter()
+                    })
+                    .collect(),
+                Applicability::HasPlaceholders,
+            );
+        }
+        _ => {
+            err.help(&msg);
+        }
+    }
+    err.emit();
 }
 
 /// Summarizes information
index f2aeed4f1e46563fc3a418111e4879ae7843d92e..1e8a149d7d9ec35bad99fbe645bbe23fa3c700d7 100644 (file)
@@ -2390,11 +2390,7 @@ fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: LocalDefId) -> bo
     // caught by case 1.
     match rty.is_representable(tcx, sp) {
         Representability::SelfRecursive(spans) => {
-            let mut err = recursive_type_with_infinite_size_error(tcx, item_def_id.to_def_id());
-            for span in spans {
-                err.span_label(span, "recursive without indirection");
-            }
-            err.emit();
+            recursive_type_with_infinite_size_error(tcx, item_def_id.to_def_id(), spans);
             return false;
         }
         Representability::Representable | Representability::ContainsRecursive => (),
index 11f82b842ba6f600caba727f333441fbe102d653..b6a4d8f4cf563bb0983897f3016c6acad1539b32 100644 (file)
@@ -6,7 +6,14 @@ LL | enum MList { Cons(isize, MList), Nil }
    | |
    | recursive type has infinite size
    |
-   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `MList` representable
+help: insert some indirection to make `MList` representable
+   |
+LL | enum MList { Cons(isize, Box<MList>), Nil }
+   |                          ^^^^     ^
+LL | enum MList { Cons(isize, Rc<MList>), Nil }
+   |                          ^^^     ^
+LL | enum MList { Cons(isize, &MList), Nil }
+   |                          ^
 
 error[E0391]: cycle detected when computing drop-check constraints for `MList`
   --> $DIR/infinite-tag-type-recursion.rs:1:1
index eb5a1366e8953d5b5bd4101a5cb8c530299c1755..8d44154650e04305feff43ba5090891e7ab5c5e3 100644 (file)
@@ -2,11 +2,18 @@ error[E0072]: recursive type `Foo` has infinite size
   --> $DIR/issue-17431-1.rs:1:1
    |
 LL | struct Foo { foo: Option<Option<Foo>> }
-   | ^^^^^^^^^^   ------------------------ recursive without indirection
+   | ^^^^^^^^^^        ------------------- recursive without indirection
    | |
    | recursive type has infinite size
    |
-   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Foo` representable
+help: insert some indirection to make `Foo` representable
+   |
+LL | struct Foo { foo: Box<Option<Option<Foo>>> }
+   |                   ^^^^                   ^
+LL | struct Foo { foo: Rc<Option<Option<Foo>>> }
+   |                   ^^^                   ^
+LL | struct Foo { foo: &Option<Option<Foo>> }
+   |                   ^
 
 error: aborting due to previous error
 
index 3a7b0e9ce7997b66def8b48da995582bd6b360a1..b06184e84da28744d20c42d7f881b8a19b6635c5 100644 (file)
@@ -2,21 +2,35 @@ error[E0072]: recursive type `Baz` has infinite size
   --> $DIR/issue-17431-2.rs:1:1
    |
 LL | struct Baz { q: Option<Foo> }
-   | ^^^^^^^^^^   -------------- recursive without indirection
+   | ^^^^^^^^^^      ----------- recursive without indirection
    | |
    | recursive type has infinite size
    |
-   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Baz` representable
+help: insert some indirection to make `Baz` representable
+   |
+LL | struct Baz { q: Box<Option<Foo>> }
+   |                 ^^^^           ^
+LL | struct Baz { q: Rc<Option<Foo>> }
+   |                 ^^^           ^
+LL | struct Baz { q: &Option<Foo> }
+   |                 ^
 
 error[E0072]: recursive type `Foo` has infinite size
   --> $DIR/issue-17431-2.rs:4:1
    |
 LL | struct Foo { q: Option<Baz> }
-   | ^^^^^^^^^^   -------------- recursive without indirection
+   | ^^^^^^^^^^      ----------- recursive without indirection
    | |
    | recursive type has infinite size
    |
-   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Foo` representable
+help: insert some indirection to make `Foo` representable
+   |
+LL | struct Foo { q: Box<Option<Baz>> }
+   |                 ^^^^           ^
+LL | struct Foo { q: Rc<Option<Baz>> }
+   |                 ^^^           ^
+LL | struct Foo { q: &Option<Baz> }
+   |                 ^
 
 error: aborting due to 2 previous errors
 
index 675a2e27142091463706d5028225cc59877dc9d3..f32bd70fd6d943e01006dbc8a5c3947ebdf3ff41 100644 (file)
@@ -2,11 +2,18 @@ error[E0072]: recursive type `Foo` has infinite size
   --> $DIR/issue-17431-3.rs:3:1
    |
 LL | struct Foo { foo: Mutex<Option<Foo>> }
-   | ^^^^^^^^^^   ----------------------- recursive without indirection
+   | ^^^^^^^^^^        ------------------ recursive without indirection
    | |
    | recursive type has infinite size
    |
-   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Foo` representable
+help: insert some indirection to make `Foo` representable
+   |
+LL | struct Foo { foo: Box<Mutex<Option<Foo>>> }
+   |                   ^^^^                  ^
+LL | struct Foo { foo: Rc<Mutex<Option<Foo>>> }
+   |                   ^^^                  ^
+LL | struct Foo { foo: &Mutex<Option<Foo>> }
+   |                   ^
 
 error: aborting due to previous error
 
index aff9071095ca0da5d56f7f24e28785aacbf21d62..372c5e975c844b4e37507a1d838891a8e8d4ee9f 100644 (file)
@@ -2,11 +2,18 @@ error[E0072]: recursive type `Foo` has infinite size
   --> $DIR/issue-17431-4.rs:3:1
    |
 LL | struct Foo<T> { foo: Option<Option<Foo<T>>>, marker: marker::PhantomData<T> }
-   | ^^^^^^^^^^^^^   --------------------------- recursive without indirection
+   | ^^^^^^^^^^^^^        ---------------------- recursive without indirection
    | |
    | recursive type has infinite size
    |
-   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Foo` representable
+help: insert some indirection to make `Foo` representable
+   |
+LL | struct Foo<T> { foo: Box<Option<Option<Foo<T>>>>, marker: marker::PhantomData<T> }
+   |                      ^^^^                      ^
+LL | struct Foo<T> { foo: Rc<Option<Option<Foo<T>>>>, marker: marker::PhantomData<T> }
+   |                      ^^^                      ^
+LL | struct Foo<T> { foo: &Option<Option<Foo<T>>>, marker: marker::PhantomData<T> }
+   |                      ^
 
 error: aborting due to previous error
 
index 537f9f34f55caf37e41be8f9f214888a8f680c6e..01b850ac336949fcd842d27d13f3393acfda07b1 100644 (file)
@@ -2,11 +2,18 @@ error[E0072]: recursive type `Bar` has infinite size
   --> $DIR/issue-17431-5.rs:5:1
    |
 LL | struct Bar<T> { x: Bar<Foo> , marker: marker::PhantomData<T> }
-   | ^^^^^^^^^^^^^   ----------- recursive without indirection
+   | ^^^^^^^^^^^^^      -------- recursive without indirection
    | |
    | recursive type has infinite size
    |
-   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Bar` representable
+help: insert some indirection to make `Bar` representable
+   |
+LL | struct Bar<T> { x: Box<Bar<Foo>> , marker: marker::PhantomData<T> }
+   |                    ^^^^        ^
+LL | struct Bar<T> { x: Rc<Bar<Foo>> , marker: marker::PhantomData<T> }
+   |                    ^^^        ^
+LL | struct Bar<T> { x: &Bar<Foo> , marker: marker::PhantomData<T> }
+   |                    ^
 
 error: aborting due to previous error
 
index cb2dab950148832cee1597c1ea8c90e46a93fcc6..ce6c2db07fb6d641fec4b795328a44cb22d368c3 100644 (file)
@@ -6,7 +6,14 @@ LL | enum Foo { X(Mutex<Option<Foo>>) }
    | |
    | recursive type has infinite size
    |
-   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Foo` representable
+help: insert some indirection to make `Foo` representable
+   |
+LL | enum Foo { X(Box<Mutex<Option<Foo>>>) }
+   |              ^^^^                  ^
+LL | enum Foo { X(Rc<Mutex<Option<Foo>>>) }
+   |              ^^^                  ^
+LL | enum Foo { X(&Mutex<Option<Foo>>) }
+   |              ^
 
 error: aborting due to previous error
 
index de70851da4b5fc9b50e2f24193aefa3c4eb1205f..4fb563ba502f2294af61399b5c2dbd605fbaf55e 100644 (file)
@@ -6,7 +6,14 @@ LL | enum Foo { Voo(Option<Option<Foo>>) }
    | |
    | recursive type has infinite size
    |
-   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Foo` representable
+help: insert some indirection to make `Foo` representable
+   |
+LL | enum Foo { Voo(Box<Option<Option<Foo>>>) }
+   |                ^^^^                   ^
+LL | enum Foo { Voo(Rc<Option<Option<Foo>>>) }
+   |                ^^^                   ^
+LL | enum Foo { Voo(&Option<Option<Foo>>) }
+   |                ^
 
 error: aborting due to previous error
 
index 0f52c79192843654951ef37022ec2ed17c470d15..48b7a61e059ea26565d4a21a4d0bd0afe4c137e4 100644 (file)
@@ -7,7 +7,14 @@ LL |     pub struct Pong(SendPacket<Ping>);
    |     |               recursive without indirection
    |     recursive type has infinite size
    |
-   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `pingpong::Pong` representable
+help: insert some indirection to make `pingpong::Pong` representable
+   |
+LL |     pub struct Pong(Box<SendPacket<Ping>>);
+   |                     ^^^^                ^
+LL |     pub struct Pong(Rc<SendPacket<Ping>>);
+   |                     ^^^                ^
+LL |     pub struct Pong(&SendPacket<Ping>);
+   |                     ^
 
 error: aborting due to previous error
 
index f12274134ee05bd1be370dbd002597f4f41b8ef8..d1173a4b3334c23e37ae0b4dce27af603fc88ec8 100644 (file)
@@ -7,7 +7,14 @@ LL | enum Bar {
 LL |     BarSome(Bar)
    |             --- recursive without indirection
    |
-   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Bar` representable
+help: insert some indirection to make `Bar` representable
+   |
+LL |     BarSome(Box<Bar>)
+   |             ^^^^   ^
+LL |     BarSome(Rc<Bar>)
+   |             ^^^   ^
+LL |     BarSome(&Bar)
+   |             ^
 
 error: aborting due to previous error
 
index acc15f4b57c73cd51f44ff090cd7e27545d4e534..4fd60639b21a8f7116ee1aeb8bdcfab2f666a4e2 100644 (file)
@@ -2,11 +2,18 @@ error[E0072]: recursive type `Bar` has infinite size
   --> $DIR/issue-3008-2.rs:2:1
    |
 LL | struct Bar { x: Bar }
-   | ^^^^^^^^^^   ------ recursive without indirection
+   | ^^^^^^^^^^      --- recursive without indirection
    | |
    | recursive type has infinite size
    |
-   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Bar` representable
+help: insert some indirection to make `Bar` representable
+   |
+LL | struct Bar { x: Box<Bar> }
+   |                 ^^^^   ^
+LL | struct Bar { x: Rc<Bar> }
+   |                 ^^^   ^
+LL | struct Bar { x: &Bar }
+   |                 ^
 
 error: aborting due to previous error
 
index d08a3d9708db3224fcfec94de60702ba7a1411dc..e6efad918830005cc1a9aadfefc78bfdf2114fab 100644 (file)
@@ -6,7 +6,14 @@ LL | enum E2<T> { V2(E2<E1>, marker::PhantomData<T>), }
    | |
    | recursive type has infinite size
    |
-   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `E2` representable
+help: insert some indirection to make `E2` representable
+   |
+LL | enum E2<T> { V2(Box<E2<E1>>, marker::PhantomData<T>), }
+   |                 ^^^^      ^
+LL | enum E2<T> { V2(Rc<E2<E1>>, marker::PhantomData<T>), }
+   |                 ^^^      ^
+LL | enum E2<T> { V2(&E2<E1>, marker::PhantomData<T>), }
+   |                 ^
 
 error: aborting due to previous error
 
index 5967627e51a4b4bb104478ca2e3bae23bd404284..0f3d3690b732ea1bf1d3660b2bd441f02caae636 100644 (file)
@@ -8,7 +8,10 @@ LL |     Plus(Expr, Expr),
    |          |
    |          recursive without indirection
    |
-   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Expr` representable
+help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Expr` representable
+   |
+LL |     Plus(Box<Expr>, Box<Expr>),
+   |          ^^^^    ^  ^^^^    ^
 
 error: aborting due to previous error
 
index ba1e842c610baa51c17ad21be9175ee3ce8bc1e4..9b50ddec12a44aa093939714b8f9d474e5e35af0 100644 (file)
@@ -5,9 +5,16 @@ LL | struct S {
    | ^^^^^^^^ recursive type has infinite size
 LL |
 LL |     element: Option<S>
-   |     ------------------ recursive without indirection
+   |              --------- recursive without indirection
    |
-   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `S` representable
+help: insert some indirection to make `S` representable
+   |
+LL |     element: Box<Option<S>>
+   |              ^^^^         ^
+LL |     element: Rc<Option<S>>
+   |              ^^^         ^
+LL |     element: &Option<S>
+   |              ^
 
 error: aborting due to previous error
 
index 4f164624f7a537ec87aaf68ee8ca11dfa1da1630..a6fe83a9b563632af9c490dffa1ad7454a143a02 100644 (file)
@@ -7,7 +7,14 @@ LL |     Class(ClassTypeSignature),
 LL |     Array(TypeSignature),
    |           ------------- recursive without indirection
    |
-   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `ObjectType` representable
+help: insert some indirection to make `ObjectType` representable
+   |
+LL |     Array(Box<TypeSignature>),
+   |           ^^^^             ^
+LL |     Array(Rc<TypeSignature>),
+   |           ^^^             ^
+LL |     Array(&TypeSignature),
+   |           ^
 
 error[E0072]: recursive type `TypeSignature` has infinite size
   --> $DIR/issue-57271.rs:19:1
@@ -18,7 +25,14 @@ LL |     Base(BaseType),
 LL |     Object(ObjectType),
    |            ---------- recursive without indirection
    |
-   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `TypeSignature` representable
+help: insert some indirection to make `TypeSignature` representable
+   |
+LL |     Object(Box<ObjectType>),
+   |            ^^^^          ^
+LL |     Object(Rc<ObjectType>),
+   |            ^^^          ^
+LL |     Object(&ObjectType),
+   |            ^
 
 error: aborting due to 2 previous errors
 
index e4674b57a6d2144cbf770548d790b9bc4d3b0a93..c68badd458bce7431ae8d38043729c6ef4c46e3c 100644 (file)
@@ -6,7 +6,14 @@ LL | enum List<T> { Cons(T, List<T>), Nil }
    | |
    | recursive type has infinite size
    |
-   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `List` representable
+help: insert some indirection to make `List` representable
+   |
+LL | enum List<T> { Cons(T, Box<List<T>>), Nil }
+   |                        ^^^^       ^
+LL | enum List<T> { Cons(T, Rc<List<T>>), Nil }
+   |                        ^^^       ^
+LL | enum List<T> { Cons(T, &List<T>), Nil }
+   |                        ^
 
 error: aborting due to previous error
 
index 95bdc34942645bc85f779d617b8fdc16f7f05dfc..99d8cfd0a05c93344c337d5cb57da671a76cc74b 100644 (file)
@@ -2,21 +2,35 @@ error[E0072]: recursive type `Baz` has infinite size
   --> $DIR/sized-cycle-note.rs:9:1
    |
 LL | struct Baz { q: Option<Foo> }
-   | ^^^^^^^^^^   -------------- recursive without indirection
+   | ^^^^^^^^^^      ----------- recursive without indirection
    | |
    | recursive type has infinite size
    |
-   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Baz` representable
+help: insert some indirection to make `Baz` representable
+   |
+LL | struct Baz { q: Box<Option<Foo>> }
+   |                 ^^^^           ^
+LL | struct Baz { q: Rc<Option<Foo>> }
+   |                 ^^^           ^
+LL | struct Baz { q: &Option<Foo> }
+   |                 ^
 
 error[E0072]: recursive type `Foo` has infinite size
   --> $DIR/sized-cycle-note.rs:11:1
    |
 LL | struct Foo { q: Option<Baz> }
-   | ^^^^^^^^^^   -------------- recursive without indirection
+   | ^^^^^^^^^^      ----------- recursive without indirection
    | |
    | recursive type has infinite size
    |
-   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Foo` representable
+help: insert some indirection to make `Foo` representable
+   |
+LL | struct Foo { q: Box<Option<Baz>> }
+   |                 ^^^^           ^
+LL | struct Foo { q: Rc<Option<Baz>> }
+   |                 ^^^           ^
+LL | struct Foo { q: &Option<Baz> }
+   |                 ^
 
 error: aborting due to 2 previous errors
 
index d4a5e7400d2a46b7b9cd89d29ff82ccb8448fd59..855e4facb7b8cb93127561dc2675ac5bb893344a 100644 (file)
@@ -5,9 +5,16 @@ LL | struct ListNode {
    | ^^^^^^^^^^^^^^^ recursive type has infinite size
 LL |     head: u8,
 LL |     tail: Option<ListNode>,
-   |     ---------------------- recursive without indirection
+   |           ---------------- recursive without indirection
    |
-   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `ListNode` representable
+help: insert some indirection to make `ListNode` representable
+   |
+LL |     tail: Box<Option<ListNode>>,
+   |           ^^^^                ^
+LL |     tail: Rc<Option<ListNode>>,
+   |           ^^^                ^
+LL |     tail: &Option<ListNode>,
+   |           ^
 
 error: aborting due to previous error
 
index dd322fe833b49147ec771162b792be5b20b74657..260c2157e96b75a90cb311fec48d1f63b04d84ed 100644 (file)
@@ -6,11 +6,18 @@ LL | | ListNode
 LL | | {
 LL | |     head: u8,
 LL | |     tail: Option<ListNode>,
-   | |     ---------------------- recursive without indirection
+   | |           ---------------- recursive without indirection
 LL | | }
    | |_^ recursive type has infinite size
    |
-   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `ListNode` representable
+help: insert some indirection to make `ListNode` representable
+   |
+LL |     tail: Box<Option<ListNode>>,
+   |           ^^^^                ^
+LL |     tail: Rc<Option<ListNode>>,
+   |           ^^^                ^
+LL |     tail: &Option<ListNode>,
+   |           ^
 
 error: aborting due to previous error
 
index d240872647e506771044e3fa7fcc7303d08d2450..c1a3270d0a567584222440a14668b0c58116a20f 100644 (file)
@@ -4,9 +4,16 @@ error[E0072]: recursive type `Foo` has infinite size
 LL | struct Foo<'a> {
    | ^^^^^^^^^^^^^^ recursive type has infinite size
 LL |     bar: Bar<'a>,
-   |     ------------ recursive without indirection
+   |          ------- recursive without indirection
    |
-   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Foo` representable
+help: insert some indirection to make `Foo` representable
+   |
+LL |     bar: Box<Bar<'a>>,
+   |          ^^^^       ^
+LL |     bar: Rc<Bar<'a>>,
+   |          ^^^       ^
+LL |     bar: &Bar<'a>,
+   |          ^
 
 error[E0072]: recursive type `Bar` has infinite size
   --> $DIR/recursive-type-field.rs:8:1
@@ -14,18 +21,18 @@ error[E0072]: recursive type `Bar` has infinite size
 LL | struct Bar<'a> {
    | ^^^^^^^^^^^^^^ recursive type has infinite size
 LL |     y: (Foo<'a>, Foo<'a>),
-   |     --------------------- recursive without indirection
+   |        ------------------ recursive without indirection
 LL |     z: Option<Bar<'a>>,
-   |     ------------------ recursive without indirection
+   |        --------------- recursive without indirection
 ...
 LL |     d: [Bar<'a>; 1],
-   |     --------------- recursive without indirection
+   |        ------------ recursive without indirection
 LL |     e: Foo<'a>,
-   |     ---------- recursive without indirection
+   |        ------- recursive without indirection
 LL |     x: Bar<'a>,
-   |     ---------- recursive without indirection
+   |        ------- recursive without indirection
    |
-   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Bar` representable
+   = help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Bar` representable
 
 error: aborting due to 2 previous errors
 
index 72bf372e561d6e2004038b96c1deb1e5e4ca7218..b98a6eac49e044ac6ac5066d4c9eb3e2070ce823 100644 (file)
@@ -5,9 +5,16 @@ LL | struct T1 {
    | ^^^^^^^^^ recursive type has infinite size
 LL |     foo: isize,
 LL |     foolish: T1
-   |     ----------- recursive without indirection
+   |              -- recursive without indirection
    |
-   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `T1` representable
+help: insert some indirection to make `T1` representable
+   |
+LL |     foolish: Box<T1>
+   |              ^^^^  ^
+LL |     foolish: Rc<T1>
+   |              ^^^  ^
+LL |     foolish: &T1
+   |              ^
 
 error: aborting due to previous error
 
index 746c1033ea34843b13039049891f4768dc02ddd4..70863a549ad25a1b555894e7b65f57419b0bb897 100644 (file)
@@ -5,9 +5,16 @@ LL | union U {
    | ^^^^^^^ recursive type has infinite size
 LL |     a: u8,
 LL |     b: U,
-   |     ---- recursive without indirection
+   |        - recursive without indirection
    |
-   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `U` representable
+help: insert some indirection to make `U` representable
+   |
+LL |     b: Box<U>,
+   |        ^^^^ ^
+LL |     b: Rc<U>,
+   |        ^^^ ^
+LL |     b: &U,
+   |        ^
 
 error: aborting due to previous error