diff options
| author | 许杰友 Jieyou Xu (Joe) <39484203+jieyouxu@users.noreply.github.com> | 2024-12-27 20:44:13 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-12-27 20:44:13 +0800 |
| commit | 72ef16f519c1787faa7d7d46a6608c4c27ea8976 (patch) | |
| tree | 96c5e486b4d9eab93f0a56b8cf4f87e02fbd4832 /compiler/rustc_middle/src | |
| parent | bc3e8917e3723928180c4a11faa19ccb29043bf5 (diff) | |
| parent | 454c09e355e0122fceaa770a3903c0ec9547bc0a (diff) | |
| download | rust-72ef16f519c1787faa7d7d46a6608c4c27ea8976.tar.gz rust-72ef16f519c1787faa7d7d46a6608c4c27ea8976.zip | |
Rollup merge of #134787 - fmease:spruce-up-queries, r=compiler-errors
Spruce up the docs of several queries related to the type/trait system and const eval
- Editorial
- Proper rustdoc summary/synopsis line by making use of extra paragraphs: Leads to better rendered output on module pages, in search result lists and overall, too
- Use rustdoc warning blocks for admonitions of the form "do not call / avoid calling this query directly"
- Use intra-doc links of the form ``[`Self::$query`]`` to cross-link queries. Indeed, such links are generally a bit brittle due to the existence of `TyCtxtFeed` which only contains a subset of queries. Therefore the docs of `feedable` queries cannot cross-link to non-`feedable` ones. I'd say it's fine to use intra-doc links despite the potential/unlikely occasional future breakage (if a query with the aforementioned characteristics becomes `feedable`). `Self::` is nicer than `TyCtxt::` (which would be more stable) since it accounts for other contexts like `TyCtxt{Feed,At,Ensure{,WithValue}}`
- Informative
- Generally add, flesh out and correct some doc comments
- Add *Panic* sections (to a few selected queries only). The lists of panics aren't necessarily exhaustive and focus on the more "obvious" or "important" panics.
- Where applicable add a paragraph calling attention to the relevant [`#[rustc_*]` TEST attribute](https://rustc-dev-guide.rust-lang.org/compiler-debugging.html#rustc_-test-attributes)
The one non-doc change (it's internal and not observable):
Be even more defensive in `query constness`'s impl (spiritual follow-up to #134122) (see self review comment).
Fixes #133494.
r\? **any**(compiler-errors, oli-obk)
Diffstat (limited to 'compiler/rustc_middle/src')
| -rw-r--r-- | compiler/rustc_middle/src/query/mod.rs | 311 |
1 files changed, 217 insertions, 94 deletions
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 2c2dffe8b88..7e7b602c560 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -132,6 +132,7 @@ rustc_queries! { } /// Return the span for a definition. + /// /// Contrary to `def_span` below, this query returns the full absolute span of the definition. /// This span is meant for dep-tracking rather than diagnostics. It should not be used outside /// of rustc_middle::hir::source_map. @@ -142,6 +143,7 @@ rustc_queries! { } /// Represents crate as a whole (as distinct from the top-level crate module). + /// /// If you call `hir_crate` (e.g., indirectly by calling `tcx.hir().krate()`), /// we will have to assume that any change means that you need to be recompiled. /// This is because the `hir_crate` query gives you access to all other items. @@ -202,28 +204,40 @@ rustc_queries! { feedable } - /// Given the def_id of a const-generic parameter, computes the associated default const - /// parameter. e.g. `fn example<const N: usize=3>` called on `N` would return `3`. + /// Returns the *default* of the const pararameter given by `DefId`. + /// + /// E.g., given `struct Ty<const N: usize = 3>;` this returns `3` for `N`. query const_param_default(param: DefId) -> ty::EarlyBinder<'tcx, ty::Const<'tcx>> { - desc { |tcx| "computing const default for a given parameter `{}`", tcx.def_path_str(param) } + desc { |tcx| "computing the default for const parameter `{}`", tcx.def_path_str(param) } cache_on_disk_if { param.is_local() } separate_provide_extern } - /// Returns the [`Ty`][rustc_middle::ty::Ty] of the given [`DefId`]. If the [`DefId`] points - /// to an alias, it will "skip" this alias to return the aliased type. + /// Returns the *type* of the definition given by `DefId`. + /// + /// For type aliases (whether eager or lazy) and associated types, this returns + /// the underlying aliased type (not the corresponding [alias type]). + /// + /// For opaque types, this returns and thus reveals the hidden type! If you + /// want to detect cycle errors use `type_of_opaque` instead. + /// + /// To clarify, for type definitions, this does *not* return the "type of a type" + /// (aka *kind* or *sort*) in the type-theoretical sense! It merely returns + /// the type primarily *associated with* it. /// - /// [`DefId`]: rustc_hir::def_id::DefId + /// # Panics + /// + /// This query will panic if the given definition doesn't (and can't + /// conceptually) have an (underlying) type. + /// + /// [alias type]: rustc_middle::ty::AliasTy query type_of(key: DefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> { desc { |tcx| "{action} `{path}`", - action = { - use rustc_hir::def::DefKind; - match tcx.def_kind(key) { - DefKind::TyAlias => "expanding type alias", - DefKind::TraitAlias => "expanding trait alias", - _ => "computing type of", - } + action = match tcx.def_kind(key) { + DefKind::TyAlias => "expanding type alias", + DefKind::TraitAlias => "expanding trait alias", + _ => "computing type of", }, path = tcx.def_path_str(key), } @@ -232,9 +246,14 @@ rustc_queries! { feedable } - /// Specialized instance of `type_of` that detects cycles that are due to - /// revealing opaque because of an auto trait bound. Unless `CyclePlaceholder` needs - /// to be handled separately, call `type_of` instead. + /// Returns the *hidden type* of the opaque type given by `DefId` unless a cycle occurred. + /// + /// This is a specialized instance of [`Self::type_of`] that detects query cycles. + /// Unless `CyclePlaceholder` needs to be handled separately, call [`Self::type_of`] instead. + /// + /// # Panics + /// + /// This query will panic if the given definition is not an opaque type. query type_of_opaque(key: DefId) -> Result<ty::EarlyBinder<'tcx, Ty<'tcx>>, CyclePlaceholder> { desc { |tcx| "computing type of opaque `{path}`", @@ -243,9 +262,22 @@ rustc_queries! { cycle_stash } + /// Returns whether the type alias given by `DefId` is lazy. + /// + /// I.e., if the type alias expands / ought to expand to a [weak] [alias type] + /// instead of the underyling aliased type. + /// + /// Relevant for features `lazy_type_alias` and `type_alias_impl_trait`. + /// + /// # Panics + /// + /// This query *may* panic if the given definition is not a type alias. + /// + /// [weak]: rustc_middle::ty::Weak + /// [alias type]: rustc_middle::ty::AliasTy query type_alias_is_lazy(key: DefId) -> bool { desc { |tcx| - "computing whether `{path}` is a lazy type alias", + "computing whether the type alias `{path}` is lazy", path = tcx.def_path_str(key), } separate_provide_extern @@ -299,8 +331,7 @@ rustc_queries! { desc { "checking lint expectations (RFC 2383)" } } - /// Maps from the `DefId` of an item (trait/struct/enum/fn) to its - /// associated generics. + /// Returns the *generics* of the definition given by `DefId`. query generics_of(key: DefId) -> &'tcx ty::Generics { desc { |tcx| "computing generics of `{}`", tcx.def_path_str(key) } arena_cache @@ -309,10 +340,13 @@ rustc_queries! { feedable } - /// Maps from the `DefId` of an item (trait/struct/enum/fn) to the - /// predicates (where-clauses) that must be proven true in order - /// to reference it. This is almost always the "predicates query" - /// that you want. + /// Returns the (elaborated) *predicates* of the definition given by `DefId` + /// that must be proven true at usage sites (and which can be assumed at definition site). + /// + /// This is almost always *the* "predicates query" that you want. + /// + /// **Tip**: You can use `#[rustc_dump_predicates]` on an item to basically print + /// the result of this query for use in UI tests or for debugging purposes. query predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { desc { |tcx| "computing predicates of `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } @@ -328,25 +362,24 @@ rustc_queries! { } } - /// Returns the list of bounds that are required to be satisfied - /// by a implementation or definition. For associated types, these - /// must be satisfied for an implementation to be well-formed, - /// and for opaque types, these are required to be satisfied by - /// the hidden-type of the opaque. + /// Returns the explicitly user-written *bounds* on the associated or opaque type given by `DefId` + /// that must be proven true at definition site (and which can be assumed at usage sites). /// - /// Syntactially, these are the bounds written on the trait's type - /// definition, or those after the `impl` keyword for an opaque: + /// For associated types, these must be satisfied for an implementation + /// to be well-formed, and for opaque types, these are required to be + /// satisfied by the hidden type of the opaque. /// - /// ```ignore (incomplete) - /// type X: Bound + 'lt - /// // ^^^^^^^^^^^ - /// impl Debug + Display - /// // ^^^^^^^^^^^^^^^ - /// ``` + /// Bounds from the parent (e.g. with nested `impl Trait`) are not included. /// - /// `key` is the `DefId` of the associated type or opaque type. + /// Syntactially, these are the bounds written on associated types in trait + /// definitions, or those after the `impl` keyword for an opaque: /// - /// Bounds from the parent (e.g. with nested impl trait) are not included. + /// ```ignore (illustrative) + /// trait Trait { type X: Bound + 'lt; } + /// // ^^^^^^^^^^^ + /// fn function() -> impl Debug + Display { /*...*/ } + /// // ^^^^^^^^^^^^^^^ + /// ``` query explicit_item_bounds(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } @@ -354,10 +387,12 @@ rustc_queries! { feedable } - /// The set of item bounds (see [`TyCtxt::explicit_item_bounds`]) that - /// share the `Self` type of the item. These are a subset of the bounds - /// that may explicitly be used for things like closure signature - /// deduction. + /// Returns the explicitly user-written *bounds* that share the `Self` type of the item. + /// + /// These are a subset of the [explicit item bounds] that may explicitly be used for things + /// like closure signature deduction. + /// + /// [explicit item bounds]: Self::explicit_item_bounds query explicit_item_super_predicates(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } @@ -365,26 +400,29 @@ rustc_queries! { feedable } - /// Elaborated version of the predicates from `explicit_item_bounds`. + /// Returns the (elaborated) *bounds* on the associated or opaque type given by `DefId` + /// that must be proven true at definition site (and which can be assumed at usage sites). /// - /// For example: + /// Bounds from the parent (e.g. with nested `impl Trait`) are not included. + /// + /// **Tip**: You can use `#[rustc_dump_item_bounds]` on an item to basically print + /// the result of this query for use in UI tests or for debugging purposes. + /// + /// # Examples /// /// ``` - /// trait MyTrait { - /// type MyAType: Eq + ?Sized; - /// } + /// trait Trait { type Assoc: Eq + ?Sized; } /// ``` /// - /// `explicit_item_bounds` returns `[<Self as MyTrait>::MyAType: Eq]`, - /// and `item_bounds` returns + /// While [`Self::explicit_item_bounds`] returns `[<Self as Trait>::Assoc: Eq]` + /// here, `item_bounds` returns: + /// /// ```text /// [ - /// <Self as Trait>::MyAType: Eq, - /// <Self as Trait>::MyAType: PartialEq<<Self as Trait>::MyAType> + /// <Self as Trait>::Assoc: Eq, + /// <Self as Trait>::Assoc: PartialEq<<Self as Trait>::Assoc> /// ] /// ``` - /// - /// Bounds from the parent (e.g. with nested impl trait) are not included. query item_bounds(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> { desc { |tcx| "elaborating item bounds for `{}`", tcx.def_path_str(key) } } @@ -615,27 +653,35 @@ rustc_queries! { desc { "getting wasm import module map" } } - /// Returns everything that looks like a predicate written explicitly - /// by the user on a trait item. + /// Returns the explicitly user-written *predicates and bounds* of the trait given by `DefId`. /// /// Traits are unusual, because predicates on associated types are /// converted into bounds on that type for backwards compatibility: /// + /// ``` /// trait X where Self::U: Copy { type U; } + /// ``` /// /// becomes /// + /// ``` /// trait X { type U: Copy; } + /// ``` /// - /// `explicit_predicates_of` and `explicit_item_bounds` will then take - /// the appropriate subsets of the predicates here. + /// [`Self::explicit_predicates_of`] and [`Self::explicit_item_bounds`] will + /// then take the appropriate subsets of the predicates here. + /// + /// # Panics + /// + /// This query will panic if the given definition is not a trait. query trait_explicit_predicates_and_bounds(key: LocalDefId) -> ty::GenericPredicates<'tcx> { desc { |tcx| "computing explicit predicates of trait `{}`", tcx.def_path_str(key) } } - /// Returns the predicates written explicitly by the user. + /// Returns the explicitly user-written *predicates* of the definition given by `DefId` + /// that must be proven true at usage sites (and which can be assumed at definition site). /// - /// You should probably use `predicates_of` unless you're looking for + /// You should probably use [`Self::predicates_of`] unless you're looking for /// predicates with explicit spans for diagnostics purposes. query explicit_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { desc { |tcx| "computing explicit predicates of `{}`", tcx.def_path_str(key) } @@ -644,18 +690,24 @@ rustc_queries! { feedable } - /// Returns the inferred outlives predicates (e.g., for `struct - /// Foo<'a, T> { x: &'a T }`, this would return `T: 'a`). + /// Returns the *inferred outlives-predicates* of the item given by `DefId`. + /// + /// E.g., for `struct Foo<'a, T> { x: &'a T }`, this would return `[T: 'a]`. + /// + /// **Tip**: You can use `#[rustc_outlives]` on an item to basically print the + /// result of this query for use in UI tests or for debugging purposes. query inferred_outlives_of(key: DefId) -> &'tcx [(ty::Clause<'tcx>, Span)] { - desc { |tcx| "computing inferred outlives predicates of `{}`", tcx.def_path_str(key) } + desc { |tcx| "computing inferred outlives-predicates of `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern feedable } - /// Maps from the `DefId` of a trait to the list of super-predicates of the trait, - /// *before* elaboration (so it doesn't contain transitive super-predicates). This - /// is a subset of the full list of predicates. We store these in a separate map + /// Returns the explicitly user-written *super-predicates* of the trait given by `DefId`. + /// + /// These predicates are unelaborated and consequently don't contain transitive super-predicates. + /// + /// This is a subset of the full list of predicates. We store these in a separate map /// because we must evaluate them even during type conversion, often before the full /// predicates are available (note that super-predicates must not be cyclic). query explicit_super_predicates_of(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { @@ -664,8 +716,9 @@ rustc_queries! { separate_provide_extern } - /// The predicates of the trait that are implied during elaboration. This is a - /// superset of the super-predicates of the trait, but a subset of the predicates + /// The predicates of the trait that are implied during elaboration. + /// + /// This is a superset of the super-predicates of the trait, but a subset of the predicates /// of the trait. For regular traits, this includes all super-predicates and their /// associated type bounds. For trait aliases, currently, this includes all of the /// predicates of the trait alias. @@ -745,14 +798,27 @@ rustc_queries! { desc { |tcx| "computing drop-check constraints for `{}`", tcx.def_path_str(key) } } - /// Returns the constness of function-like things (tuple struct/variant constructors, functions, - /// methods) + /// Returns the constness of the function-like[^1] definition given by `DefId`. + /// + /// Tuple struct/variant constructors are *always* const, foreign functions are + /// *never* const. The rest is const iff marked with keyword `const` (or rather + /// its parent in the case of associated functions). /// - /// Will ICE if used on things that are always const or never const. + /// <div class="warning"> /// - /// **Do not call this function manually.** It is only meant to cache the base data for the + /// **Do not call this query** directly. It is only meant to cache the base data for the /// higher-level functions. Consider using `is_const_fn` or `is_const_trait_impl` instead. - /// Also note that neither of them takes into account feature gates and stability. + /// + /// Also note that neither of them takes into account feature gates, stability and + /// const predicates/conditions! + /// + /// </div> + /// + /// # Panics + /// + /// This query will panic if the given definition is not function-like[^1]. + /// + /// [^1]: Tuple struct/variant constructors, closures and free, associated and foreign functions. query constness(key: DefId) -> hir::Constness { desc { |tcx| "checking if item is const: `{}`", tcx.def_path_str(key) } separate_provide_extern @@ -798,13 +864,25 @@ rustc_queries! { separate_provide_extern } - /// Gets a map with the variance of every item; use `variances_of` instead. + /// Gets a map with the variances of every item in the local crate. + /// + /// <div class="warning"> + /// + /// **Do not call this query** directly, use [`Self::variances_of`] instead. + /// + /// </div> query crate_variances(_: ()) -> &'tcx ty::CrateVariancesMap<'tcx> { arena_cache desc { "computing the variances for items in this crate" } } - /// Maps from the `DefId` of a type or region parameter to its (inferred) variance. + /// Returns the (inferred) variances of the item given by `DefId`. + /// + /// The list of variances corresponds to the list of (early-bound) generic + /// parameters of the item (including its parents). + /// + /// **Tip**: You can use `#[rustc_variance]` on an item to basically print the + /// result of this query for use in UI tests or for debugging purposes. query variances_of(def_id: DefId) -> &'tcx [ty::Variance] { desc { |tcx| "computing the variances of `{}`", tcx.def_path_str(def_id) } cache_on_disk_if { def_id.is_local() } @@ -812,10 +890,16 @@ rustc_queries! { cycle_delay_bug } - /// Maps from thee `DefId` of a type to its (inferred) outlives. + /// Gets a map with the inferred outlives-predicates of every item in the local crate. + /// + /// <div class="warning"> + /// + /// **Do not call this query** directly, use [`Self::inferred_outlives_of`] instead. + /// + /// </div> query inferred_outlives_crate(_: ()) -> &'tcx ty::CratePredicatesMap<'tcx> { arena_cache - desc { "computing the inferred outlives predicates for items in this crate" } + desc { "computing the inferred outlives-predicates for items in this crate" } } /// Maps from an impl/trait or struct/variant `DefId` @@ -1038,20 +1122,35 @@ rustc_queries! { } /// Gets a complete map from all types to their inherent impls. - /// Not meant to be used directly outside of coherence. + /// + /// <div class="warning"> + /// + /// **Not meant to be used** directly outside of coherence. + /// + /// </div> query crate_inherent_impls(k: ()) -> (&'tcx CrateInherentImpls, Result<(), ErrorGuaranteed>) { desc { "finding all inherent impls defined in crate" } } /// Checks all types in the crate for overlap in their inherent impls. Reports errors. - /// Not meant to be used directly outside of coherence. + /// + /// <div class="warning"> + /// + /// **Not meant to be used** directly outside of coherence. + /// + /// </div> query crate_inherent_impls_validity_check(_: ()) -> Result<(), ErrorGuaranteed> { desc { "check for inherent impls that should not be defined in crate" } ensure_forwards_result_if_red } /// Checks all types in the crate for overlap in their inherent impls. Reports errors. - /// Not meant to be used directly outside of coherence. + /// + /// <div class="warning"> + /// + /// **Not meant to be used** directly outside of coherence. + /// + /// </div> query crate_inherent_impls_overlap_check(_: ()) -> Result<(), ErrorGuaranteed> { desc { "check for overlap between inherent impls defined in this crate" } ensure_forwards_result_if_red @@ -1089,8 +1188,12 @@ rustc_queries! { } /// Computes the tag (if any) for a given type and variant. + /// /// `None` means that the variant doesn't need a tag (because it is niched). - /// Will panic for uninhabited variants. + /// + /// # Panics + /// + /// This query will panic for uninhabited variants and if the passed type is not an enum. query tag_for_variant( key: (Ty<'tcx>, abi::VariantIdx) ) -> Option<ty::ScalarInt> { @@ -1099,7 +1202,12 @@ rustc_queries! { /// Evaluates a constant and returns the computed allocation. /// - /// **Do not use this** directly, use the `eval_to_const_value` or `eval_to_valtree` instead. + /// <div class="warning"> + /// + /// **Do not call this query** directly, use [`Self::eval_to_const_value_raw`] or + /// [`Self::eval_to_valtree`] instead. + /// + /// </div> query eval_to_allocation_raw(key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>) -> EvalToAllocationRawResult<'tcx> { desc { |tcx| @@ -1120,12 +1228,18 @@ rustc_queries! { feedable } - /// Evaluates const items or anonymous constants - /// (such as enum variant explicit discriminants or array lengths) - /// into a representation suitable for the type system and const generics. + /// Evaluates const items or anonymous constants[^1] into a representation + /// suitable for the type system and const generics. + /// + /// <div class="warning"> + /// + /// **Do not call this** directly, use one of the following wrappers: + /// [`TyCtxt::const_eval_poly`], [`TyCtxt::const_eval_resolve`], + /// [`TyCtxt::const_eval_instance`], or [`TyCtxt::const_eval_global_id`]. + /// + /// </div> /// - /// **Do not use this** directly, use one of the following wrappers: `tcx.const_eval_poly`, - /// `tcx.const_eval_resolve`, `tcx.const_eval_instance`, or `tcx.const_eval_global_id`. + /// [^1]: Such as enum variant explicit discriminants or array lengths. query eval_to_const_value_raw(key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>) -> EvalToConstValueResult<'tcx> { desc { |tcx| @@ -1252,13 +1366,13 @@ rustc_queries! { separate_provide_extern } - /// Determines whether an item is annotated with `doc(hidden)`. + /// Determines whether an item is annotated with `#[doc(hidden)]`. query is_doc_hidden(def_id: DefId) -> bool { desc { |tcx| "checking whether `{}` is `doc(hidden)`", tcx.def_path_str(def_id) } separate_provide_extern } - /// Determines whether an item is annotated with `doc(notable_trait)`. + /// Determines whether an item is annotated with `#[doc(notable_trait)]`. query is_doc_notable_trait(def_id: DefId) -> bool { desc { |tcx| "checking whether `{}` is `doc(notable_trait)`", tcx.def_path_str(def_id) } } @@ -1796,13 +1910,22 @@ rustc_queries! { query is_late_bound_map(owner_id: hir::OwnerId) -> Option<&'tcx FxIndexSet<ItemLocalId>> { desc { |tcx| "testing if a region is late bound inside `{}`", tcx.def_path_str(owner_id) } } - /// For a given item's generic parameter, gets the default lifetimes to be used - /// for each parameter if a trait object were to be passed for that parameter. - /// For example, for `T` in `struct Foo<'a, T>`, this would be `'static`. - /// For `T` in `struct Foo<'a, T: 'a>`, this would instead be `'a`. - /// This query will panic if passed something that is not a type parameter. + /// Returns the *default lifetime* to be used if a trait object type were to be passed for + /// the type parameter given by `DefId`. + /// + /// **Tip**: You can use `#[rustc_object_lifetime_default]` on an item to basically + /// print the result of this query for use in UI tests or for debugging purposes. + /// + /// # Examples + /// + /// - For `T` in `struct Foo<'a, T: 'a>(&'a T);`, this would be `Param('a)` + /// - For `T` in `struct Bar<'a, T>(&'a T);`, this would be `Empty` + /// + /// # Panics + /// + /// This query will panic if the given definition is not a type parameter. query object_lifetime_default(def_id: DefId) -> ObjectLifetimeDefault { - desc { "looking up lifetime defaults for generic parameter `{}`", tcx.def_path_str(def_id) } + desc { "looking up lifetime defaults for type parameter `{}`", tcx.def_path_str(def_id) } separate_provide_extern } query late_bound_vars_map(owner_id: hir::OwnerId) |
