Repository navigation
Tracking issue for RFC 2093: Infer T: 'x outlives requirements on structs #44493
Description
Activity
- addedB-RFC-approvedBlocker: Approved by a merged RFC but not yet implemented.Blocker: Approved by a merged RFC but not yet implemented.T-langRelevant to the language teamRelevant to the language team
on Sep 11, 2017 - addedT-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.and removed
on Sep 15, 2017 - addedC-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 RFC
on Sep 17, 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:predicates_of(D) = explicit_predicates_of(D) + inferred_outlives_of(D)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:
- Check
predicates_ofto be implemented in terms of a subsidiary predicateexplicit_predicates_of. - Introduce
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. - Implement the predicate inference, fix the test, add more tests.
- addedE-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.and removed
on Sep 18, 2017 I would like to work on this!
@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
visiting for triage. PR #53793 is meant to resolve this.
- added a commit that references this issue
on Sep 12, 2018 visiting for triage. #53793 landed. closing as fixed.
Created #54185 to track the
'staticquestion#52042 already exists to track an idiom lint
- added a commit that references this issue
on Sep 28, 2018 - added a commit that references this issue
on Feb 24, 2019 #54185 (comment) ended the question about whether to special-case
'static; PR #97875 removed#![feature(infer_static_outlives_requirements)].Reacted by QuineDot- added a commit that references this issue
on Aug 29, 2024 - added a commit that references this issue
on May 12, 2026
This is a tracking issue for the RFC "Infer
T: 'xoutlives 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:
Unresolved questions:
The interaction with
'staticremains a bit unclear. For example, do we want to infer aT: 'staticrequirement on the type parameterThere? The code currently will do so, arguably leading to confusing errors.