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

There is no variance to infer for generics that occur in non-variance contexts #13261

Merged
merged 5 commits into from
Apr 17, 2014

Conversation

pnkfelix
Copy link
Member

@pnkfelix pnkfelix commented Apr 2, 2014

Fix #12856.

I wanted to put this up first because I wanted to get feedback about the second commit in the series, commit 8599236. Its the more invasive part of the patch and is largely just belt-and-suspenders assertion checking; in the commit message I mentioned at least one other approach we could take here. Or we could drop the belt-and-suspenders and just rely on the guard added in the first patch, commit 8d6a005 (which is really quite trivial on its own).

So any feedback on what would be better is appreciated.

r? @nikomatsakis

@pnkfelix
Copy link
Member Author

pnkfelix commented Apr 7, 2014

The more I reflect on sha 8599236 , the more I think I should explore the alternative approach I outlined in the commit message (i.e., the ty::Region type should carry info about whether it is a parameter on a generic type, or on a generic function/method). Will look into that.

@nikomatsakis nikomatsakis self-assigned this Apr 7, 2014
kind: ParamKind,
index: uint,
param_id: ast::NodeId)
{
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: not that I care, but I think our official coding standards moves such braces to the previous line.

@nikomatsakis
Copy link
Contributor

Ultimately I agree with everything you wrote @pnkfelix. This seems like a good sanity check. It might be better to only enable it if assertions are enabled. It might be better still to just have a way to go from the def-id of a region parameter (in this case, the early bound parameter) to the item that declared it, which is really all you're trying to infer here. I'm not actually sure if such a thing exists, the usual thing would be to add it to the ast-map I guess.

@pnkfelix
Copy link
Member Author

r? @nikomatsakis

feedback? @eddyb (especially regarding commit dc37ba3 )

@eddyb
Copy link
Member

eddyb commented Apr 11, 2014

LGTM logic-wise, at least.
I prefer to keep folding within a structure literal - see the changes to folding in #13316, that feels cleaner to me than some of the current folding code.

@nikomatsakis
Copy link
Contributor

When did we gain an invariant about when the "new_id" is called? Was it always like that and I didn't realize?

@nikomatsakis
Copy link
Contributor

@pnkfelix this looks pretty good. My inclination would be to have the canonical path be checking the inferred map, and have the ast path you wrote out be an assertion, but I'm really just micro-optimizing here.

@nikomatsakis
Copy link
Contributor

(r+ once merge conflicts are fixed -- but considering making the inferred map be the normal path)

Before adding a variance constrant for a given early-bound param,
check if it was meant to be inferred.

To support the above, added `fn is_to_be_inferred` to
`variance::ConstraintContext`.
@pnkfelix
Copy link
Member Author

@nikomatsakis I believe the invariant about when new_id is called was injected by commit a02b10a (since that was what introduced the pattern of setting the Ctx's parent on calls to new_id), and also was when the comments noting the invariant first appeared in fold.rs

Part of this required added an override of `fold_type_method` in the
Folder for Ctx impl; it follows the same pattern as `fold_method`.

Also, as a drive-by fix, I moved all of the calls to `folder.new_id`
in syntax::fold's no-op default traversal to really be the first
statement in each function.

  * This is to uphold the invariant that `folder.new_id` is always
    called first (an unfortunate requirement of the current `ast_map`
    code), an invariant that we seemingly were breaking in e.g. the
    previous `noop_fold_block`.

  * Now it should be easier to see when adding new code that this
    invariant must be upheld.

  * (note that the breakage in `noop_fold_block` may not have mattered
    so much previously, since the only thing that blocks can bind are
    lifetimes, which I am only adding support for now.)
This version of `is_to_be_inferred` double-checks the result from
`inferred_map` by querying the `named_region_map` and `ast_map` and
then asserts that the `inferred_map` state is consistent with its own
findings.  (See issue 13261 for further discussion of the approaches).
@pnkfelix
Copy link
Member Author

(I'm going to treat the question from @nikomatsakis about when the invariant was introduced as evidence that I am correct to attempt to make the invariant more apparent in the code.)

@pnkfelix pnkfelix changed the title Cannot infer variance for generics that occur in non-variance contexts Do not infer variance for generics that occur in non-variance contexts Apr 17, 2014
@pnkfelix pnkfelix changed the title Do not infer variance for generics that occur in non-variance contexts There is no variance to infer for generics that occur in non-variance contexts Apr 17, 2014
bors added a commit that referenced this pull request Apr 17, 2014
Fix #12856.

I wanted to put this up first because I wanted to get feedback about the second commit in the series, commit 8599236.  Its the more invasive part of the patch and is largely just belt-and-suspenders assertion checking; in the commit message I mentioned at least one other approach we could take here.  Or we could drop the belt-and-suspenders and just rely on the guard added in the first patch, commit 8d6a005 (which is really quite trivial on its own).

So any feedback on what would be better is appreciated.

r? @nikomatsakis
@bors bors merged commit 3099451 into rust-lang:master Apr 17, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ICE on trait method with type parameter bounded by trait with lifetime parameter
4 participants