diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2017-08-23 18:56:19 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2017-08-23 18:56:19 -0400 |
| commit | 373e909d07344f18b6e8ce443d4a4c484afc5c92 (patch) | |
| tree | 6905b6e1982187af5b93931c726ee45159805af3 | |
| parent | 94703ce3f7de97c8e8aa1fdda92724bea38dce28 (diff) | |
| download | rust-373e909d07344f18b6e8ce443d4a4c484afc5c92.tar.gz rust-373e909d07344f18b6e8ce443d4a4c484afc5c92.zip | |
add a comment
| -rw-r--r-- | src/librustc/ty/wf.rs | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index bd9eb12ee03..4d5f9e8f51c 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -114,6 +114,29 @@ struct WfPredicates<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { out: Vec<traits::PredicateObligation<'tcx>>, } +/// Controls whether we "elaborate" supertraits and so forth on the WF +/// predicates. This is a kind of hack to address #43784. The +/// underlying problem in that issue was a trait structure like: +/// +/// ``` +/// trait Foo: Copy { } +/// trait Bar: Foo { } +/// impl<T: Bar> Foo for T { } +/// impl<T> Bar for T { } +/// ``` +/// +/// Here, in the `Foo` impl, we will check that `T: Copy` holds -- but +/// we decide that this is true because `T: Bar` is in the +/// where-clauses (and we can elaborate that to include `T: +/// Copy`). This wouldn't be a problem, except that when we check the +/// `Bar` impl, we decide that `T: Foo` must hold because of the `Foo` +/// impl. And so nowhere did we check that `T: Copy` holds! +/// +/// To resolve this, we elaborate the WF requirements that must be +/// proven when checking impls. This means that (e.g.) the `impl Bar +/// for T` will be forced to prove not only that `T: Foo` but also `T: +/// Copy` (which it won't be able to do, because there is no `Copy` +/// impl for `T`). #[derive(Debug, PartialEq, Eq, Copy, Clone)] enum Elaborate { All, |
