Skip to content

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

Merged
merged 3 commits into from
May 7, 2017
Merged

Conversation

estebank
Copy link
Contributor

@estebank estebank commented Mar 27, 2017

On recursive types of infinite size, point at all the fields that make
the type recursive.

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

@rust-highfive
Copy link
Contributor

r? @eddyb

(rust_highfive has picked a reviewer for you, use r? to override)

@estebank
Copy link
Contributor Author

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.

@eddyb
Copy link
Member

eddyb commented Mar 27, 2017

r? @jonathandturner

@rust-highfive rust-highfive assigned sophiajt and unassigned eddyb Mar 27, 2017
@estebank
Copy link
Contributor Author

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

@estebank estebank force-pushed the recursive branch 2 times, most recently from d426564 to 02619ec Compare March 28, 2017 03:00
@estebank
Copy link
Contributor Author

Current output:

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

@GuillaumeGomez
Copy link
Member

Wo, that's awesome!

@sophiajt
Copy link
Contributor

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.

@estebank
Copy link
Contributor Author

estebank commented Apr 2, 2017

Ping @jonathandturner.

@sophiajt
Copy link
Contributor

sophiajt commented Apr 3, 2017

@estebank - I already reviewed design, but you'll need to ping someone on the compiler team for code review. Maybe @arielb1 or @nikomatsakis

@estebank
Copy link
Contributor Author

estebank commented Apr 3, 2017

@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 :)

@arielb1
Copy link
Contributor

arielb1 commented Apr 4, 2017

I'll look at it tomorrow.

@arielb1 arielb1 self-assigned this Apr 4, 2017
@estebank
Copy link
Contributor Author

estebank commented Apr 4, 2017

@arielb1 thanks!

@arielb1
Copy link
Contributor

arielb1 commented Apr 6, 2017

Why are you walking the HIR instead of Ty information? (aka AdtDef, FieldDef)? You could rewrite is_representable to return a backtrace.

@Mark-Simulacrum Mark-Simulacrum added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Apr 14, 2017
find_nonrepresentable(tcx,
sp,
let spans = def.all_fields().map(|f| {
tcx.hir.span_if_local(f.did).unwrap_or(DUMMY_SP)
Copy link
Contributor

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_SPs? Can you use Option<Span>?

Copy link
Member

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.

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),
Copy link
Contributor

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?

Copy link
Contributor Author

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.

@arielb1
Copy link
Contributor

arielb1 commented Apr 16, 2017

Tidy error:

[00:03:37] tidy error: /checkout/src/librustc/ty/util.rs:722: line longer than 100 chars
[00:03:37] tidy error: /checkout/src/librustc/ty/util.rs:723: line longer than 100 chars

@carols10cents
Copy link
Member

Friendly ping to keep this on your radar @estebank!

@estebank
Copy link
Contributor Author

@carols10cents I'll be coming back to this, but it'll probably won't be until next weekend :-/

@arielb1
Copy link
Contributor

arielb1 commented Apr 25, 2017

Friendly ping to keep this on your radar @estebank!

@carols10cents
Copy link
Member

I just pinged this PR yesterday and estebank responded 17 hours before your ping @arielb1 :)

@sophiajt
Copy link
Contributor

sophiajt commented May 3, 2017

@estebank - any luck fixing the tidy errors on this one?

estebank added 2 commits May 4, 2017 19:11
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
@estebank estebank force-pushed the recursive branch 4 times, most recently from 349fe7c to 234c721 Compare May 6, 2017 02:10
@estebank
Copy link
Contributor Author

estebank commented May 6, 2017

Updated.

@Mark-Simulacrum Mark-Simulacrum added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels May 7, 2017
@arielb1
Copy link
Contributor

arielb1 commented May 7, 2017

That's perfect.

@bors r+

@bors
Copy link
Collaborator

bors commented May 7, 2017

📌 Commit a4fc925 has been approved by arielb1

@bors
Copy link
Collaborator

bors commented May 7, 2017

⌛ Testing commit a4fc925 with merge a478e46...

bors added a commit that referenced this pull request May 7, 2017
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
```
@bors
Copy link
Collaborator

bors commented May 7, 2017

☀️ Test successful - status-appveyor, status-travis
Approved by: arielb1
Pushing a478e46 to master...

@bors bors merged commit a4fc925 into rust-lang:master May 7, 2017
@estebank estebank deleted the recursive branch November 9, 2023 05:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants