Update (doc) comments
Several (doc) comments were super outdated or didn't provide enough context. Some doc comments shoved everything in a single paragraph without respecting the fact that the first paragraph should be a single sentence because rustdoc treats these as item descriptions / synopses on module pages.
This commit is contained in:
parent
05d48b936f
commit
82c2c8deb1
@ -303,10 +303,6 @@ impl TraitBoundModifiers {
|
||||
};
|
||||
}
|
||||
|
||||
/// The AST represents all type param bounds as types.
|
||||
/// `typeck::collect::compute_bounds` matches these against
|
||||
/// the "special" built-in traits (see `middle::lang_items`) and
|
||||
/// detects `Copy`, `Send` and `Sync`.
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub enum GenericBound {
|
||||
Trait(PolyTraitRef, TraitBoundModifiers),
|
||||
|
@ -480,7 +480,7 @@ pub fn walk_use_tree<'a, V: Visitor<'a>>(
|
||||
try_visit!(visitor.visit_path(&use_tree.prefix, id));
|
||||
match use_tree.kind {
|
||||
UseTreeKind::Simple(rename) => {
|
||||
// The extra IDs are handled during HIR lowering.
|
||||
// The extra IDs are handled during AST lowering.
|
||||
visit_opt!(visitor, visit_ident, rename);
|
||||
}
|
||||
UseTreeKind::Glob => {}
|
||||
|
@ -29,11 +29,12 @@
|
||||
//! item id (`item_id`) in case of impl trait or path resolution id (`path_id`) otherwise.
|
||||
//!
|
||||
//! Since we do not have a proper way to obtain function type information by path resolution
|
||||
//! in AST, we mark each function parameter type as `InferDelegation` and inherit it in `AstConv`.
|
||||
//! in AST, we mark each function parameter type as `InferDelegation` and inherit it during
|
||||
//! HIR ty lowering.
|
||||
//!
|
||||
//! Similarly generics, predicates and header are set to the "default" values.
|
||||
//! In case of discrepancy with callee function the `NotSupportedDelegation` error will
|
||||
//! also be emitted in `AstConv`.
|
||||
//! also be emitted during HIR ty lowering.
|
||||
|
||||
use crate::{ImplTraitPosition, ResolverAstLoweringExt};
|
||||
|
||||
@ -129,7 +130,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
) -> &'hir hir::FnDecl<'hir> {
|
||||
let args_count = if let Some(local_sig_id) = sig_id.as_local() {
|
||||
// Map may be filled incorrectly due to recursive delegation.
|
||||
// Error will be emmited later in astconv.
|
||||
// Error will be emitted later during HIR ty lowering.
|
||||
self.resolver.fn_parameter_counts.get(&local_sig_id).cloned().unwrap_or_default()
|
||||
} else {
|
||||
self.tcx.fn_arg_names(sig_id).len()
|
||||
|
@ -1427,8 +1427,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
// Error if `?Trait` bounds in where clauses don't refer directly to type parameters.
|
||||
// Note: we used to clone these bounds directly onto the type parameter (and avoid lowering
|
||||
// these into hir when we lower thee where clauses), but this makes it quite difficult to
|
||||
// keep track of the Span info. Now, `add_implicitly_sized` in `AstConv` checks both param bounds and
|
||||
// where clauses for `?Sized`.
|
||||
// keep track of the Span info. Now, `<dyn HirTyLowerer>::add_implicit_sized_bound`
|
||||
// checks both param bounds and where clauses for `?Sized`.
|
||||
for pred in &generics.where_clause.predicates {
|
||||
let WherePredicate::BoundPredicate(bound_pred) = pred else {
|
||||
continue;
|
||||
|
@ -428,10 +428,6 @@ pub enum TraitBoundModifier {
|
||||
MaybeConst,
|
||||
}
|
||||
|
||||
/// The AST represents all type param bounds as types.
|
||||
/// `typeck::collect::compute_bounds` matches these against
|
||||
/// the "special" built-in traits (see `middle::lang_items`) and
|
||||
/// detects `Copy`, `Send` and `Sync`.
|
||||
#[derive(Clone, Copy, Debug, HashStable_Generic)]
|
||||
pub enum GenericBound<'hir> {
|
||||
Trait(PolyTraitRef<'hir>, TraitBoundModifier),
|
||||
@ -1860,7 +1856,7 @@ pub enum ExprKind<'hir> {
|
||||
/// Wraps the expression in a terminating scope.
|
||||
/// This makes it semantically equivalent to `{ let _t = expr; _t }`.
|
||||
///
|
||||
/// This construct only exists to tweak the drop order in HIR lowering.
|
||||
/// This construct only exists to tweak the drop order in AST lowering.
|
||||
/// An example of that is the desugaring of `for` loops.
|
||||
DropTemps(&'hir Expr<'hir>),
|
||||
/// A `let $pat = $expr` expression.
|
||||
@ -2293,7 +2289,7 @@ pub enum ImplItemKind<'hir> {
|
||||
/// Bind a type to an associated type (i.e., `A = Foo`).
|
||||
///
|
||||
/// Bindings like `A: Debug` are represented as a special type `A =
|
||||
/// $::Debug` that is understood by the astconv code.
|
||||
/// $::Debug` that is understood by the HIR ty lowering code.
|
||||
///
|
||||
/// FIXME(alexreg): why have a separate type for the binding case,
|
||||
/// wouldn't it be better to make the `ty` field an enum like the
|
||||
|
@ -17,7 +17,9 @@ use crate::bounds::Bounds;
|
||||
use crate::errors;
|
||||
|
||||
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
/// Sets `implicitly_sized` to true on `Bounds` if necessary
|
||||
/// Add a `Sized` bound to the `bounds` if appropriate.
|
||||
///
|
||||
/// Doesn't add the bound if the HIR bounds contain any of `Sized`, `?Sized` or `!Sized`.
|
||||
pub(crate) fn add_sized_bound(
|
||||
&self,
|
||||
bounds: &mut Bounds<'tcx>,
|
||||
@ -101,21 +103,27 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
}
|
||||
}
|
||||
|
||||
/// This helper takes a *converted* parameter type (`param_ty`)
|
||||
/// and an *unconverted* list of bounds:
|
||||
/// Lower HIR bounds into `bounds` given the self type `param_ty` and the overarching late-bound vars if any.
|
||||
///
|
||||
/// ```text
|
||||
/// fn foo<T: Debug>
|
||||
/// ^ ^^^^^ `ast_bounds` parameter, in HIR form
|
||||
/// |
|
||||
/// `param_ty`, in ty form
|
||||
/// ### Examples
|
||||
///
|
||||
/// ```ignore (illustrative)
|
||||
/// fn foo<T>() where for<'a> T: Trait<'a> + Copy {}
|
||||
/// // ^^^^^^^ ^ ^^^^^^^^^^^^^^^^ `ast_bounds`, in HIR form
|
||||
/// // | |
|
||||
/// // | `param_ty`, in ty form
|
||||
/// // `bound_vars`, in ty form
|
||||
///
|
||||
/// fn bar<T>() where T: for<'a> Trait<'a> + Copy {} // no overarching `bound_vars` here!
|
||||
/// // ^ ^^^^^^^^^^^^^^^^^^^^^^^^ `ast_bounds`, in HIR form
|
||||
/// // |
|
||||
/// // `param_ty`, in ty form
|
||||
/// ```
|
||||
///
|
||||
/// It adds these `ast_bounds` into the `bounds` structure.
|
||||
/// ### A Note on Binders
|
||||
///
|
||||
/// **A note on binders:** there is an implied binder around
|
||||
/// `param_ty` and `ast_bounds`. See `instantiate_poly_trait_ref`
|
||||
/// for more details.
|
||||
/// There is an implied binder around `param_ty` and `ast_bounds`.
|
||||
/// See `lower_poly_trait_ref` for more details.
|
||||
#[instrument(level = "debug", skip(self, ast_bounds, bounds))]
|
||||
pub(crate) fn lower_poly_bounds<'hir, I: Iterator<Item = &'hir hir::GenericBound<'tcx>>>(
|
||||
&self,
|
||||
@ -170,22 +178,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
}
|
||||
}
|
||||
|
||||
/// Translates a list of bounds from the HIR into the `Bounds` data structure.
|
||||
/// The self-type for the bounds is given by `param_ty`.
|
||||
/// Lower HIR bounds into `bounds` given the self type `param_ty` and *no* overarching late-bound vars.
|
||||
///
|
||||
/// Example:
|
||||
/// ### Example
|
||||
///
|
||||
/// ```ignore (illustrative)
|
||||
/// fn foo<T: Bar + Baz>() { }
|
||||
/// fn foo<T: Bar + Baz>() {}
|
||||
/// // ^ ^^^^^^^^^ ast_bounds
|
||||
/// // param_ty
|
||||
/// ```
|
||||
///
|
||||
/// The `sized_by_default` parameter indicates if, in this context, the `param_ty` should be
|
||||
/// considered `Sized` unless there is an explicit `?Sized` bound. This would be true in the
|
||||
/// example above, but is not true in supertrait listings like `trait Foo: Bar + Baz`.
|
||||
///
|
||||
/// `span` should be the declaration size of the parameter.
|
||||
pub(crate) fn lower_mono_bounds(
|
||||
&self,
|
||||
param_ty: Ty<'tcx>,
|
||||
@ -227,12 +228,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
bounds
|
||||
}
|
||||
|
||||
/// Given an HIR binding like `Item = Foo` or `Item: Foo`, pushes the corresponding predicates
|
||||
/// onto `bounds`.
|
||||
/// Lower an associated item binding from HIR into `bounds`.
|
||||
///
|
||||
/// **A note on binders:** given something like `T: for<'a> Iterator<Item = &'a u32>`, the
|
||||
/// `trait_ref` here will be `for<'a> T: Iterator`. The `binding` data however is from *inside*
|
||||
/// the binder (e.g., `&'a u32`) and hence may reference bound regions.
|
||||
/// ### A Note on Binders
|
||||
///
|
||||
/// Given something like `T: for<'a> Iterator<Item = &'a u32>`,
|
||||
/// the `trait_ref` here will be `for<'a> T: Iterator`.
|
||||
/// The `binding` data however is from *inside* the binder
|
||||
/// (e.g., `&'a u32`) and hence may reference bound regions.
|
||||
#[instrument(level = "debug", skip(self, bounds, dup_bindings, path_span))]
|
||||
pub(super) fn lower_assoc_item_binding(
|
||||
&self,
|
||||
@ -244,22 +247,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
path_span: Span,
|
||||
only_self_bounds: OnlySelfBounds,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
// Given something like `U: SomeTrait<T = X>`, we want to produce a
|
||||
// predicate like `<U as SomeTrait>::T = X`. This is somewhat
|
||||
// subtle in the event that `T` is defined in a supertrait of
|
||||
// `SomeTrait`, because in that case we need to upcast.
|
||||
//
|
||||
// That is, consider this case:
|
||||
//
|
||||
// ```
|
||||
// trait SubTrait: SuperTrait<i32> { }
|
||||
// trait SuperTrait<A> { type T; }
|
||||
//
|
||||
// ... B: SubTrait<T = foo> ...
|
||||
// ```
|
||||
//
|
||||
// We want to produce `<B as SuperTrait<i32>>::T == foo`.
|
||||
|
||||
let tcx = self.tcx();
|
||||
|
||||
let assoc_kind = if binding.gen_args.parenthesized
|
||||
@ -272,6 +259,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
ty::AssocKind::Type
|
||||
};
|
||||
|
||||
// Given something like `U: Trait<T = X>`, we want to produce a predicate like
|
||||
// `<U as Trait>::T = X`.
|
||||
// This is somewhat subtle in the event that `T` is defined in a supertrait of `Trait`,
|
||||
// because in that case we need to upcast. I.e., we want to produce
|
||||
// `<B as SuperTrait<i32>>::T == X` for `B: SubTrait<T = X>` where
|
||||
//
|
||||
// trait SubTrait: SuperTrait<i32> {}
|
||||
// trait SuperTrait<A> { type T; }
|
||||
let candidate = if self.probe_trait_that_defines_assoc_item(
|
||||
trait_ref.def_id(),
|
||||
assoc_kind,
|
||||
@ -449,6 +444,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
span: binding.span,
|
||||
}));
|
||||
}
|
||||
// Lower an equality constraint like `Item = u32` as found in HIR bound `T: Iterator<Item = u32>`
|
||||
// to a projection predicate: `<T as Iterator>::Item = u32`.
|
||||
hir::TypeBindingKind::Equality { term } => {
|
||||
let term = match term {
|
||||
hir::Term::Ty(ty) => self.lower_ty(ty).into(),
|
||||
@ -490,10 +487,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
},
|
||||
);
|
||||
|
||||
// "Desugar" a constraint like `T: Iterator<Item = u32>` this to
|
||||
// the "projection predicate" for:
|
||||
//
|
||||
// `<T as Iterator>::Item = u32`
|
||||
bounds.push_projection_bound(
|
||||
tcx,
|
||||
projection_ty
|
||||
@ -501,18 +494,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
binding.span,
|
||||
);
|
||||
}
|
||||
// Lower a constraint like `Item: Debug` as found in HIR bound `T: Iterator<Item: Debug>`
|
||||
// to a bound involving a projection: `<T as Iterator>::Item: Debug`.
|
||||
hir::TypeBindingKind::Constraint { bounds: ast_bounds } => {
|
||||
// "Desugar" a constraint like `T: Iterator<Item: Debug>` to
|
||||
//
|
||||
// `<T as Iterator>::Item: Debug`
|
||||
//
|
||||
// Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty`
|
||||
// parameter to have a skipped binder.
|
||||
//
|
||||
// NOTE: If `only_self_bounds` is true, do NOT expand this associated
|
||||
// type bound into a trait predicate, since we only want to add predicates
|
||||
// for the `Self` type.
|
||||
// NOTE: If `only_self_bounds` is true, do NOT expand this associated type bound into
|
||||
// a trait predicate, since we only want to add predicates for the `Self` type.
|
||||
if !only_self_bounds.0 {
|
||||
// Calling `skip_binder` is okay, because `lower_bounds` expects the `param_ty`
|
||||
// parameter to have a skipped binder.
|
||||
let param_ty = Ty::new_alias(tcx, ty::Projection, projection_ty.skip_binder());
|
||||
self.lower_poly_bounds(
|
||||
param_ty,
|
||||
|
@ -143,24 +143,22 @@ fn generic_arg_mismatch_err(
|
||||
err.emit()
|
||||
}
|
||||
|
||||
/// Creates the relevant generic arguments
|
||||
/// corresponding to a set of generic parameters. This is a
|
||||
/// rather complex function. Let us try to explain the role
|
||||
/// Lower generic arguments from the HIR to the [`rustc_middle::ty`] representation.
|
||||
///
|
||||
/// This is a rather complex function. Let us try to explain the role
|
||||
/// of each of its parameters:
|
||||
///
|
||||
/// To start, we are given the `def_id` of the thing whose generic
|
||||
/// parameters we are instantiating, and a partial set of
|
||||
/// arguments `parent_args`. In general, the generic arguments
|
||||
/// for an item begin with arguments for all the "parents" of
|
||||
/// that item -- e.g., for a method it might include the
|
||||
/// parameters from the impl.
|
||||
/// To start, we are given the `def_id` of the thing whose generic parameters we
|
||||
/// are creating, and a partial set of arguments `parent_args`. In general,
|
||||
/// the generic arguments for an item begin with arguments for all the "parents"
|
||||
/// of that item -- e.g., for a method it might include the parameters from the impl.
|
||||
///
|
||||
/// Therefore, the method begins by walking down these parents,
|
||||
/// starting with the outermost parent and proceed inwards until
|
||||
/// it reaches `def_id`. For each parent `P`, it will check `parent_args`
|
||||
/// first to see if the parent's arguments are listed in there. If so,
|
||||
/// we can append those and move on. Otherwise, it invokes the
|
||||
/// three callback functions:
|
||||
/// we can append those and move on. Otherwise, it uses the provided
|
||||
/// [`GenericArgsLowerer`] `ctx` which has the following methods:
|
||||
///
|
||||
/// - `args_for_def_id`: given the `DefId` `P`, supplies back the
|
||||
/// generic arguments that were given to that parent from within
|
||||
@ -168,10 +166,10 @@ fn generic_arg_mismatch_err(
|
||||
/// might refer to the trait `Foo`, and the arguments might be
|
||||
/// `[T]`. The boolean value indicates whether to infer values
|
||||
/// for arguments whose values were not explicitly provided.
|
||||
/// - `provided_kind`: given the generic parameter and the value from `args_for_def_id`,
|
||||
/// instantiate a `GenericArg`.
|
||||
/// - `inferred_kind`: if no parameter was provided, and inference is enabled, then
|
||||
/// creates a suitable inference variable.
|
||||
/// - `provided_kind`: given the generic parameter and the value
|
||||
/// from `args_for_def_id`, creating a `GenericArg`.
|
||||
/// - `inferred_kind`: if no parameter was provided, and inference
|
||||
/// is enabled, then creates a suitable inference variable.
|
||||
pub fn lower_generic_args<'tcx: 'a, 'a>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: DefId,
|
||||
|
@ -1,6 +1,17 @@
|
||||
//! Conversion from AST representation of types to the `ty.rs` representation.
|
||||
//! The main routine here is `ast_ty_to_ty()`; each use is parameterized by an
|
||||
//! instance of `AstConv`.
|
||||
//! HIR ty lowering: Lowers type-system entities[^1] from the [HIR][hir] to
|
||||
//! the [`rustc_middle::ty`] representation.
|
||||
//!
|
||||
//! Not to be confused with *AST lowering* which lowers AST constructs to HIR ones
|
||||
//! or with *THIR* / *MIR* *lowering* / *building* which lowers HIR *bodies*
|
||||
//! (i.e., “executable code”) to THIR / MIR.
|
||||
//!
|
||||
//! Most lowering routines are defined on [`dyn HirTyLowerer`](HirTyLowerer) directly,
|
||||
//! like the main routine of this module, `lower_ty`.
|
||||
//!
|
||||
//! This module used to be called `astconv`.
|
||||
//!
|
||||
//! [^1]: This includes types, lifetimes / regions, constants in type positions,
|
||||
//! trait references and bounds.
|
||||
|
||||
mod bounds;
|
||||
mod errors;
|
||||
@ -43,6 +54,7 @@ use rustc_trait_selection::traits::{self, ObligationCtxt};
|
||||
use std::fmt::Display;
|
||||
use std::slice;
|
||||
|
||||
/// A path segment that is semantically allowed to have generic arguments.
|
||||
#[derive(Debug)]
|
||||
pub struct GenericPathSegment(pub DefId, pub usize);
|
||||
|
||||
@ -67,23 +79,30 @@ pub enum PredicateFilter {
|
||||
SelfAndAssociatedTypeBounds,
|
||||
}
|
||||
|
||||
/// A context which can lower type-system entities from the [HIR][hir] to
|
||||
/// the [`rustc_middle::ty`] representation.
|
||||
///
|
||||
/// This trait used to be called `AstConv`.
|
||||
pub trait HirTyLowerer<'tcx> {
|
||||
fn tcx(&self) -> TyCtxt<'tcx>;
|
||||
|
||||
/// Returns the [`DefId`] of the overarching item whose constituents get lowered.
|
||||
fn item_def_id(&self) -> DefId;
|
||||
|
||||
/// Returns predicates in scope of the form `X: Foo<T>`, where `X`
|
||||
/// is a type parameter `X` with the given id `def_id` and T
|
||||
/// matches `assoc_name`. This is a subset of the full set of
|
||||
/// predicates.
|
||||
/// Probe bounds in scope where the bounded type coincides with the given type parameter.
|
||||
///
|
||||
/// This is used for one specific purpose: resolving "short-hand"
|
||||
/// associated type references like `T::Item`. In principle, we
|
||||
/// would do that by first getting the full set of predicates in
|
||||
/// scope and then filtering down to find those that apply to `T`,
|
||||
/// but this can lead to cycle errors. The problem is that we have
|
||||
/// to do this resolution *in order to create the predicates in
|
||||
/// the first place*. Hence, we have this "special pass".
|
||||
/// Rephrased, this returns bounds of the form `T: Trait`, where `T` is a type parameter
|
||||
/// with the given `def_id`. This is a subset of the full set of bounds.
|
||||
///
|
||||
/// This method may use the given `assoc_name` to disregard bounds whose trait reference
|
||||
/// doesn't define an associated item with the provided name.
|
||||
///
|
||||
/// This is used for one specific purpose: Resolving “short-hand” associated type references
|
||||
/// like `T::Item` where `T` is a type parameter. In principle, we would do that by first
|
||||
/// getting the full set of predicates in scope and then filtering down to find those that
|
||||
/// apply to `T`, but this can lead to cycle errors. The problem is that we have to do this
|
||||
/// resolution *in order to create the predicates in the first place*.
|
||||
/// Hence, we have this “special pass”.
|
||||
fn probe_ty_param_bounds(
|
||||
&self,
|
||||
span: Span,
|
||||
@ -91,14 +110,14 @@ pub trait HirTyLowerer<'tcx> {
|
||||
assoc_name: Ident,
|
||||
) -> ty::GenericPredicates<'tcx>;
|
||||
|
||||
/// Returns the lifetime to use when a lifetime is omitted (and not elided).
|
||||
/// Returns the region to use when a lifetime is omitted (and not elided).
|
||||
fn re_infer(&self, param: Option<&ty::GenericParamDef>, span: Span)
|
||||
-> Option<ty::Region<'tcx>>;
|
||||
|
||||
/// Returns the type to use when a type is omitted.
|
||||
fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx>;
|
||||
|
||||
/// Returns `true` if `_` is allowed in type signatures in the current context.
|
||||
/// Returns `true` if the current context allows the use of inference variables.
|
||||
fn allow_infer(&self) -> bool;
|
||||
|
||||
/// Returns the const to use when a const is omitted.
|
||||
@ -109,13 +128,18 @@ pub trait HirTyLowerer<'tcx> {
|
||||
span: Span,
|
||||
) -> Const<'tcx>;
|
||||
|
||||
/// Projecting an associated type from a (potentially)
|
||||
/// higher-ranked trait reference is more complicated, because of
|
||||
/// the possibility of late-bound regions appearing in the
|
||||
/// associated type binding. This is not legal in function
|
||||
/// signatures for that reason. In a function body, we can always
|
||||
/// handle it because we can use inference variables to remove the
|
||||
/// late-bound regions.
|
||||
/// Lower an associated type to a projection.
|
||||
///
|
||||
/// This method has to be defined by the concrete lowering context because
|
||||
/// dealing with higher-ranked trait references depends on its capabilities:
|
||||
///
|
||||
/// If the context can make use of type inference, it can simply instantiate
|
||||
/// any late-bound vars bound by the trait reference with inference variables.
|
||||
/// If it doesn't support type inference, there is nothing reasonable it can
|
||||
/// do except reject the associated type.
|
||||
///
|
||||
/// The canonical example of this is associated type `T::P` where `T` is a type
|
||||
/// param constrained by `T: for<'a> Trait<'a>` and where `Trait` defines `P`.
|
||||
fn lower_assoc_ty(
|
||||
&self,
|
||||
span: Span,
|
||||
@ -125,20 +149,26 @@ pub trait HirTyLowerer<'tcx> {
|
||||
) -> Ty<'tcx>;
|
||||
|
||||
/// Returns `AdtDef` if `ty` is an ADT.
|
||||
/// Note that `ty` might be a projection type that needs normalization.
|
||||
///
|
||||
/// Note that `ty` might be a alias type that needs normalization.
|
||||
/// This used to get the enum variants in scope of the type.
|
||||
/// For example, `Self::A` could refer to an associated type
|
||||
/// or to an enum variant depending on the result of this function.
|
||||
fn probe_adt(&self, span: Span, ty: Ty<'tcx>) -> Option<ty::AdtDef<'tcx>>;
|
||||
|
||||
/// Invoked when we encounter an error from some prior pass
|
||||
/// (e.g., resolve) that is translated into a ty-error. This is
|
||||
/// used to help suppress derived errors typeck might otherwise
|
||||
/// report.
|
||||
/// Taint the context with errors.
|
||||
///
|
||||
/// Invoke this when you encounter an error from some prior pass like name resolution.
|
||||
/// This is used to help suppress derived errors typeck might otherwise report.
|
||||
fn set_tainted_by_errors(&self, e: ErrorGuaranteed);
|
||||
|
||||
/// Record the lowered type of a HIR node in this context.
|
||||
fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span);
|
||||
|
||||
/// Convenience method for coercing the lowering context into a trait object type.
|
||||
///
|
||||
/// Most lowering routines are defined on the trait object type directly
|
||||
/// necessitating a coercion step from the concrete lowering context.
|
||||
fn lowerer(&self) -> &dyn HirTyLowerer<'tcx>
|
||||
where
|
||||
Self: Sized,
|
||||
@ -146,6 +176,7 @@ pub trait HirTyLowerer<'tcx> {
|
||||
self
|
||||
}
|
||||
|
||||
/// The inference context of the lowering context if applicable.
|
||||
fn infcx(&self) -> Option<&InferCtxt<'tcx>>;
|
||||
}
|
||||
|
||||
@ -197,6 +228,10 @@ pub struct GenericArgCountResult {
|
||||
pub correct: Result<(), GenericArgCountMismatch>,
|
||||
}
|
||||
|
||||
/// A context which can lower HIR's [`GenericArg`] to `rustc_middle`'s [`ty::GenericArg`].
|
||||
///
|
||||
/// Its only consumer is [`generics::lower_generic_args`].
|
||||
/// Read its documentation to learn more.
|
||||
pub trait GenericArgsLowerer<'a, 'tcx> {
|
||||
fn args_for_def_id(&mut self, def_id: DefId) -> (Option<&'a GenericArgs<'tcx>>, bool);
|
||||
|
||||
@ -215,6 +250,7 @@ pub trait GenericArgsLowerer<'a, 'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
/// Lower a lifetime from the HIR to our internal notion of a lifetime called a *region*.
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
pub fn lower_lifetime(
|
||||
&self,
|
||||
@ -271,8 +307,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
}
|
||||
}
|
||||
|
||||
/// Given a path `path` that refers to an item `I` with the declared generics `decl_generics`,
|
||||
/// returns an appropriate set of generic arguments for this particular reference to `I`.
|
||||
pub fn lower_generic_args_of_path_segment(
|
||||
&self,
|
||||
span: Span,
|
||||
@ -293,14 +327,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
args
|
||||
}
|
||||
|
||||
/// Given the type/lifetime/const arguments provided to some path (along with
|
||||
/// an implicit `Self`, if this is a trait reference), returns the complete
|
||||
/// set of generic arguments. This may involve applying defaulted type parameters.
|
||||
/// Lower the generic arguments provided to some path.
|
||||
///
|
||||
/// Constraints on associated types are not converted here but
|
||||
/// separately in `add_predicates_for_ast_type_binding`.
|
||||
/// If this is a trait reference, you also need to pass the self type `self_ty`.
|
||||
/// The lowering process may involve applying defaulted type parameters.
|
||||
///
|
||||
/// Example:
|
||||
/// Associated item bindings are not handled here!
|
||||
///
|
||||
/// ### Example
|
||||
///
|
||||
/// ```ignore (illustrative)
|
||||
/// T: std::ops::Index<usize, Output = u32>
|
||||
@ -589,16 +623,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
if let Some(b) = item_segment.args().bindings.first() {
|
||||
prohibit_assoc_item_binding(self.tcx(), b.span, Some((item_segment, span)));
|
||||
}
|
||||
|
||||
args
|
||||
}
|
||||
|
||||
/// Instantiates the path for the given trait reference, assuming that it's
|
||||
/// bound to a valid trait type. Returns the `DefId` of the defining trait.
|
||||
/// The type _cannot_ be a type other than a trait type.
|
||||
/// Lower a trait reference as found in an impl header as the implementee.
|
||||
///
|
||||
/// If the `projections` argument is `None`, then assoc type bindings like `Foo<T = X>`
|
||||
/// are disallowed. Otherwise, they are pushed onto the vector given.
|
||||
/// The self type `self_ty` is the implementer of the trait.
|
||||
pub fn lower_impl_trait_ref(
|
||||
&self,
|
||||
trait_ref: &hir::TraitRef<'tcx>,
|
||||
@ -616,25 +646,29 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
)
|
||||
}
|
||||
|
||||
/// Given a trait bound like `Debug`, applies that trait bound the given self-type to construct
|
||||
/// a full trait reference. The resulting trait reference is returned. This may also generate
|
||||
/// auxiliary bounds, which are added to `bounds`.
|
||||
/// Lower a polymorphic trait reference given a self type into `bounds`.
|
||||
///
|
||||
/// Example:
|
||||
/// *Polymorphic* in the sense that it may bind late-bound vars.
|
||||
///
|
||||
/// ```ignore (illustrative)
|
||||
/// poly_trait_ref = Iterator<Item = u32>
|
||||
/// self_ty = Foo
|
||||
/// ```
|
||||
/// This may generate auxiliary bounds if the trait reference contains associated item bindings.
|
||||
///
|
||||
/// this would return `Foo: Iterator` and add `<Foo as Iterator>::Item = u32` into `bounds`.
|
||||
/// ### Example
|
||||
///
|
||||
/// Given the trait ref `Iterator<Item = u32>` and the self type `Ty`, this will add the
|
||||
///
|
||||
/// 1. *trait predicate* `<Ty as Iterator>` (known as `Foo: Iterator` in surface syntax) and the
|
||||
/// 2. *projection predicate* `<Ty as Iterator>::Item = u32`
|
||||
///
|
||||
/// to `bounds`.
|
||||
///
|
||||
/// ### A Note on Binders
|
||||
///
|
||||
/// Against our usual convention, there is an implied binder around the `self_ty` and the
|
||||
/// `trait_ref` here. So they may reference late-bound vars.
|
||||
///
|
||||
/// **A note on binders:** against our usual convention, there is an implied binder around
|
||||
/// the `self_ty` and `poly_trait_ref` parameters here. So they may reference bound regions.
|
||||
/// If for example you had `for<'a> Foo<'a>: Bar<'a>`, then the `self_ty` would be `Foo<'a>`
|
||||
/// where `'a` is a bound region at depth 0. Similarly, the `poly_trait_ref` would be
|
||||
/// `Bar<'a>`. The returned poly-trait-ref will have this binder instantiated explicitly,
|
||||
/// however.
|
||||
/// where `'a` is a bound region at depth 0. Similarly, the `trait_ref` would be `Bar<'a>`.
|
||||
/// The lowered poly-trait-ref will track this binder explicitly, however.
|
||||
#[instrument(level = "debug", skip(self, span, constness, bounds))]
|
||||
pub(crate) fn lower_poly_trait_ref(
|
||||
&self,
|
||||
@ -702,6 +736,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
arg_count
|
||||
}
|
||||
|
||||
/// Lower a monomorphic trait reference given a self type while prohibiting associated item bindings.
|
||||
///
|
||||
/// *Monomorphic* in the sense that it doesn't bind any late-bound vars.
|
||||
fn lower_mono_trait_ref(
|
||||
&self,
|
||||
span: Span,
|
||||
@ -709,7 +746,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
self_ty: Ty<'tcx>,
|
||||
trait_segment: &hir::PathSegment<'tcx>,
|
||||
is_impl: bool,
|
||||
// FIXME(effects) move all host param things in astconv to hir lowering
|
||||
// FIXME(effects): Move all host param things in HIR ty lowering to AST lowering.
|
||||
constness: ty::BoundConstness,
|
||||
) -> ty::TraitRef<'tcx> {
|
||||
self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, is_impl);
|
||||
@ -762,10 +799,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
}
|
||||
}
|
||||
|
||||
// Search for a bound on a type parameter which includes the associated item
|
||||
// given by `assoc_name`. `ty_param_def_id` is the `DefId` of the type parameter
|
||||
// This function will fail if there are no suitable bounds or there is
|
||||
// any ambiguity.
|
||||
/// Search for a trait bound on a type parameter whose trait defines the associated type given by `assoc_name`.
|
||||
///
|
||||
/// This fails if there is no such bound in the list of candidates or if there are multiple
|
||||
/// candidates in which case it reports ambiguity.
|
||||
///
|
||||
/// `ty_param_def_id` is the `LocalDefId` of the type parameter.
|
||||
fn probe_single_ty_param_bound_for_assoc_ty(
|
||||
&self,
|
||||
ty_param_def_id: LocalDefId,
|
||||
@ -803,8 +842,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
)
|
||||
}
|
||||
|
||||
// Checks that `bounds` contains exactly one element and reports appropriate
|
||||
// errors otherwise.
|
||||
/// Search for a single trait bound whose trait defines the associated item given by `assoc_name`.
|
||||
///
|
||||
/// This fails if there is no such bound in the list of candidates or if there are multiple
|
||||
/// candidates in which case it reports ambiguity.
|
||||
#[instrument(level = "debug", skip(self, all_candidates, ty_param_name, binding), ret)]
|
||||
fn probe_single_bound_for_assoc_item<I>(
|
||||
&self,
|
||||
@ -927,12 +968,31 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
Ok(bound)
|
||||
}
|
||||
|
||||
// Create a type from a path to an associated type or to an enum variant.
|
||||
// For a path `A::B::C::D`, `qself_ty` and `qself_def` are the type and def for `A::B::C`
|
||||
// and item_segment is the path segment for `D`. We return a type and a def for
|
||||
// the whole path.
|
||||
// Will fail except for `T::A` and `Self::A`; i.e., if `qself_ty`/`qself_def` are not a type
|
||||
// parameter or `Self`.
|
||||
/// Lower a [type-relative] path referring to an associated type or to an enum variant.
|
||||
///
|
||||
/// If the path refers to an enum variant and `permit_variants` holds,
|
||||
/// the returned type is simply the provided self type `qself_ty`.
|
||||
///
|
||||
/// A path like `A::B::C::D` is understood as `<A::B::C>::D`. I.e.,
|
||||
/// `qself_ty` / `qself` is `A::B::C` and `assoc_segment` is `D`.
|
||||
/// We return the lowered type and the `DefId` for the whole path.
|
||||
///
|
||||
/// We only support associated type paths whose self type is a type parameter or a `Self`
|
||||
/// type alias (in a trait impl) like `T::Ty` (where `T` is a ty param) or `Self::Ty`.
|
||||
/// We **don't** support paths whose self type is an arbitrary type like `Struct::Ty` where
|
||||
/// struct `Struct` impls an in-scope trait that defines an associated type called `Ty`.
|
||||
/// For the latter case, we report ambiguity.
|
||||
/// While desirable to support, the implemention would be non-trivial. Tracked in [#22519].
|
||||
///
|
||||
/// At the time of writing, *inherent associated types* are also resolved here. This however
|
||||
/// is [problematic][iat]. A proper implementation would be as non-trivial as the one
|
||||
/// described in the previous paragraph and their modeling of projections would likely be
|
||||
/// very similar in nature.
|
||||
///
|
||||
/// [type-relative]: hir::QPath::TypeRelative
|
||||
/// [#22519]: https://github.com/rust-lang/rust/issues/22519
|
||||
/// [iat]: https://github.com/rust-lang/rust/issues/8995#issuecomment-1569208403
|
||||
//
|
||||
// NOTE: When this function starts resolving `Trait::AssocTy` successfully
|
||||
// it should also start reporting the `BARE_TRAIT_OBJECTS` lint.
|
||||
#[instrument(level = "debug", skip(self, hir_ref_id, span, qself, assoc_segment), fields(assoc_ident=?assoc_segment.ident), ret)]
|
||||
@ -1064,6 +1124,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(inherent_associated_types, #106719): Support self types other than ADTs.
|
||||
if let Some((ty, did)) = self.probe_inherent_assoc_ty(
|
||||
assoc_ident,
|
||||
assoc_segment,
|
||||
@ -1233,8 +1294,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
// Don't attempt to look up inherent associated types when the feature is not enabled.
|
||||
// Theoretically it'd be fine to do so since we feature-gate their definition site.
|
||||
// However, due to current limitations of the implementation (caused by us performing
|
||||
// selection in AstConv), IATs can lead to cycle errors (#108491, #110106) which mask the
|
||||
// feature-gate error, needlessly confusing users that use IATs by accident (#113265).
|
||||
// selection during HIR ty lowering instead of in the trait solver), IATs can lead to cycle
|
||||
// errors (#108491) which mask the feature-gate error, needlessly confusing users
|
||||
// who use IATs by accident (#113265).
|
||||
if !tcx.features().inherent_associated_types {
|
||||
return Ok(None);
|
||||
}
|
||||
@ -1289,7 +1351,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
self.check_assoc_ty(assoc_item, name, def_scope, block, span);
|
||||
|
||||
// FIXME(fmease): Currently creating throwaway `parent_args` to please
|
||||
// `create_args_for_associated_item`. Modify the latter instead (or sth. similar) to
|
||||
// `lower_generic_args_of_assoc_item`. Modify the latter instead (or sth. similar) to
|
||||
// not require the parent args logic.
|
||||
let parent_args = ty::GenericArgs::identity_for_item(tcx, impl_);
|
||||
let args = self.lower_generic_args_of_assoc_item(span, assoc_item, segment, parent_args);
|
||||
@ -1490,6 +1552,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Lower a qualified path to a type.
|
||||
fn lower_qpath(
|
||||
&self,
|
||||
span: Span,
|
||||
@ -1676,6 +1739,22 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
emitted
|
||||
}
|
||||
|
||||
/// Probe path segments that are semantically allowed to have generic arguments.
|
||||
///
|
||||
/// ### Example
|
||||
///
|
||||
/// ```ignore (illustrative)
|
||||
/// Option::None::<()>
|
||||
/// // ^^^^ permitted to have generic args
|
||||
///
|
||||
/// // ==> [GenericPathSegment(Option_def_id, 1)]
|
||||
///
|
||||
/// Option::<()>::None
|
||||
/// // ^^^^^^ ^^^^ *not* permitted to have generic args
|
||||
/// // permitted to have generic args
|
||||
///
|
||||
/// // ==> [GenericPathSegment(Option_def_id, 0)]
|
||||
/// ```
|
||||
// FIXME(eddyb, varkor) handle type paths here too, not just value ones.
|
||||
pub fn probe_generic_path_segments(
|
||||
&self,
|
||||
@ -1685,9 +1764,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
def_id: DefId,
|
||||
span: Span,
|
||||
) -> Vec<GenericPathSegment> {
|
||||
// We need to extract the type parameters supplied by the user in
|
||||
// We need to extract the generic arguments supplied by the user in
|
||||
// the path `path`. Due to the current setup, this is a bit of a
|
||||
// tricky-process; the problem is that resolve only tells us the
|
||||
// tricky process; the problem is that resolve only tells us the
|
||||
// end-point of the path resolution, and not the intermediate steps.
|
||||
// Luckily, we can (at least for now) deduce the intermediate steps
|
||||
// just from the end-point.
|
||||
@ -1698,35 +1777,35 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
//
|
||||
// struct Foo<T>(...)
|
||||
//
|
||||
// In this case, the parameters are declared in the type space.
|
||||
// In this case, the generic arguments are declared in the type space.
|
||||
//
|
||||
// 2. Reference to a constructor of an enum variant:
|
||||
//
|
||||
// enum E<T> { Foo(...) }
|
||||
//
|
||||
// In this case, the parameters are defined in the type space,
|
||||
// In this case, the generic arguments are defined in the type space,
|
||||
// but may be specified either on the type or the variant.
|
||||
//
|
||||
// 3. Reference to a fn item or a free constant:
|
||||
// 3. Reference to a free function or constant:
|
||||
//
|
||||
// fn foo<T>() { }
|
||||
// fn foo<T>() {}
|
||||
//
|
||||
// In this case, the path will again always have the form
|
||||
// `a::b::foo::<T>` where only the final segment should have
|
||||
// type parameters. However, in this case, those parameters are
|
||||
// declared on a value, and hence are in the `FnSpace`.
|
||||
// `a::b::foo::<T>` where only the final segment should have generic
|
||||
// arguments. However, in this case, those arguments are declared on
|
||||
// a value, and hence are in the value space.
|
||||
//
|
||||
// 4. Reference to a method or an associated constant:
|
||||
// 4. Reference to an associated function or constant:
|
||||
//
|
||||
// impl<A> SomeStruct<A> {
|
||||
// fn foo<B>(...)
|
||||
// fn foo<B>(...) {}
|
||||
// }
|
||||
//
|
||||
// Here we can have a path like
|
||||
// `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
|
||||
// may appear in two places. The penultimate segment,
|
||||
// `SomeStruct::<A>`, contains parameters in TypeSpace, and the
|
||||
// final segment, `foo::<B>` contains parameters in fn space.
|
||||
// Here we can have a path like `a::b::SomeStruct::<A>::foo::<B>`,
|
||||
// in which case generic arguments may appear in two places. The
|
||||
// penultimate segment, `SomeStruct::<A>`, contains generic arguments
|
||||
// in the type space, and the final segment, `foo::<B>` contains
|
||||
// generic arguments in value space.
|
||||
//
|
||||
// The first step then is to categorize the segments appropriately.
|
||||
|
||||
@ -1804,7 +1883,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
generic_segments
|
||||
}
|
||||
|
||||
/// Check a type `Path` and convert it to a `Ty`.
|
||||
/// Lower a type `Path` to a type.
|
||||
pub fn lower_path(
|
||||
&self,
|
||||
opt_self_ty: Option<Ty<'tcx>>,
|
||||
@ -1844,7 +1923,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
self.lower_path_segment(span, did, path.segments.last().unwrap())
|
||||
}
|
||||
Res::Def(kind @ DefKind::Variant, def_id) if permit_variants => {
|
||||
// Convert "variant type" as if it were a real type.
|
||||
// Lower "variant type" as if it were a real type.
|
||||
// The resulting `Ty` is type of the variant's enum for now.
|
||||
assert_eq!(opt_self_ty, None);
|
||||
|
||||
@ -2045,8 +2124,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
}
|
||||
}
|
||||
|
||||
// Converts a hir id corresponding to a type parameter to
|
||||
// a early-bound `ty::Param` or late-bound `ty::Bound`.
|
||||
/// Lower a type parameter from the HIR to our internal notion of a type.
|
||||
///
|
||||
/// Early-bound type parameters get lowered to [`ty::Param`]
|
||||
/// and late-bound ones to [`ty::Bound`].
|
||||
pub(crate) fn lower_ty_param(&self, hir_id: hir::HirId) -> Ty<'tcx> {
|
||||
let tcx = self.tcx();
|
||||
match tcx.named_bound_var(hir_id) {
|
||||
@ -2070,8 +2151,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
}
|
||||
}
|
||||
|
||||
// Converts a hir id corresponding to a const parameter to
|
||||
// a early-bound `ConstKind::Param` or late-bound `ConstKind::Bound`.
|
||||
/// Lower a const parameter from the HIR to our internal notion of a constant.
|
||||
///
|
||||
/// Early-bound const parameters get lowered to [`ty::ConstKind::Param`]
|
||||
/// and late-bound ones to [`ty::ConstKind::Bound`].
|
||||
pub(crate) fn lower_const_param(&self, hir_id: hir::HirId, param_ty: Ty<'tcx>) -> Const<'tcx> {
|
||||
let tcx = self.tcx();
|
||||
match tcx.named_bound_var(hir_id) {
|
||||
@ -2092,14 +2175,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses the programmer's textual representation of a type into our
|
||||
/// internal notion of a type.
|
||||
/// Lower a type from the HIR to our internal notion of a type.
|
||||
pub fn lower_ty(&self, ast_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
|
||||
self.lower_ty_common(ast_ty, false, false)
|
||||
}
|
||||
|
||||
/// Parses the programmer's textual representation of a type into our
|
||||
/// internal notion of a type. This is meant to be used within a path.
|
||||
/// Lower a type inside of a path from the HIR to our internal notion of a type.
|
||||
pub fn lower_ty_in_path(&self, ast_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
|
||||
self.lower_ty_common(ast_ty, false, true)
|
||||
}
|
||||
@ -2202,8 +2283,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
sig.instantiate_identity()
|
||||
};
|
||||
|
||||
// Bound vars are also inherited from `sig_id`. They will be
|
||||
// rebinded later in `ty_of_fn`.
|
||||
// Bound vars are also inherited from `sig_id`.
|
||||
// They will be rebound later in `lower_fn_ty`.
|
||||
let sig = sig.skip_binder();
|
||||
|
||||
match idx {
|
||||
@ -2212,8 +2293,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
}
|
||||
}
|
||||
|
||||
/// Turns a `hir::Ty` into a `Ty`. For diagnostics' purposes we keep track of whether trait
|
||||
/// objects are borrowed like `&dyn Trait` to avoid emitting redundant errors.
|
||||
/// Lower a type from the HIR to our internal notion of a type given some extra data for diagnostics.
|
||||
///
|
||||
/// Extra diagnostic data:
|
||||
///
|
||||
/// 1. `borrowed`: Whether trait object types are borrowed like in `&dyn Trait`.
|
||||
/// Used to avoid emitting redundant errors.
|
||||
/// 2. `in_path`: Whether the type appears inside of a path.
|
||||
/// Used to provide correct diagnostics for bare trait object types.
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
fn lower_ty_common(&self, ast_ty: &hir::Ty<'tcx>, borrowed: bool, in_path: bool) -> Ty<'tcx> {
|
||||
let tcx = self.tcx();
|
||||
@ -2348,6 +2435,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
result_ty
|
||||
}
|
||||
|
||||
/// Lower an opaque type (i.e., an existential impl-Trait type) from the HIR.
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
fn lower_opaque_ty(
|
||||
&self,
|
||||
@ -2405,6 +2493,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
}
|
||||
}
|
||||
|
||||
/// Lower a function type from the HIR to our internal notion of a function signature.
|
||||
#[instrument(level = "debug", skip(self, hir_id, unsafety, abi, decl, generics, hir_ty), ret)]
|
||||
pub fn lower_fn_ty(
|
||||
&self,
|
||||
@ -2484,7 +2573,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
if !self.allow_infer() && !(visitor.0.is_empty() && infer_replacements.is_empty()) {
|
||||
// We always collect the spans for placeholder types when evaluating `fn`s, but we
|
||||
// only want to emit an error complaining about them if infer types (`_`) are not
|
||||
// allowed. `allow_ty_infer` gates this behavior. We check for the presence of
|
||||
// allowed. `allow_infer` gates this behavior. We check for the presence of
|
||||
// `ident_span` to not emit an error twice when we have `fn foo(_: fn() -> _)`.
|
||||
|
||||
let mut diag = crate::collect::placeholder_type_error_diag(
|
||||
@ -2610,7 +2699,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
}
|
||||
|
||||
/// Given the bounds on an object, determines what single region bound (if any) we can
|
||||
/// use to summarize this type. The basic idea is that we will use the bound the user
|
||||
/// use to summarize this type.
|
||||
///
|
||||
/// The basic idea is that we will use the bound the user
|
||||
/// provided, if they provided one, and otherwise search the supertypes of trait bounds
|
||||
/// for region bounds. It may be that we can derive no bound at all, in which case
|
||||
/// we return `None`.
|
||||
|
@ -18,6 +18,7 @@ use smallvec::{smallvec, SmallVec};
|
||||
use super::HirTyLowerer;
|
||||
|
||||
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
/// Lower a trait object type from the HIR to our internal notion of a type.
|
||||
pub(super) fn lower_trait_object_ty(
|
||||
&self,
|
||||
span: Span,
|
||||
|
@ -1,5 +1,5 @@
|
||||
//! Bounds are restrictions applied to some types after they've been converted into the
|
||||
//! `ty` form from the HIR.
|
||||
//! Bounds are restrictions applied to some types after they've been lowered from the HIR to the
|
||||
//! [`rustc_middle::ty`] form.
|
||||
|
||||
use rustc_hir::LangItem;
|
||||
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
|
||||
|
@ -382,8 +382,8 @@ fn check_opaque_meets_bounds<'tcx>(
|
||||
Ok(()) => {}
|
||||
Err(ty_err) => {
|
||||
// Some types may be left "stranded" if they can't be reached
|
||||
// from an astconv'd bound but they're mentioned in the HIR. This
|
||||
// will happen, e.g., when a nested opaque is inside of a non-
|
||||
// from a lowered rustc_middle bound but they're mentioned in the HIR.
|
||||
// This will happen, e.g., when a nested opaque is inside of a non-
|
||||
// existent associated type, like `impl Trait<Missing = impl Trait>`.
|
||||
// See <tests/ui/impl-trait/stranded-opaque.rs>.
|
||||
let ty_err = ty_err.to_string(tcx);
|
||||
|
@ -746,7 +746,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
||||
|
||||
// We may not collect all RPITITs that we see in the HIR for a trait signature
|
||||
// because an RPITIT was located within a missing item. Like if we have a sig
|
||||
// returning `-> Missing<impl Sized>`, that gets converted to `-> [type error]`,
|
||||
// returning `-> Missing<impl Sized>`, that gets converted to `-> {type error}`,
|
||||
// and when walking through the signature we end up never collecting the def id
|
||||
// of the `impl Sized`. Insert that here, so we don't ICE later.
|
||||
for assoc_item in tcx.associated_types_for_impl_traits_in_associated_fn(trait_m.def_id) {
|
||||
|
@ -760,7 +760,7 @@ impl<'tcx> RegionResolutionVisitor<'tcx> {
|
||||
|
||||
fn enter_node_scope_with_dtor(&mut self, id: hir::ItemLocalId) {
|
||||
// If node was previously marked as a terminating scope during the
|
||||
// recursive visit of its parent node in the AST, then we need to
|
||||
// recursive visit of its parent node in the HIR, then we need to
|
||||
// account for the destruction scope representing the scope of
|
||||
// the destructors that run immediately after it completes.
|
||||
if self.terminating_scopes.contains(&id) {
|
||||
|
@ -272,7 +272,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
|
||||
}
|
||||
Some(ty::ImplPolarity::Negative) => {
|
||||
let ast::ImplPolarity::Negative(span) = impl_.polarity else {
|
||||
bug!("impl_polarity query disagrees with impl's polarity in AST");
|
||||
bug!("impl_polarity query disagrees with impl's polarity in HIR");
|
||||
};
|
||||
// FIXME(#27579): what amount of WF checking do we need for neg impls?
|
||||
if let hir::Defaultness::Default { .. } = impl_.defaultness {
|
||||
|
@ -88,13 +88,12 @@ pub fn provide(providers: &mut Providers) {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Context specific to some particular item. This is what implements
|
||||
/// [`AstConv`].
|
||||
/// Context specific to some particular item. This is what implements [`HirTyLowerer`].
|
||||
///
|
||||
/// # `ItemCtxt` vs `FnCtxt`
|
||||
///
|
||||
/// `ItemCtxt` is primarily used to type-check item signatures and lower them
|
||||
/// from HIR to their [`ty::Ty`] representation, which is exposed using [`AstConv`].
|
||||
/// from HIR to their [`ty::Ty`] representation, which is exposed using [`HirTyLowerer`].
|
||||
/// It's also used for the bodies of items like structs where the body (the fields)
|
||||
/// are just signatures.
|
||||
///
|
||||
@ -111,11 +110,11 @@ pub fn provide(providers: &mut Providers) {
|
||||
/// `ItemCtxt` has information about the predicates that are defined
|
||||
/// on the trait. Unfortunately, this predicate information is
|
||||
/// available in various different forms at various points in the
|
||||
/// process. So we can't just store a pointer to e.g., the AST or the
|
||||
/// process. So we can't just store a pointer to e.g., the HIR or the
|
||||
/// parsed ty form, we have to be more flexible. To this end, the
|
||||
/// `ItemCtxt` is parameterized by a `DefId` that it uses to satisfy
|
||||
/// `get_type_parameter_bounds` requests, drawing the information from
|
||||
/// the AST (`hir::Generics`), recursively.
|
||||
/// `probe_ty_param_bounds` requests, drawing the information from
|
||||
/// the HIR (`hir::Generics`), recursively.
|
||||
pub struct ItemCtxt<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
item_def_id: LocalDefId,
|
||||
@ -785,8 +784,7 @@ fn lower_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) {
|
||||
tcx.ensure().predicates_of(f.did);
|
||||
}
|
||||
|
||||
// Convert the ctor, if any. This also registers the variant as
|
||||
// an item.
|
||||
// Lower the ctor, if any. This also registers the variant as an item.
|
||||
if let Some(ctor_def_id) = variant.ctor_def_id() {
|
||||
lower_variant_ctor(tcx, ctor_def_id.expect_local());
|
||||
}
|
||||
@ -1545,7 +1543,7 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::ImplTrai
|
||||
// we have a const impl, but for a trait without `#[const_trait]`, so
|
||||
// without the host param. If we continue with the HIR trait ref, we get
|
||||
// ICEs for generic arg count mismatch. We do a little HIR editing to
|
||||
// make astconv happy.
|
||||
// make HIR ty lowering happy.
|
||||
let mut path_segments = ast_trait_ref.path.segments.to_vec();
|
||||
let last_segment = path_segments.len() - 1;
|
||||
let mut args = *path_segments[last_segment].args();
|
||||
|
@ -138,8 +138,8 @@ pub(super) fn explicit_item_bounds_with_filter(
|
||||
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
|
||||
opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter)
|
||||
}
|
||||
// Since RPITITs are astconv'd as projections in `ast_ty_to_ty`, when we're asking
|
||||
// for the item bounds of the *opaques* in a trait's default method signature, we
|
||||
// Since RPITITs are lowered as projections in `<dyn HirTyLowerer>::lower_ty`, when we're
|
||||
// asking for the item bounds of the *opaques* in a trait's default method signature, we
|
||||
// need to map these projections back to opaques.
|
||||
hir::Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait: true, origin, .. }),
|
||||
|
@ -542,8 +542,8 @@ pub(super) fn explicit_predicates_of<'tcx>(
|
||||
}
|
||||
|
||||
/// Ensures that the super-predicates of the trait with a `DefId`
|
||||
/// of `trait_def_id` are converted and stored. This also ensures that
|
||||
/// the transitive super-predicates are converted.
|
||||
/// of `trait_def_id` are lowered and stored. This also ensures that
|
||||
/// the transitive super-predicates are lowered.
|
||||
pub(super) fn super_predicates_of(
|
||||
tcx: TyCtxt<'_>,
|
||||
trait_def_id: LocalDefId,
|
||||
@ -574,8 +574,8 @@ pub(super) fn implied_predicates_of(
|
||||
}
|
||||
|
||||
/// Ensures that the super-predicates of the trait with a `DefId`
|
||||
/// of `trait_def_id` are converted and stored. This also ensures that
|
||||
/// the transitive super-predicates are converted.
|
||||
/// of `trait_def_id` are lowered and stored. This also ensures that
|
||||
/// the transitive super-predicates are lowered.
|
||||
pub(super) fn implied_predicates_with_filter(
|
||||
tcx: TyCtxt<'_>,
|
||||
trait_def_id: DefId,
|
||||
@ -615,7 +615,7 @@ pub(super) fn implied_predicates_with_filter(
|
||||
&*tcx.arena.alloc_from_iter(superbounds.clauses().chain(where_bounds_that_match));
|
||||
debug!(?implied_bounds);
|
||||
|
||||
// Now require that immediate supertraits are converted, which will, in
|
||||
// Now require that immediate supertraits are lowered, which will, in
|
||||
// turn, reach indirect supertraits, so we detect cycles now instead of
|
||||
// overflowing during elaboration. Same for implied predicates, which
|
||||
// make sure we walk into associated type bounds.
|
||||
@ -656,7 +656,7 @@ pub(super) fn type_param_predicates(
|
||||
use rustc_hir::*;
|
||||
use rustc_middle::ty::Ty;
|
||||
|
||||
// In the AST, bounds can derive from two places. Either
|
||||
// In the HIR, bounds can derive from two places. Either
|
||||
// written inline like `<T: Foo>` or in a where-clause like
|
||||
// `where T: Foo`.
|
||||
|
||||
@ -714,10 +714,11 @@ pub(super) fn type_param_predicates(
|
||||
}
|
||||
|
||||
impl<'tcx> ItemCtxt<'tcx> {
|
||||
/// Finds bounds from `hir::Generics`. This requires scanning through the
|
||||
/// AST. We do this to avoid having to convert *all* the bounds, which
|
||||
/// would create artificial cycles. Instead, we can only convert the
|
||||
/// bounds for a type parameter `X` if `X::Foo` is used.
|
||||
/// Finds bounds from `hir::Generics`.
|
||||
///
|
||||
/// This requires scanning through the HIR.
|
||||
/// We do this to avoid having to lower *all* the bounds, which would create artificial cycles.
|
||||
/// Instead, we can only lower the bounds for a type parameter `X` if `X::Foo` is used.
|
||||
#[instrument(level = "trace", skip(self, ast_generics))]
|
||||
fn probe_ty_param_bounds_in_generics(
|
||||
&self,
|
||||
|
@ -1917,7 +1917,7 @@ fn is_late_bound_map(
|
||||
///
|
||||
/// If we conservatively considered `'a` unconstrained then we could break users who had written code before
|
||||
/// we started correctly handling aliases. If we considered `'a` constrained then it would become late bound
|
||||
/// causing an error during astconv as the `'a` is not constrained by the input type `<() as Trait<'a>>::Assoc`
|
||||
/// causing an error during HIR ty lowering as the `'a` is not constrained by the input type `<() as Trait<'a>>::Assoc`
|
||||
/// but appears in the output type `<() as Trait<'a>>::Assoc`.
|
||||
///
|
||||
/// We must therefore "look into" the `Alias` to see whether we should consider `'a` constrained or not.
|
||||
@ -1970,8 +1970,8 @@ fn is_late_bound_map(
|
||||
None,
|
||||
hir::Path { res: Res::Def(DefKind::TyAlias, alias_def), segments, span },
|
||||
)) => {
|
||||
// See comments on `ConstrainedCollectorPostAstConv` for why this arm does not just consider
|
||||
// args to be unconstrained.
|
||||
// See comments on `ConstrainedCollectorPostHirTyLowering` for why this arm does not
|
||||
// just consider args to be unconstrained.
|
||||
let generics = self.tcx.generics_of(alias_def);
|
||||
let mut walker = ConstrainedCollectorPostHirTyLowering {
|
||||
arg_is_constrained: vec![false; generics.params.len()].into_boxed_slice(),
|
||||
|
@ -97,10 +97,10 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
||||
// I believe this match arm is only needed for GAT but I am not 100% sure - BoxyUwU
|
||||
Node::Ty(hir_ty @ hir::Ty { kind: TyKind::Path(QPath::TypeRelative(_, segment)), .. }) => {
|
||||
// Find the Item containing the associated type so we can create an ItemCtxt.
|
||||
// Using the ItemCtxt convert the HIR for the unresolved assoc type into a
|
||||
// Using the ItemCtxt lower the HIR for the unresolved assoc type into a
|
||||
// ty which is a fully resolved projection.
|
||||
// For the code example above, this would mean converting Self::Assoc<3>
|
||||
// into a ty::Alias(ty::Projection, <Self as Foo>::Assoc<3>)
|
||||
// For the code example above, this would mean lowering `Self::Assoc<3>`
|
||||
// to a ty::Alias(ty::Projection, `<Self as Foo>::Assoc<3>`).
|
||||
let item_def_id = tcx
|
||||
.hir()
|
||||
.parent_owner_iter(hir_id)
|
||||
|
@ -30,8 +30,8 @@ several major phases:
|
||||
The type checker is defined into various submodules which are documented
|
||||
independently:
|
||||
|
||||
- astconv: converts the AST representation of types
|
||||
into the `ty` representation.
|
||||
- astconv: lowers type-system entities from the [HIR][hir] to the
|
||||
[`rustc_middle::ty`] representation.
|
||||
|
||||
- collect: computes the types of each top-level item and enters them into
|
||||
the `tcx.types` table for later use.
|
||||
@ -211,8 +211,16 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// A quasi-deprecated helper used in rustdoc and clippy to get
|
||||
/// the type from a HIR node.
|
||||
/// Lower a [`hir::Ty`] to a [`Ty`].
|
||||
///
|
||||
/// <div class="warning">
|
||||
///
|
||||
/// This function is **quasi-deprecated**. It can cause ICEs if called inside of a body
|
||||
/// (of a function or constant) and especially if it contains inferred types (`_`).
|
||||
///
|
||||
/// It's used in rustdoc and Clippy.
|
||||
///
|
||||
/// </div>
|
||||
pub fn lower_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
|
||||
// In case there are any projections, etc., find the "environment"
|
||||
// def-ID that will be used to determine the traits/predicates in
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Constraint construction and representation
|
||||
//!
|
||||
//! The second pass over the AST determines the set of constraints.
|
||||
//! The second pass over the HIR determines the set of constraints.
|
||||
//! We walk the set of items and, for each member, generate new constraints.
|
||||
|
||||
use hir::def_id::{DefId, LocalDefId};
|
||||
|
@ -826,7 +826,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
);
|
||||
}
|
||||
QPath::TypeRelative(ref qself, ref segment) => {
|
||||
// Don't use `self.to_ty`, since this will register a WF obligation.
|
||||
// Don't use `self.lower_ty`, since this will register a WF obligation.
|
||||
// If we're trying to call a nonexistent method on a trait
|
||||
// (e.g. `MyTrait::missing_method`), then resolution will
|
||||
// give us a `QPath::TypeRelative` with a trait object as
|
||||
|
@ -360,8 +360,8 @@ impl<'a, 'tcx> HirTyLowerer<'tcx> for FnCtxt<'a, 'tcx> {
|
||||
/// The `ty` representation of a user-provided type. Depending on the use-site
|
||||
/// we want to either use the unnormalized or the normalized form of this type.
|
||||
///
|
||||
/// This is a bridge between the interface of `AstConv`, which outputs a raw `Ty`,
|
||||
/// and the API in this module, which expect `Ty` to be fully normalized.
|
||||
/// This is a bridge between the interface of HIR ty lowering, which outputs a raw
|
||||
/// `Ty`, and the API in this module, which expect `Ty` to be fully normalized.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct LoweredTy<'tcx> {
|
||||
/// The unnormalized type provided by the user.
|
||||
|
@ -957,7 +957,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
bounded_ty,
|
||||
..
|
||||
}) => {
|
||||
// FIXME: Maybe these calls to `ast_ty_to_ty` can be removed (and the ones below)
|
||||
// FIXME: Maybe these calls to `lower_ty` can be removed (and the ones below)
|
||||
let ty = self.lowerer().lower_ty(bounded_ty);
|
||||
Some((ty, bounds))
|
||||
}
|
||||
|
@ -1062,7 +1062,7 @@ pub enum ExpnKind {
|
||||
Macro(MacroKind, Symbol),
|
||||
/// Transform done by the compiler on the AST.
|
||||
AstPass(AstPass),
|
||||
/// Desugaring done by the compiler during HIR lowering.
|
||||
/// Desugaring done by the compiler during AST lowering.
|
||||
Desugaring(DesugaringKind),
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
//! Computes a normalizes-to (projection) goal for inherent associated types,
|
||||
//! `#![feature(inherent_associated_type)]`. Since astconv already determines
|
||||
//! `#![feature(inherent_associated_type)]`. Since HIR ty lowering already determines
|
||||
//! which impl the IAT is being projected from, we just:
|
||||
//! 1. instantiate generic parameters,
|
||||
//! 2. equate the self type, and
|
||||
|
@ -32,8 +32,9 @@ use std::ops::ControlFlow;
|
||||
|
||||
pub use crate::traits::{MethodViolationCode, ObjectSafetyViolation};
|
||||
|
||||
/// Returns the object safety violations that affect
|
||||
/// astconv -- currently, `Self` in supertraits. This is needed
|
||||
/// Returns the object safety violations that affect HIR ty lowering.
|
||||
///
|
||||
/// Currently that is `Self` in supertraits. This is needed
|
||||
/// because `object_safety_violations` can't be used during
|
||||
/// type collection.
|
||||
pub fn hir_ty_lowering_object_safety_violations(
|
||||
|
@ -1264,7 +1264,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
|
||||
// Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`,
|
||||
// normalizing in the process, since `type_of` returns something directly from
|
||||
// astconv (which means it's un-normalized).
|
||||
// HIR ty lowering (which means it's un-normalized).
|
||||
let source_tail = normalize_with_depth_to(
|
||||
self,
|
||||
obligation.param_env,
|
||||
|
@ -396,7 +396,7 @@ pub(crate) fn assoc_def(
|
||||
// associated type. Normally this situation
|
||||
// could only arise through a compiler bug --
|
||||
// if the user wrote a bad item name, it
|
||||
// should have failed in astconv.
|
||||
// should have failed during HIR ty lowering.
|
||||
bug!(
|
||||
"No associated type `{}` for {}",
|
||||
tcx.item_name(assoc_def_id),
|
||||
|
@ -60,7 +60,7 @@ impl AliasKind {
|
||||
/// Defines the kinds of types used by the type system.
|
||||
///
|
||||
/// Types written by the user start out as `hir::TyKind` and get
|
||||
/// converted to this representation using `AstConv::ast_ty_to_ty`.
|
||||
/// converted to this representation using `<dyn HirTyLowerer>::lower_ty`.
|
||||
#[cfg_attr(feature = "nightly", rustc_diagnostic_item = "IrTyKind")]
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
|
@ -118,10 +118,10 @@ Here the HIR sees the types without "thinking" about them, it knows that the fun
|
||||
an `u32`. As far as `hir::Ty` is concerned those might be different types. But at the `ty::Ty` level the compiler
|
||||
understands that they're the same type, in-depth lifetimes, etc...
|
||||
|
||||
To get from a `hir::Ty` to a `ty::Ty`, you can use the [`hir_ty_to_ty`][hir_ty_to_ty] function outside of bodies or
|
||||
To get from a `hir::Ty` to a `ty::Ty`, you can use the [`lower_ty`][lower_ty] function outside of bodies or
|
||||
the [`TypeckResults::node_type()`][node_type] method inside of bodies.
|
||||
|
||||
> **Warning**: Don't use `hir_ty_to_ty` inside of bodies, because this can cause ICEs.
|
||||
> **Warning**: Don't use `lower_ty` inside of bodies, because this can cause ICEs.
|
||||
|
||||
## Creating Types programmatically
|
||||
|
||||
@ -162,6 +162,6 @@ in this chapter:
|
||||
[Ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html
|
||||
[TyKind]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/ty_kind/enum.TyKind.html
|
||||
[TypeckResults]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html
|
||||
[middle_ty]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_middle/ty/struct.Ty.html
|
||||
[hir_ty]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_hir/struct.Ty.html
|
||||
[hir_ty_to_ty]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_hir_analysis/fn.hir_ty_to_ty.html
|
||||
[middle_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html
|
||||
[hir_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/struct.Ty.html
|
||||
[lower_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/fn.lower_ty.html
|
||||
|
@ -56,7 +56,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>, qpath:
|
||||
};
|
||||
let inner_span = match qpath_generic_tys(inner_qpath).next() {
|
||||
Some(hir_ty) => {
|
||||
// Reallocation of a fat pointer causes it to become thin. `hir_ty_to_ty` is safe to use
|
||||
// Reallocation of a fat pointer causes it to become thin. `lower_ty` is safe to use
|
||||
// here because `mod.rs` guarantees this lint is only run on types outside of bodies and
|
||||
// is not run on locals.
|
||||
let ty = lower_ty(cx.tcx, hir_ty);
|
||||
|
@ -193,7 +193,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
|
||||
}
|
||||
|
||||
fn check_body(&mut self, _: &LateContext<'_>, _: &hir::Body<'_>) {
|
||||
// `hir_ty_to_ty` cannot be called in `Body`s or it will panic (sometimes). But in bodies
|
||||
// `lower_ty` cannot be called in `Body`s or it will panic (sometimes). But in bodies
|
||||
// we can use `cx.typeck_results.node_type(..)` to get the `ty::Ty` from a `hir::Ty`.
|
||||
// However the `node_type()` method can *only* be called in bodies.
|
||||
if let Some(&mut StackItem::Check { ref mut in_body, .. }) = self.stack.last_mut() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
//! This is a minimal reproducer for the ICE in https://github.com/rust-lang/rust-clippy/pull/6179.
|
||||
//! The ICE is mainly caused by using `hir_ty_to_ty`. See the discussion in the PR for details.
|
||||
//! The ICE is mainly caused by using `lower_ty`. See the discussion in the PR for details.
|
||||
|
||||
#![warn(clippy::use_self)]
|
||||
#![allow(dead_code, clippy::let_with_type_underscore)]
|
||||
|
@ -1,5 +1,5 @@
|
||||
//@ run-pass
|
||||
// Test that astconv doesn't forget about mutability of &mut str
|
||||
// Test that HIR ty lowering doesn't forget about mutability of `&mut str`.
|
||||
|
||||
//@ pretty-expanded FIXME #23616
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// astconv uses `FreshTy(0)` as a dummy `Self` type when instanciating trait objects.
|
||||
// HIR ty lowering uses `FreshTy(0)` as a dummy `Self` type when instanciating trait objects.
|
||||
// This `FreshTy(0)` can leak into substs, causing ICEs in several places.
|
||||
|
||||
#![feature(trait_alias)]
|
||||
|
Loading…
x
Reference in New Issue
Block a user