Skip to content
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

nll part 5 #46733

Merged
merged 25 commits into from
Dec 20, 2017
Merged

nll part 5 #46733

merged 25 commits into from
Dec 20, 2017

Conversation

nikomatsakis
Copy link
Contributor

Next round of changes from the nll-master branch.

Extensions:

  • we now propagate ty-region-outlives constraints out of closures and into their creator when necessary
  • we fix a few ICEs that can occur by doing liveness analysis (and the resulting normalization) during type-checking
  • we handle the implicit region bound that assumes that each type T outlives the fn body
  • we handle normalization of inputs/outputs in fn signatures

Not included in this PR (will come next):

  • handling impl Trait
  • tracking causal information
  • extended errors

r? @arielb1

@bors
Copy link
Contributor

bors commented Dec 15, 2017

☔ The latest upstream changes (presumably #46537) made this pull request unmergeable. Please resolve the merge conflicts.

@kennytm kennytm added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Dec 15, 2017
Before, we would always have a `Some` ClosureRegionRequirements if we
were inferring values for a closure. Now we only do is it has a
non-empty set of outlives requirements.
This allows us to re-use the `normalize` method on `TypeCheck`, which
is important since normalization may create fresh region
variables. This is not an ideal solution, though, since the current
representation of "liveness constraints" (a vector of (region, point)
pairs) is rather inefficient. Could do somewhat better by converting
to indices, but it'd still be less good than the older code. Unclear
how important this is.
In the future, `check_type_tests` will also potentially propagate
constriants to its caller.
The existing flags did not consider `'static` to be "free". This then
fed into what was "erasable" -- but `'static` is most certainly
erasable.
Currently, we only propagate type tests that exclude all regions from
the type.
This is needed to allow the `ClosureRegionRequirements` to capture
types that include regions.
The input/output types found in `UniversalRegions` are not normalized.
The old code used to assign them directly into the MIR, which would
lead to errors when there was a projection in a argument or return
type. This also led to some special cases in the `renumber` code.

We now renumber uniformly but then pass the input/output types into
the MIR type-checker, which equates them with the types found in MIR.
This allows us to normalize at the same time.
Turns out this works but we had no test targeting it.
The prior messages were not stable across platforms.
/// checks that they meet certain extra criteria. If not, an error
/// can be issued.
///
/// One reason for this is that these type tests always boil down to a
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not quite correct - consider <&'α T as Foo>::Bar: 'x where is an inference variable. IIRC at least AST borrowck will convert this to 'α: 'x

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. When I was writing this, I thought I remembered that we always issued hard region constraints in that case (over-constrained). But I remembered later that we do not. Still not crazy about this behavior, but the right fix is a pain of course. =) (For later...)

/// Once regions have been propagated, this method is used to see
/// whether any of the constraints were too strong. In particular,
/// we want to check for a case where a universally quantified
/// region exceeded its bounds. Consider:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong comment: this code is about type tests - T: 'a - not region tests ('a: 'b).

@@ -64,12 +69,14 @@ pub struct UniversalRegions<'tcx> {
/// closure type, but for a top-level function it's the `TyFnDef`.
pub defining_ty: Ty<'tcx>,

/// The return type of this function, with all regions replaced
/// by their universal `RegionVid` equivalents.
/// The return type of this function, with all regions replaced by
Copy link
Contributor

@arielb1 arielb1 Dec 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you mean "This type contains explicit free regions" ? Nope, this means "this type might contain associated types".

/// extern. This is an important category, because these regions
/// can be referenced in `ClosureRegionRequirements`.
pub fn is_non_local_free_region(&self, r: RegionVid) -> bool {
self.region_classification(r) == Some(RegionClassification::Local)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a missing ! here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes -- but this also appears to be dead-code. I thought I remembered finding (and fixing...) this particular bug, but I can't seem to find that in my other branches now. Anyway, I will remove these bits of dead code I think.

@nikomatsakis
Copy link
Contributor Author

Pushed various commits to address the bits of feedback.

// - `'static: 'a`
// - `'static: 'b`
//
// First, let's assume that `r` is some existential
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the inferred value of a region required to be closed under the subregion relationship? I mean, semantically it is (i.e. the included value can't be 'static without including all other free regions) but this talks as if structurally it is not.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would mean an inferred value of {'a, 'static} does not make sense.

Also, we only care about the state of the inference variable right after the closure returns, so CFG nodes - which here come from within the closure, since that is what we are type-checking - are not important, because they are "in our past".

//
// Now let's consider the inferred value `{'a, 'b}`. This
// means `r` is effectively `'a | 'b`. I'm not sure if
// this can come about, actually, but assuming it did, we
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uselessly, you could have something like this:

fn foo<'a, 'b, 'c>(x: Cell<&'a u8>, y: Cell<&'b u8>) -> Option<Cell<&'c u8>>
    where 'c: 'a, 'c: 'b
{
    None
}

@arielb1
Copy link
Contributor

arielb1 commented Dec 19, 2017

So I think the hackyincomplete type propagation code is imperfect, but I can't think of anything better or of "real-world" example cases for breaking it.

Therefore,
@bors r+

@bors
Copy link
Contributor

bors commented Dec 19, 2017

📌 Commit 1816ede has been approved by arielb1

@bors
Copy link
Contributor

bors commented Dec 19, 2017

⌛ Testing commit 1816ede with merge dbe91562a03fdcab13bd1170c589d38de7442a3e...

@bors
Copy link
Contributor

bors commented Dec 19, 2017

💔 Test failed - status-travis

@nikomatsakis
Copy link
Contributor Author

nikomatsakis commented Dec 19, 2017

Huh. The failure seems to be:

[01:04:25] ---- [run-make] run-make/sanitizer-memory stdout ----
[01:04:25] 	
[01:04:25] error: make failed
[01:04:25] status: exit code: 2
[01:04:25] command: "make"
[01:04:25] stdout:
[01:04:25] ------------------------------------------
[01:04:25] LD_LIBRARY_PATH="/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make/sanitizer-memory.stage2-x86_64-unknown-linux-gnu:/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib:/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools/x86_64-unknown-linux-gnu/release/deps:/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-sysroot/lib/rustlib/x86_64-unknown-linux-gnu/lib:" '/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc' --out-dir /checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make/sanitizer-memory.stage2-x86_64-unknown-linux-gnu -L /checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make/sanitizer-memory.stage2-x86_64-unknown-linux-gnu  -g -Z sanitizer=memory -Z print-link-args uninit.rs | "/checkout/src/etc/cat-and-grep.sh" librustc_msan
[01:04:25] [[[ begin stdout ]]]
[01:04:25] �[90m"cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make/sanitizer-memory.stage2-x86_64-unknown-linux-gnu/uninit.uninit0.rcgu.o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make/sanitizer-memory.stage2-x86_64-unknown-linux-gnu/uninit.uninit1.rcgu.o" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make/sanitizer-memory.stage2-x86_64-unknown-linux-gnu/uninit" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make/sanitizer-memory.stage2-x86_64-unknown-linux-gnu/uninit.crate.allocator.rcgu.o" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make/sanitizer-memory.stage2-x86_64-unknown-linux-gnu" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-8a57f85a0ae8b781.rlib" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-d795c34fd7eb72c9.rlib" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-0f4b95d88e53e455.rlib" "-Wl,--whole-archive" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make/sanitizer-memory.stage2-x86_64-unknown-linux-gnu/rustc.CIJw1hdYBiRz/librustc_msan-fbd8d4c3523df812.rlib" "-Wl,--no-whole-archive" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc_system-6d9370e956155877.rlib" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-f874e85b0fc1f5b8.rlib" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-c7758873e5bedec1.rlib" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd_unicode-c9b8ae6d904bd621.rlib" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-c80c8268f013635d.rlib" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-6389cf691b0a8db6.rlib" "-Wl,-Bdynamic" "-l" "dl" "-l" "rt" "-l" "pthread" "-l" "pthread" "-l" "gcc_s" "-l" "c" "-l" "m" "-l" "rt" "-l" "pthread" "-l" "util" "-l" "util"
[01:04:25] �[0m
[01:04:25] [[[ end stdout ]]]
[01:04:25] /checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make/sanitizer-memory.stage2-x86_64-unknown-linux-gnu/uninit 2>&1 | "/checkout/src/etc/cat-and-grep.sh" use-of-uninitialized-value
[01:04:25] [[[ begin stdout ]]]
[01:04:25] �[90mFATAL: Code 0x0100da5aad10 is out of application range. Non-PIE build?
[01:04:25] FATAL: MemorySanitizer can not mmap the shadow memory.
[01:04:25] FATAL: Make sure to compile with -fPIE and to link with -pie.
[01:04:25] FATAL: Disabling ASLR is known to cause this error.
[01:04:25] FATAL: If running under GDB, try 'set disable-randomization off'.
[01:04:25] ==29253==Process memory map follows:
[01:04:25] 	0x0100da584000-0x0100da655000	/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make/sanitizer-memory.stage2-x86_64-unknown-linux-gnu/uninit
[01:04:25] 	0x0100da855000-0x0100da85a000	/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make/sanitizer-memory.stage2-x86_64-unknown-linux-gnu/uninit
[01:04:25] 	0x0100da85a000-0x0100da85d000	/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make/sanitizer-memory.stage2-x86_64-unknown-linux-gnu/uninit
[01:04:25] 	0x0100da85d000-0x0100dccc3000	
[01:04:25] 	0x7ffabc640000-0x7ffabc992000	
[01:04:25] 	0x7ffabc992000-0x7ffabca9a000	/lib/x86_64-linux-gnu/libm-2.23.so
[01:04:25] 	0x7ffabca9a000-0x7ffabcc99000	/lib/x86_64-linux-gnu/libm-2.23.so
[01:04:25] 	0x7ffabcc99000-0x7ffabcc9a000	/lib/x86_64-linux-gnu/libm-2.23.so
[01:04:25] 	0x7ffabcc9a000-0x7ffabcc9b000	/lib/x86_64-linux-gnu/libm-2.23.so
[01:04:25] 	0x7ffabcc9b000-0x7ffabce5b000	/lib/x86_64-linux-gnu/libc-2.23.so
[01:04:25] 	0x7ffabce5b000-0x7ffabd05b000	/lib/x86_64-linux-gnu/libc-2.23.so
[01:04:25] 	0x7ffabd05b000-0x7ffabd05f000	/lib/x86_64-linux-gnu/libc-2.23.so
[01:04:25] 	0x7ffabd05f000-0x7ffabd061000	/lib/x86_64-linux-gnu/libc-2.23.so
[01:04:25] 	0x7ffabd061000-0x7ffabd065000	
[01:04:25] 	0x7ffabd065000-0x7ffabd07b000	/lib/x86_64-linux-gnu/libgcc_s.so.1
[01:04:25] 	0x7ffabd07b000-0x7ffabd27a000	/lib/x86_64-linux-gnu/libgcc_s.so.1
[01:04:25] 	0x7ffabd27a000-0x7ffabd27b000	/lib/x86_64-linux-gnu/libgcc_s.so.1
[01:04:25] 	0x7ffabd27b000-0x7ffabd293000	/lib/x86_64-linux-gnu/libpthread-2.23.so
[01:04:25] 	0x7ffabd293000-0x7ffabd492000	/lib/x86_64-linux-gnu/libpthread-2.23.so
[01:04:25] 	0x7ffabd492000-0x7ffabd493000	/lib/x86_64-linux-gnu/libpthread-2.23.so
[01:04:25] 	0x7ffabd493000-0x7ffabd494000	/lib/x86_64-linux-gnu/libpthread-2.23.so
[01:04:25] 	0x7ffabd494000-0x7ffabd498000	
[01:04:25] 	0x7ffabd498000-0x7ffabd49f000	/lib/x86_64-linux-gnu/librt-2.23.so
[01:04:25] 	0x7ffabd49f000-0x7ffabd69e000	/lib/x86_64-linux-gnu/librt-2.23.so
[01:04:25] 	0x7ffabd69e000-0x7ffabd69f000	/lib/x86_64-linux-gnu/librt-2.23.so
[01:04:25] 	0x7ffabd69f000-0x7ffabd6a0000	/lib/x86_64-linux-gnu/librt-2.23.so
[01:04:25] 	0x7ffabd6a0000-0x7ffabd6a3000	/lib/x86_64-linux-gnu/libdl-2.23.so
[01:04:25] 	0x7ffabd6a3000-0x7ffabd8a2000	/lib/x86_64-linux-gnu/libdl-2.23.so
[01:04:25] 	0x7ffabd8a2000-0x7ffabd8a3000	/lib/x86_64-linux-gnu/libdl-2.23.so
[01:04:25] 	0x7ffabd8a3000-0x7ffabd8a4000	/lib/x86_64-linux-gnu/libdl-2.23.so
[01:04:25] 	0x7ffabd8a4000-0x7ffabd8ca000	/lib/x86_64-linux-gnu/ld-2.23.so
[01:04:25] 	0x7ffabdab6000-0x7ffabdac7000	
[01:04:25] 	0x7ffabdac7000-0x7ffabdac9000	
[01:04:25] 	0x7ffabdac9000-0x7ffabdaca000	/lib/x86_64-linux-gnu/ld-2.23.so
[01:04:25] 	0x7ffabdaca000-0x7ffabdacb000	/lib/x86_64-linux-gnu/ld-2.23.so
[01:04:25] 	0x7ffabdacb000-0x7ffabdacc000	
[01:04:25] 	0x7fffbed67000-0x7fffbed89000	[stack]
[01:04:25] 	0x7fffbeda7000-0x7fffbeda9000	[vvar]
[01:04:25] 	0x7fffbeda9000-0x7fffbedab000	[vdso]
[01:04:25] 	0xffffffffff600000-0xffffffffff601000	[vsyscall]
[01:04:25] ==29253==End of process memory map.
[01:04:25] �[0m
[01:04:25] [[[ end stdout ]]]
[01:04:25] �[1;31mError: cannot match: use-of-uninitialized-value�[0m
[01:04:25] Makefile:6: recipe for target 'all' failed
[01:04:25] 
[01:04:25] ------------------------------------------
[01:04:25] stderr:
[01:04:25] ------------------------------------------
[01:04:25] warning: unused variable: `y`
[01:04:25]   --> uninit.rs:15:9
[01:04:25]    |
[01:04:25] 15 |     let y = xs[0] + xs[1];
[01:04:25]    |         ^
[01:04:25]    |
[01:04:25]    = note: #[warn(unused_variables)] on by default
[01:04:25]    = note: to avoid this warning, consider using `_y` instead
[01:04:25] 
[01:04:25] make: *** [all] Error 1
[01:04:25] 
[01:04:25] ------------------------------------------
[01:04:25] 
[01:04:25] thread '[run-make] run-make/sanitizer-memory' panicked at 'explicit panic', /checkout/src/tools/compiletest/src/runtest.rs:2776:8
[01:04:25] note: Run with `RUST_BACKTRACE=1` for a backtrace.
[01:04:25] 
[01:04:25] 
[01:04:25] failures:
[01:04:25]     [run-make] run-make/sanitizer-memory
[01:04:25] 
[01:04:25] test result: �[31mFAILED�(B�[m. 167 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out

@nikomatsakis
Copy link
Contributor Author

@bors retry


cc #46313

@kennytm kennytm added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 19, 2017
@nikomatsakis
Copy link
Contributor Author

@bors p=1 -- NLL is super high priority

@bors
Copy link
Contributor

bors commented Dec 19, 2017

⌛ Testing commit 1816ede with merge 46833922ac11fdcf82ca4c31ac0948a819783dcd...

@bors
Copy link
Contributor

bors commented Dec 20, 2017

💔 Test failed - status-appveyor

@nikomatsakis
Copy link
Contributor Author

cc @rust-lang/infra -- I can't quite tell why the appveyor failed, but the log seems to mysteriously stop at 2 hour 58 minutes. Is there a 3h timeout? Is there a possibility that this is within standard variation? (Or perhaps the PR adds new tests or otherwise slows things down?)

@alexcrichton
Copy link
Member

@bors: retry

Yeah we've got a 3 hour time limit on AppVeyor, sometimes it just seems to randomly slow down. Let's see if it happens again.

@bors
Copy link
Contributor

bors commented Dec 20, 2017

⌛ Testing commit 1816ede with merge 588f7db...

bors added a commit that referenced this pull request Dec 20, 2017
…ielb1

nll part 5

Next round of changes from the nll-master branch.

Extensions:

- we now propagate ty-region-outlives constraints out of closures and into their creator when necessary
- we fix a few ICEs that can occur by doing liveness analysis (and the resulting normalization) during type-checking
- we handle the implicit region bound that assumes that each type `T` outlives the fn body
- we handle normalization of inputs/outputs in fn signatures

Not included in this PR (will come next):

- handling `impl Trait`
- tracking causal information
- extended errors

r? @arielb1
@bors
Copy link
Contributor

bors commented Dec 20, 2017

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

@bors bors merged commit 1816ede into rust-lang:master Dec 20, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants