Repository navigation
Closed
Labels
B-RFC-approvedBlocker: Approved by a merged RFC but not yet implemented.Blocker: Approved by a merged RFC but not yet implemented.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFCE-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.E-mentorCall for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.P-highHigh priorityHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamRelevant to the language teamdisposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.This issue / PR is in PFCP or FCP with a disposition to merge it.finished-final-comment-periodThe final comment period is finished for this PR / Issue.The final comment period is finished for this PR / Issue.
Milestone
Description
This is a tracking issue for the RFC "Infer T: 'x outlives requirements on structs " (rust-lang/rfcs#2093).
Current status:
Implemented and we have decided to stabilize. We still need someone to make the stabilization PR! Mentoring instructions here:
https://github.com/rust-lang/rust/issue_comments#issuecomment-411781121
Until then, you can use this by adding #![feature(infer_outlives_requirements)] to your crate.
Steps:
- Implement the RFC (mentoring instructions here)
- Adjust documentation (see instructions on forge)
- Stabilization PR (see instructions on forge)
Unresolved questions:
The interaction with 'static remains a bit unclear. For example, do we want to infer a T: 'static requirement on the type parameter T here? The code currently will do so, arguably leading to confusing errors.
#![feature(infer_outlives_requirements)]
struct Foo<T> { t: &'static T }
fn main() {
let x = 3;
let _ = Foo { t: &x };
}Reacted by MSxDOS and Brandon H. Gomes
Reacted by Kornel and runiq
Metadata
Metadata
Assignees
Labels
B-RFC-approvedBlocker: Approved by a merged RFC but not yet implemented.Blocker: Approved by a merged RFC but not yet implemented.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFCE-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.E-mentorCall for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.P-highHigh priorityHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamRelevant to the language teamdisposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.This issue / PR is in PFCP or FCP with a disposition to merge it.finished-final-comment-periodThe final comment period is finished for this PR / Issue.The final comment period is finished for this PR / Issue.
Activity
nikomatsakis commentedon Sep 18, 2017
Mentoring instructions
In the compiler, when we want to know what predicates are defined on something (e.g., a struct), we do that via the
predicates_ofquery. Right now, this is implemented by this code inlibrusc_typeck. This code basically reads the HIR and produces exactly the results found there.In terms of how to fit this inference into the compiler pipeline, then, I think we want to ensure that
predicates_ofincludes these inferred predicates. To do that, we can redefinepredicates_ofin terms of two new queries,explicit_predicates_ofandinferred_outlives_of-- basically,predicates_ofwould be the union of the two:explicit_predicates_ofwould be exactly the same aspredicates_ofis today (and only defined for local crates). It just returns the predicates the user typed.inferred_outlives_of, in contrast, will include the predicates that we are going to infer.The very first PR, then, could be to introduce the
explicit_predicates_ofquery and to makepredicates_ofjust redirect to it (later, we will addinferred_outlives_of). This makes sense because we're going to needexplicit_predicates_ofwhen defininginferred_outlives_of.Now we have to figure out how to implemented
inferred_outlives_of. I think the basic structure here is going to be similar to how variance inference is setup. In terms of queries, variance inference is defined by two queries:crate_variances-- returns a map containing the variance for every item in the cratevariances_of-- just selects an item of this map.The
crate_variancesquery is intended as an implementation detail of variance -- end-users should usevariances_offor a particular item.The reason for this particular setup is that we can't infer the variances for a single item in isolation; the variance for an item X depends on the contents of the struct, and there may be cycles. Since cycles are generally forbidden between queries, we instead compute the variances for ALL structs in the crate, and then use individual queries to extract the result.
So, for
inferred_outlives_of, we will basically create a new query, probably living alongsidevarianceinlibrustc_typeck, let's call itinferred_outlives_of. This query will defer to a crate-wide queryinferred_outlives_crate(we should probably have namedcrate_variancesasvariances_crate...). Since we only infer predicates for struts,inferred_outlives_ofcan just return the empty set for any def-id that is not a struct.This crate-wide computation will work much as it is described in the RFC -- there will be a set of constraints being inferred for each struct
S, what the RFC callsA[S]. These sets will be sets ofPredicate<'tcx>values. We will initialize them by filtering theexplicit_predicates_ofeach struct to only include those of typeTypeOutlivesorRegionOutlives.Next, we can walk the types of the fields declared in each struct. These can be obtained by invoking
type_of(def_id)wheredef_idis theDefIdof the struct. This should give back a type of theTyAdtvariant; from this, you can extract the types of the fields. Something like this code from variance should give you the idea. For each field that references another structS2, we need to create a link between those types and ensure that their implied predicates are a superset.Once this is done, we should have some kind of inferred set of obligations for each struct. I think it'd be good to setup a unit-testing mechanism for this similar to the one we use for variance. Basically, some custom code that looks for a
#[rustc_inferred_outlives]annotation and, when found, dumps out a "compilation error" that includes the results. This lets us write unit tests like this one, where we just check the result of this query.So, in terms of first steps, these are good PRs to open:
predicates_ofto be implemented in terms of a subsidiary predicateexplicit_predicates_of.inferred_outlivespredicate and unit-testing mechanism. Initially, the predicate can always return an empty set of predicates, but we can add some tests nonetheless; they'll just initially show an empty result for the predicate.toidiu commentedon Sep 19, 2017
I would like to work on this!
nikomatsakis commentedon Sep 25, 2017
@toidiu hey, just checking in! I just r+'d that first PR, wondering if you'd had any time to mess around with the next few steps?
72 remaining items
pnkfelix commentedon Aug 30, 2018
visiting for triage. PR #53793 is meant to resolve this.
Auto merge of #53793 - toidiu:ak-stabalize, r=nikomatsakis
pnkfelix commentedon Sep 13, 2018
visiting for triage. #53793 landed. closing as fixed.
nikomatsakis commentedon Sep 13, 2018
Created #54185 to track the
'staticquestionnikomatsakis commentedon Sep 13, 2018
#52042 already exists to track an idiom lint
in which inferable outlives-requirements are linted
Replace `T: 'a + Messenger` with `T: Messenger`
pnkfelix commentedon Aug 2, 2022
#54185 (comment) ended the question about whether to special-case
'static; PR #97875 removed#![feature(infer_static_outlives_requirements)].Auto merge of #53793 - toidiu:ak-stabalize, r=nikomatsakis
use infer_outlives_requirements feature