Skip to content

make MIR type checker handle a number of other cases #46582

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 22 commits into from
Dec 14, 2017

Conversation

nikomatsakis
Copy link
Contributor

The existing type checker was primarily used to verify types, but was skipping over a number of details. For example, it was not checking that the predicates on functions were satisfied and so forth. This meant that the NLL region checker was not getting a lot of the constraints it needed. This PR closes those gaps. It also includes a bit of refactoring for the way that we store region values, encapsulating the bit matrix over into its own module and improving the data structures in use.

This is mostly work by @spastorino being ported over from nll-master.

r? @arielb1 or @pnkfelix

@kennytm kennytm added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Dec 8, 2017
@bors
Copy link
Collaborator

bors commented Dec 11, 2017

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

@nikomatsakis nikomatsakis force-pushed the nll-master-to-rust-master-4 branch from 2a0d380 to 3cf58dc Compare December 11, 2017 15:34
Copy link
Contributor

@arielb1 arielb1 left a comment

Choose a reason for hiding this comment

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

see comments. Nice PR otherwise.

@@ -1746,6 +1746,27 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}))
}

/// Create an unsafe fn ty based on a safe fn ty.
Copy link
Contributor

Choose a reason for hiding this comment

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

bad comment (talks about "unsafe fn ty" but takes a closure signature).

result.push_str("}");

result
inferred_values.region_value_str(r)
}

/// Indicates that the region variable `v` is live at the point `point`.
Copy link
Contributor

Choose a reason for hiding this comment

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

I would prefer more documentation about the sense of the boolean - e.g. "returns true if the region had changed"

@@ -493,7 +493,27 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> {
substs.substs
Copy link
Contributor

Choose a reason for hiding this comment

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

A comment describing what this function and defining_ty do would be welcome

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, for the comment for TyClosure: weirdly enough, closure substs don't contain any extra regions, so identity_substs.regions().count() should be the same as substs.substs.regions().count().

// types. What is the best way to handle this? Should we
// be checking something other than the type of the def-id
// to figure out what to do (e.g. the def-key?).
ty::TyUint(..) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

How does this code work with constants that don't have type uint? Doesn't it get called for them? Associated constants can have region parameters.

We might want to add the free region information to the MIR or to a query on the def id (computed by typeck::collect).

But sure, constants should have no inputs and 1 output.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It ICEs. I have later patches that do better.

@@ -171,7 +174,42 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
);

let expected_ty = match constant.literal {
Literal::Value { value } => value.ty,
Literal::Value { value } => {
if let ConstVal::Function(def_id, ..) = value.val {
Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah this is really the wrong way to go around doing things - we should be having the region relations from the unevaluated constant type, especially if it is an associated constant. value.val is already "too cooked".


let ty_fn_ptr_from = tcx.mk_fn_ptr(fn_sig);

if let Err(terr) = self.eq_types(ty_fn_ptr_from, ty, location.at_self()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think typeck allows some sort of (e.g. higher-ranked) subtyping here, so you'll need to allow it too.

e.g.

// this sig contains a binder
fn foo<'a>(_x: &'a ()) {}
fn bar<'b>() {
    foo as fn(&'b ()); // ... but this doesn't
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, that code type-checks. Perhaps because I haven't addressed previous comment yet.

// During NLL region analysis, this will get renumbered to `typeof(foo::<'?0>)`
// where `'?0` is a new region variable.
//
// (Note that if `'a` on `foo` were early-bound, the type would be
Copy link
Contributor

Choose a reason for hiding this comment

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

... but 'a is early-bound. Did you mean late-bound?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did mean late-bound -- if it were late-bound, it wouldn't be part of the type of foo

@nikomatsakis
Copy link
Contributor Author

OK @arielb1 pushed some comments to address those.

@nikomatsakis nikomatsakis force-pushed the nll-master-to-rust-master-4 branch 2 times, most recently from b192e0a to 2d853aa Compare December 13, 2017 11:22
@nikomatsakis
Copy link
Contributor Author

rebased, fixed a few minor things relating to changes in the underlying borrowck leading to slightly different errors, but I kept the separate commits in place

@arielb1
Copy link
Contributor

arielb1 commented Dec 13, 2017

Error message needs fixing:

[00:59:35] 
[00:59:35] ---- [compile-fail] compile-fail/nll/where_clauses_in_repeat_rvalue.rs stdout ----
[00:59:35] 	
[00:59:35] error: /checkout/src/test/compile-fail/nll/where_clauses_in_repeat_rvalue.rs:30: unexpected error: '30:17: 30:19: `x` does not live long enough [E0597]'
[00:59:35] 
[00:59:35] error: /checkout/src/test/compile-fail/nll/where_clauses_in_repeat_rvalue.rs:38: expected error not found: borrowed value does not live long enough [E0597]
[00:59:35] 
[00:59:35] error: 1 unexpected errors found, 1 expected errors not found
[00:59:35] status: exit code: 101
[00:59:35] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/compile-fail/nll/where_clauses_in_repeat_rvalue.rs" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/nll/where_clauses_in_repeat_rvalue.stage2-x86_64-unknown-linux-gnu" "-Crpath" "-O" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-Z" "borrowck=mir" "-Z" "nll" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/nll/where_clauses_in_repeat_rvalue.stage2-x86_64-unknown-linux-gnu.aux" "-A" "unused"
[00:59:35] unexpected errors (from JSON output): [
[00:59:35]     Error {
[00:59:35]         line_num: 30,
[00:59:35]         kind: Some(
[00:59:35]             Error
[00:59:35]         ),
[00:59:35]         msg: "30:17: 30:19: `x` does not live long enough [E0597]"
[00:59:35]     }
[00:59:35] ]
[00:59:35] 
[00:59:35] not found errors (from test file): [
[00:59:35]     Error {
[00:59:35]         line_num: 38,
[00:59:35]         kind: Some(
[00:59:35]             Error
[00:59:35]         ),
[00:59:35]         msg: "borrowed value does not live long enough [E0597]"
[00:59:35]     }
[00:59:35] ]
[00:59:35] 
[00:59:35] thread '[compile-fail] compile-fail/nll/where_clauses_in_repeat_rvalue.rs' panicked at 'explicit panic', /checkout/src/tools/compiletest/src/runtest.rs:1163:12
[00:59:35] 
[00:59:35] 
[00:59:35] failures:
[00:59:35]     [compile-fail] compile-fail/nll/where_clauses_in_repeat_rvalue.rs
[00:59:35] 
[00:59:35] test result: �[31mFAILED�(B�[m. 2698 passed; 1 failed; 15 ignored; 0 measured; 0 filtered out
[00:59:35] 

These tests had FIXMEs for errors that were not previously being
reported.
Converting a `RegionElementIndex` to a `Location` is O(n) though could
trivially be O(log n), but we don't do it that much anyhow -- just on
error and debugging.
@nikomatsakis nikomatsakis force-pushed the nll-master-to-rust-master-4 branch from 2d853aa to 237dd41 Compare December 13, 2017 17:25
@nikomatsakis
Copy link
Contributor Author

@arielb1 pushed an update to that error msg...let's see what travis thinks

@arielb1
Copy link
Contributor

arielb1 commented Dec 13, 2017

@bors r+

@bors
Copy link
Collaborator

bors commented Dec 13, 2017

📌 Commit 237dd41 has been approved by arielb1

@bors
Copy link
Collaborator

bors commented Dec 13, 2017

🌲 The tree is currently closed for pull requests below priority 2, this pull request will be tested once the tree is reopened

@arielb1 arielb1 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 13, 2017
@bors
Copy link
Collaborator

bors commented Dec 14, 2017

⌛ Testing commit 237dd41 with merge f03e067...

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

make MIR type checker handle a number of other cases

The existing type checker was primarily used to verify types, but was skipping over a number of details. For example, it was not checking that the predicates on functions were satisfied and so forth. This meant that the NLL region checker was not getting a lot of the constraints it needed. This PR closes those gaps. It also includes a bit of refactoring for the way that we store region values, encapsulating the bit matrix over into its own module and improving the data structures in use.

This is mostly work by @spastorino being ported over from nll-master.

r? @arielb1 or @pnkfelix
@bors
Copy link
Collaborator

bors commented Dec 14, 2017

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

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