Skip to content

Commit c14b615

Browse files
committedJan 16, 2016
Auto merge of rust-lang#30533 - nikomatsakis:fulfillment-tree, r=aturon
This PR introduces an `ObligationForest` data structure that the fulfillment context can use to track what's going on, instead of the current flat vector. This enables a number of improvements: 1. transactional support, at least for pushing new obligations 2. remove the "errors will be reported" hack -- instead, we only add types to the global cache once their entire subtree has been proven safe. Before, we never knew when this point was reached because we didn't track the subtree. - this in turn allows us to limit coinductive reasoning to structural traits, which sidesteps rust-lang#29859 3. keeping the backtrace should allow for an improved error message, where we give the user full context - we can also remove chained obligation causes This PR is not 100% complete. In particular: - [x] Currently, types that embed themselves like `struct Foo { f: Foo }` give an overflow when evaluating whether `Foo: Sized`. This is not a very user-friendly error message, and this is a common beginner error. I plan to special-case this scenario, I think. - [x] I should do some perf. measurements. (Update: 2% regression.) - [x] More tests targeting rust-lang#29859 - [ ] The transactional support is not fully integrated, though that should be easy enough. - [ ] The error messages are not taking advantage of the backtrace. I'd certainly like to do 1 through 3 before landing, but 4 and 5 could come as separate PRs. r? @aturon // good way to learn more about this part of the trait system f? @arielb1 // already knows this part of the trait system :)
2 parents dda25f2 + 4fbb71f commit c14b615

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+1467
-356
lines changed
 

‎src/librustc/diagnostics.rs

+37
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,43 @@ There's no easy fix for this, generally code will need to be refactored so that
679679
you no longer need to derive from `Super<Self>`.
680680
"####,
681681

682+
E0072: r##"
683+
When defining a recursive struct or enum, any use of the type being defined
684+
from inside the definition must occur behind a pointer (like `Box` or `&`).
685+
This is because structs and enums must have a well-defined size, and without
686+
the pointer the size of the type would need to be unbounded.
687+
688+
Consider the following erroneous definition of a type for a list of bytes:
689+
690+
```
691+
// error, invalid recursive struct type
692+
struct ListNode {
693+
head: u8,
694+
tail: Option<ListNode>,
695+
}
696+
```
697+
698+
This type cannot have a well-defined size, because it needs to be arbitrarily
699+
large (since we would be able to nest `ListNode`s to any depth). Specifically,
700+
701+
```plain
702+
size of `ListNode` = 1 byte for `head`
703+
+ 1 byte for the discriminant of the `Option`
704+
+ size of `ListNode`
705+
```
706+
707+
One way to fix this is by wrapping `ListNode` in a `Box`, like so:
708+
709+
```
710+
struct ListNode {
711+
head: u8,
712+
tail: Option<Box<ListNode>>,
713+
}
714+
```
715+
716+
This works because `Box` is a pointer, so its size is well-known.
717+
"##,
718+
682719
E0109: r##"
683720
You tried to give a type parameter to a type which doesn't need it. Erroneous
684721
code example:

‎src/librustc/middle/check_const.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
125125
None => self.tcx.empty_parameter_environment()
126126
};
127127

128-
let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, Some(param_env), false);
128+
let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, Some(param_env));
129129

130130
f(&mut euv::ExprUseVisitor::new(self, &infcx))
131131
}
@@ -280,7 +280,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
280280

281281
fn check_static_type(&self, e: &hir::Expr) {
282282
let ty = self.tcx.node_id_to_type(e.id);
283-
let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, None, false);
283+
let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, None);
284284
let cause = traits::ObligationCause::new(e.span, e.id, traits::SharedStatic);
285285
let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut();
286286
fulfill_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause);

0 commit comments

Comments
 (0)