-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Point at fields that make the type recursive #40857
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
r? @eddyb (rust_highfive has picked a reviewer for you, use r? to override) |
Needs code clean up and differentiating between fields that have indirections and the ones that don't have indirection (and are therefore the culprit for the error), but I finally got it working last night so I'm putting it out there as an RFC on the approach and copy of the messages. CC @jonathandturner, @GuillaumeGomez, @nagisa, @nikomatsakis. |
One of the things I want to confirm is on the following: +error[E0072]: recursive type `Foo` has infinite size
+ --> $DIR/recursive-type-field.rs:13:1
+ |
+13 | struct Foo<'a> {
+ | _^ starting here...
+14 | | bar: Bar<'a>,
+ | | ------------ recursive without indirection
+15 | | b: Rc<Bar<'a>>,
+ | | -------------- SHOULD WE MARK THAT IT IS RECURSIVE HERE, EVEN THOUGH IT IS NOT PART OF THE PROBLEM?
+16 | | }
+ | |_^ ...ending here: recursive type has infinite size
+ |
+ = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Foo` representable |
d426564
to
02619ec
Compare
error[E0072]: recursive type `Bar` has infinite size
--> $DIR/recursive-type-field.rs:18:1
|
18 | struct Bar<'a> {
| _^ starting here...
19 | | y: (Foo<'a>, Foo<'a>),
| | --------------------- recursive without indirection
20 | | z: Option<Bar<'a>>,
21 | | a: &'a Foo<'a>,
22 | | c: &'a [Bar<'a>],
23 | | d: [Bar<'a>; 1],
| | --------------- recursive without indirection
24 | | e: Foo<'a>,
| | ---------- recursive without indirection
25 | | x: Bar<'a>,
| | ---------- recursive without indirection
26 | | }
| |_^ ...ending here: recursive type has infinite size
|
= help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Bar` representable |
Wo, that's awesome! |
I like the idea, that's very cool. Ideally, we only mark the areas that are part of the problem. I can't speak to the code, but the design of the error I think is good. |
Ping @jonathandturner. |
@estebank - I already reviewed design, but you'll need to ping someone on the compiler team for code review. Maybe @arielb1 or @nikomatsakis |
@jonathandturner sorry, as you were set as reviewer I assumed that you'd come back later to review the code. Rereading what you wrote you said exactly what you meant to say :) |
I'll look at it tomorrow. |
@arielb1 thanks! |
Why are you walking the HIR instead of |
src/librustc/ty/util.rs
Outdated
find_nonrepresentable(tcx, | ||
sp, | ||
let spans = def.all_fields().map(|f| { | ||
tcx.hir.span_if_local(f.did).unwrap_or(DUMMY_SP) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need the DUMMY_SP
s? Can you use Option<Span>
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO we should stop using span_if_local
because tcx.def_span(f.did)
works but we still need a solution for printing cross-crate spans - and I can't find the issue for it.
src/librustc/ty/util.rs
Outdated
seen, | ||
def.all_fields().map(|f| f.ty(tcx, substs))) | ||
def.all_fields().map(|f| (f.ty(tcx, substs), tcx.hir.span_if_local(f.did).unwrap_or(DUMMY_SP)))) { | ||
Representability::SelfRecursive(_) => Representability::SelfRecursive(spans), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't this destroy the info on what is the appropriate field?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, the last commit is mostly me trying to modify the logic here as little as possible while adding spans. It seems to me that I'll have to take some time to rewrite this to properly keep a stack.
Tidy error:
|
Friendly ping to keep this on your radar @estebank! |
@carols10cents I'll be coming back to this, but it'll probably won't be until next weekend :-/ |
Friendly ping to keep this on your radar @estebank! |
I just pinged this PR yesterday and estebank responded 17 hours before your ping @arielb1 :) |
@estebank - any luck fixing the tidy errors on this one? |
On recursive types of infinite size, point at all the fields that make the type recursive. ```rust struct Foo { bar: Bar, } struct Bar { foo: Foo, } ``` outputs ``` error[E0072]: recursive type `Foo` has infinite size --> file.rs:1:1 1 | struct Foo { | _^ starting here... 2 | | bar: Bar, | | -------- recursive here 3 | | } | |_^ ...ending here: recursive type has infinite size | = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Foo` representable error[E0072]: recursive type `Bar` has infinite size --> file.rs:5:1 | 5 | struct Bar { | _^ starting here... 6 | | foo: Foo, | | -------- recursive here 7 | | } | |_^ ...ending here: recursive type has infinite size | = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Bar` representable ```
* clean up code * point only fields that cause the type to be of infinite size * fix unittests
349fe7c
to
234c721
Compare
Updated. |
That's perfect. @bors r+ |
📌 Commit a4fc925 has been approved by |
Point at fields that make the type recursive On recursive types of infinite size, point at all the fields that make the type recursive. ```rust struct Foo { bar: Bar, } struct Bar { foo: Foo, } ``` outputs ``` error[E0072]: recursive type `Foo` has infinite size --> file.rs:1:1 1 | struct Foo { | ^^^^^^^^^^ recursive type has infinite size 2 | bar: Bar, | -------- recursive here | = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Foo` representable error[E0072]: recursive type `Bar` has infinite size --> file.rs:5:1 | 5 | struct Bar { | ^^^^^^^^^^ recursive type has infinite size 6 | foo: Foo, | -------- recursive here | = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Bar` representable ```
☀️ Test successful - status-appveyor, status-travis |
On recursive types of infinite size, point at all the fields that make
the type recursive.
outputs