Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MCP 723] Rename astconv::AstConv and related items #120926

Merged
merged 6 commits into from
Mar 22, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {}
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_ast_lowering/src/delegation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -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()
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 2 additions & 6 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down
103 changes: 46 additions & 57 deletions compiler/rustc_hir_analysis/src/astconv/bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
Expand Down Expand Up @@ -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.
///
/// ### Examples
///
/// ```text
/// fn foo<T: Debug>
/// ^ ^^^^^ `ast_bounds` parameter, in HIR form
/// |
/// `param_ty`, in ty form
/// ```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`.
Copy link
Contributor

Choose a reason for hiding this comment

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

What does "implied binder" mean here? If no binder is specified, you get an empty binder?

Copy link
Member Author

@fmease fmease Mar 22, 2024

Choose a reason for hiding this comment

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

It just means that param_ty: Ty<'tcx> may contain late-bound vars even though it's not wrapped in a Binder<'tcx, ·> (rendering them escaping I guess). Neither is ast_bounds/hir_bounds but well that param is of a HIR data type, so obviously it can't be wrapped in a Binder.

Wording is a bit poor, I guess I could've adjusted it.

/// 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,
Expand Down Expand Up @@ -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>,
Expand Down Expand Up @@ -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
///
/// **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.
/// 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,
Expand All @@ -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
Expand All @@ -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,
Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -490,29 +487,21 @@ 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
.map_bound(|projection_ty| ty::ProjectionPredicate { projection_ty, term }),
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,
Expand Down
28 changes: 13 additions & 15 deletions compiler/rustc_hir_analysis/src/astconv/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,35 +143,33 @@ 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
/// the path; so e.g., if you have `<T as Foo>::Bar`, the `DefId`
/// 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,
Expand Down
Loading