Auto merge of #120926 - fmease:astconv-no-mo, r=oli-obk

[MCP 723] Rename `astconv::AstConv` and related items

See rust-lang/compiler-team#723.
Corresponding rustc-dev-guide PR: rust-lang/rustc-dev-guide#1916.

Please consult the following *normative* list of changes here:
https://fmease.dev/rustc-dev/astconv-no-mo.html ([2024-03-22 archive link](https://web.archive.org/web/20240322054711/https://fmease.dev/rustc-dev/astconv-no-mo.html)).
This commit is contained in:
bors 2024-03-22 10:28:39 +00:00
commit eff958c59e
57 changed files with 875 additions and 830 deletions

View File

@ -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)] #[derive(Clone, Encodable, Decodable, Debug)]
pub enum GenericBound { pub enum GenericBound {
Trait(PolyTraitRef, TraitBoundModifiers), Trait(PolyTraitRef, TraitBoundModifiers),

View File

@ -480,7 +480,7 @@ pub fn walk_use_tree<'a, V: Visitor<'a>>(
try_visit!(visitor.visit_path(&use_tree.prefix, id)); try_visit!(visitor.visit_path(&use_tree.prefix, id));
match use_tree.kind { match use_tree.kind {
UseTreeKind::Simple(rename) => { 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); visit_opt!(visitor, visit_ident, rename);
} }
UseTreeKind::Glob => {} UseTreeKind::Glob => {}

View File

@ -29,11 +29,12 @@
//! item id (`item_id`) in case of impl trait or path resolution id (`path_id`) otherwise. //! 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 //! 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. //! Similarly generics, predicates and header are set to the "default" values.
//! In case of discrepancy with callee function the `NotSupportedDelegation` error will //! 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}; use crate::{ImplTraitPosition, ResolverAstLoweringExt};
@ -129,7 +130,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
) -> &'hir hir::FnDecl<'hir> { ) -> &'hir hir::FnDecl<'hir> {
let args_count = if let Some(local_sig_id) = sig_id.as_local() { let args_count = if let Some(local_sig_id) = sig_id.as_local() {
// Map may be filled incorrectly due to recursive delegation. // 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() self.resolver.fn_parameter_counts.get(&local_sig_id).cloned().unwrap_or_default()
} else { } else {
self.tcx.fn_arg_names(sig_id).len() self.tcx.fn_arg_names(sig_id).len()

View File

@ -1427,8 +1427,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
// Error if `?Trait` bounds in where clauses don't refer directly to type parameters. // 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 // 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 // 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 // keep track of the Span info. Now, `<dyn HirTyLowerer>::add_implicit_sized_bound`
// where clauses for `?Sized`. // checks both param bounds and where clauses for `?Sized`.
for pred in &generics.where_clause.predicates { for pred in &generics.where_clause.predicates {
let WherePredicate::BoundPredicate(bound_pred) = pred else { let WherePredicate::BoundPredicate(bound_pred) = pred else {
continue; continue;

View File

@ -428,10 +428,6 @@ pub enum TraitBoundModifier {
MaybeConst, 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)] #[derive(Clone, Copy, Debug, HashStable_Generic)]
pub enum GenericBound<'hir> { pub enum GenericBound<'hir> {
Trait(PolyTraitRef<'hir>, TraitBoundModifier), Trait(PolyTraitRef<'hir>, TraitBoundModifier),
@ -1860,7 +1856,7 @@ pub enum ExprKind<'hir> {
/// Wraps the expression in a terminating scope. /// Wraps the expression in a terminating scope.
/// This makes it semantically equivalent to `{ let _t = expr; _t }`. /// 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. /// An example of that is the desugaring of `for` loops.
DropTemps(&'hir Expr<'hir>), DropTemps(&'hir Expr<'hir>),
/// A `let $pat = $expr` expression. /// A `let $pat = $expr` expression.
@ -2293,7 +2289,7 @@ pub enum ImplItemKind<'hir> {
/// Bind a type to an associated type (i.e., `A = Foo`). /// Bind a type to an associated type (i.e., `A = Foo`).
/// ///
/// Bindings like `A: Debug` are represented as a special type `A = /// 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, /// 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 /// wouldn't it be better to make the `ty` field an enum like the

View File

@ -1,5 +1,5 @@
//! Bounds are restrictions applied to some types after they've been converted into the //! Bounds are restrictions applied to some types after they've been lowered from the HIR to the
//! `ty` form from the HIR. //! [`rustc_middle::ty`] form.
use rustc_hir::LangItem; use rustc_hir::LangItem;
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt}; use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};

View File

@ -382,8 +382,8 @@ fn check_opaque_meets_bounds<'tcx>(
Ok(()) => {} Ok(()) => {}
Err(ty_err) => { Err(ty_err) => {
// Some types may be left "stranded" if they can't be reached // 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 // from a lowered rustc_middle bound but they're mentioned in the HIR.
// will happen, e.g., when a nested opaque is inside of a non- // This will happen, e.g., when a nested opaque is inside of a non-
// existent associated type, like `impl Trait<Missing = impl Trait>`. // existent associated type, like `impl Trait<Missing = impl Trait>`.
// See <tests/ui/impl-trait/stranded-opaque.rs>. // See <tests/ui/impl-trait/stranded-opaque.rs>.
let ty_err = ty_err.to_string(tcx); let ty_err = ty_err.to_string(tcx);

View File

@ -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 // 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 // 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 // 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. // 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) { for assoc_item in tcx.associated_types_for_impl_traits_in_associated_fn(trait_m.def_id) {

View File

@ -760,7 +760,7 @@ impl<'tcx> RegionResolutionVisitor<'tcx> {
fn enter_node_scope_with_dtor(&mut self, id: hir::ItemLocalId) { fn enter_node_scope_with_dtor(&mut self, id: hir::ItemLocalId) {
// If node was previously marked as a terminating scope during the // 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 // account for the destruction scope representing the scope of
// the destructors that run immediately after it completes. // the destructors that run immediately after it completes.
if self.terminating_scopes.contains(&id) { if self.terminating_scopes.contains(&id) {

View File

@ -272,7 +272,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
} }
Some(ty::ImplPolarity::Negative) => { Some(ty::ImplPolarity::Negative) => {
let ast::ImplPolarity::Negative(span) = impl_.polarity else { 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? // FIXME(#27579): what amount of WF checking do we need for neg impls?
if let hir::Defaultness::Default { .. } = impl_.defaultness { if let hir::Defaultness::Default { .. } = impl_.defaultness {
@ -1866,7 +1866,7 @@ fn check_variances_for_type_defn<'tcx>(
.iter() .iter()
.filter_map(|predicate| match predicate { .filter_map(|predicate| match predicate {
hir::WherePredicate::BoundPredicate(predicate) => { hir::WherePredicate::BoundPredicate(predicate) => {
match icx.to_ty(predicate.bounded_ty).kind() { match icx.lower_ty(predicate.bounded_ty).kind() {
ty::Param(data) => Some(Parameter(data.index)), ty::Param(data) => Some(Parameter(data.index)),
_ => None, _ => None,
} }

View File

@ -40,9 +40,9 @@ use std::cell::Cell;
use std::iter; use std::iter;
use std::ops::Bound; use std::ops::Bound;
use crate::astconv::AstConv;
use crate::check::intrinsic::intrinsic_operation_unsafety; use crate::check::intrinsic::intrinsic_operation_unsafety;
use crate::errors; use crate::errors;
use crate::hir_ty_lowering::HirTyLowerer;
pub use type_of::test_opaque_hidden_types; pub use type_of::test_opaque_hidden_types;
mod generics_of; mod generics_of;
@ -88,13 +88,12 @@ pub fn provide(providers: &mut Providers) {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
/// Context specific to some particular item. This is what implements /// Context specific to some particular item. This is what implements [`HirTyLowerer`].
/// [`AstConv`].
/// ///
/// # `ItemCtxt` vs `FnCtxt` /// # `ItemCtxt` vs `FnCtxt`
/// ///
/// `ItemCtxt` is primarily used to type-check item signatures and lower them /// `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) /// It's also used for the bodies of items like structs where the body (the fields)
/// are just signatures. /// are just signatures.
/// ///
@ -111,11 +110,11 @@ pub fn provide(providers: &mut Providers) {
/// `ItemCtxt` has information about the predicates that are defined /// `ItemCtxt` has information about the predicates that are defined
/// on the trait. Unfortunately, this predicate information is /// on the trait. Unfortunately, this predicate information is
/// available in various different forms at various points in the /// 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 /// parsed ty form, we have to be more flexible. To this end, the
/// `ItemCtxt` is parameterized by a `DefId` that it uses to satisfy /// `ItemCtxt` is parameterized by a `DefId` that it uses to satisfy
/// `get_type_parameter_bounds` requests, drawing the information from /// `probe_ty_param_bounds` requests, drawing the information from
/// the AST (`hir::Generics`), recursively. /// the HIR (`hir::Generics`), recursively.
pub struct ItemCtxt<'tcx> { pub struct ItemCtxt<'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
item_def_id: LocalDefId, item_def_id: LocalDefId,
@ -277,7 +276,7 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
} }
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
convert_item(self.tcx, item.item_id()); lower_item(self.tcx, item.item_id());
reject_placeholder_type_signatures_in_item(self.tcx, item); reject_placeholder_type_signatures_in_item(self.tcx, item);
intravisit::walk_item(self, item); intravisit::walk_item(self, item);
} }
@ -315,12 +314,12 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
} }
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) { fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
convert_trait_item(self.tcx, trait_item.trait_item_id()); lower_trait_item(self.tcx, trait_item.trait_item_id());
intravisit::walk_trait_item(self, trait_item); intravisit::walk_trait_item(self, trait_item);
} }
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) { fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
convert_impl_item(self.tcx, impl_item.impl_item_id()); lower_impl_item(self.tcx, impl_item.impl_item_id());
intravisit::walk_impl_item(self, impl_item); intravisit::walk_impl_item(self, impl_item);
} }
} }
@ -344,8 +343,8 @@ impl<'tcx> ItemCtxt<'tcx> {
ItemCtxt { tcx, item_def_id, tainted_by_errors: Cell::new(None) } ItemCtxt { tcx, item_def_id, tainted_by_errors: Cell::new(None) }
} }
pub fn to_ty(&self, ast_ty: &hir::Ty<'tcx>) -> Ty<'tcx> { pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
self.astconv().ast_ty_to_ty(ast_ty) self.lowerer().lower_ty(hir_ty)
} }
pub fn hir_id(&self) -> hir::HirId { pub fn hir_id(&self) -> hir::HirId {
@ -364,7 +363,7 @@ impl<'tcx> ItemCtxt<'tcx> {
} }
} }
impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> { impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
fn tcx(&self) -> TyCtxt<'tcx> { fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx self.tcx
} }
@ -373,23 +372,14 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
self.item_def_id.to_def_id() self.item_def_id.to_def_id()
} }
fn get_type_parameter_bounds( fn allow_infer(&self) -> bool {
&self, false
span: Span,
def_id: LocalDefId,
assoc_name: Ident,
) -> ty::GenericPredicates<'tcx> {
self.tcx.at(span).type_param_predicates((self.item_def_id, def_id, assoc_name))
} }
fn re_infer(&self, _: Option<&ty::GenericParamDef>, _: Span) -> Option<ty::Region<'tcx>> { fn re_infer(&self, _: Option<&ty::GenericParamDef>, _: Span) -> Option<ty::Region<'tcx>> {
None None
} }
fn allow_ty_infer(&self) -> bool {
false
}
fn ty_infer(&self, _: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> { fn ty_infer(&self, _: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
Ty::new_error_with_message(self.tcx(), span, "bad placeholder type") Ty::new_error_with_message(self.tcx(), span, "bad placeholder type")
} }
@ -404,7 +394,16 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
ty::Const::new_error_with_message(self.tcx(), ty, span, "bad placeholder constant") ty::Const::new_error_with_message(self.tcx(), ty, span, "bad placeholder constant")
} }
fn projected_ty_from_poly_trait_ref( fn probe_ty_param_bounds(
&self,
span: Span,
def_id: LocalDefId,
assoc_name: Ident,
) -> ty::GenericPredicates<'tcx> {
self.tcx.at(span).type_param_predicates((self.item_def_id, def_id, assoc_name))
}
fn lower_assoc_ty(
&self, &self,
span: Span, span: Span,
item_def_id: DefId, item_def_id: DefId,
@ -412,7 +411,7 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
poly_trait_ref: ty::PolyTraitRef<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tcx>,
) -> Ty<'tcx> { ) -> Ty<'tcx> {
if let Some(trait_ref) = poly_trait_ref.no_bound_vars() { if let Some(trait_ref) = poly_trait_ref.no_bound_vars() {
let item_args = self.astconv().create_args_for_associated_item( let item_args = self.lowerer().lower_generic_args_of_assoc_item(
span, span,
item_def_id, item_def_id,
item_segment, item_segment,
@ -497,10 +496,6 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
ty.ty_adt_def() ty.ty_adt_def()
} }
fn set_tainted_by_errors(&self, err: ErrorGuaranteed) {
self.tainted_by_errors.set(Some(err));
}
fn record_ty(&self, _hir_id: hir::HirId, _ty: Ty<'tcx>, _span: Span) { fn record_ty(&self, _hir_id: hir::HirId, _ty: Ty<'tcx>, _span: Span) {
// There's no place to record types from signatures? // There's no place to record types from signatures?
} }
@ -508,6 +503,10 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
fn infcx(&self) -> Option<&InferCtxt<'tcx>> { fn infcx(&self) -> Option<&InferCtxt<'tcx>> {
None None
} }
fn set_tainted_by_errors(&self, err: ErrorGuaranteed) {
self.tainted_by_errors.set(Some(err));
}
} }
/// Synthesize a new lifetime name that doesn't clash with any of the lifetimes already present. /// Synthesize a new lifetime name that doesn't clash with any of the lifetimes already present.
@ -547,9 +546,10 @@ fn get_new_lifetime_name<'tcx>(
(1..).flat_map(a_to_z_repeat_n).find(|lt| !existing_lifetimes.contains(lt.as_str())).unwrap() (1..).flat_map(a_to_z_repeat_n).find(|lt| !existing_lifetimes.contains(lt.as_str())).unwrap()
} }
fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { #[instrument(level = "debug", skip_all)]
fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
let it = tcx.hir().item(item_id); let it = tcx.hir().item(item_id);
debug!("convert: item {} with id {}", it.ident, it.hir_id()); debug!(item = %it.ident, id = %it.hir_id());
let def_id = item_id.owner_id.def_id; let def_id = item_id.owner_id.def_id;
match &it.kind { match &it.kind {
@ -591,7 +591,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
tcx.ensure().generics_of(def_id); tcx.ensure().generics_of(def_id);
tcx.ensure().type_of(def_id); tcx.ensure().type_of(def_id);
tcx.ensure().predicates_of(def_id); tcx.ensure().predicates_of(def_id);
convert_enum_variant_types(tcx, def_id.to_def_id()); lower_enum_variant_types(tcx, def_id.to_def_id());
} }
hir::ItemKind::Impl { .. } => { hir::ItemKind::Impl { .. } => {
tcx.ensure().generics_of(def_id); tcx.ensure().generics_of(def_id);
@ -625,7 +625,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
} }
if let Some(ctor_def_id) = struct_def.ctor_def_id() { if let Some(ctor_def_id) = struct_def.ctor_def_id() {
convert_variant_ctor(tcx, ctor_def_id); lower_variant_ctor(tcx, ctor_def_id);
} }
} }
@ -668,7 +668,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
} }
} }
fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) { fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
let trait_item = tcx.hir().trait_item(trait_item_id); let trait_item = tcx.hir().trait_item(trait_item_id);
let def_id = trait_item_id.owner_id; let def_id = trait_item_id.owner_id;
tcx.ensure().generics_of(def_id); tcx.ensure().generics_of(def_id);
@ -717,7 +717,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
tcx.ensure().predicates_of(def_id); tcx.ensure().predicates_of(def_id);
} }
fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) { fn lower_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
let def_id = impl_item_id.owner_id; let def_id = impl_item_id.owner_id;
tcx.ensure().generics_of(def_id); tcx.ensure().generics_of(def_id);
tcx.ensure().type_of(def_id); tcx.ensure().type_of(def_id);
@ -746,13 +746,13 @@ fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
} }
} }
fn convert_variant_ctor(tcx: TyCtxt<'_>, def_id: LocalDefId) { fn lower_variant_ctor(tcx: TyCtxt<'_>, def_id: LocalDefId) {
tcx.ensure().generics_of(def_id); tcx.ensure().generics_of(def_id);
tcx.ensure().type_of(def_id); tcx.ensure().type_of(def_id);
tcx.ensure().predicates_of(def_id); tcx.ensure().predicates_of(def_id);
} }
fn convert_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) { fn lower_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) {
let def = tcx.adt_def(def_id); let def = tcx.adt_def(def_id);
let repr_type = def.repr().discr_type(); let repr_type = def.repr().discr_type();
let initial = repr_type.initial_discriminant(tcx); let initial = repr_type.initial_discriminant(tcx);
@ -785,10 +785,9 @@ fn convert_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) {
tcx.ensure().predicates_of(f.did); tcx.ensure().predicates_of(f.did);
} }
// Convert the ctor, if any. This also registers the variant as // Lower the ctor, if any. This also registers the variant as an item.
// an item.
if let Some(ctor_def_id) = variant.ctor_def_id() { if let Some(ctor_def_id) = variant.ctor_def_id() {
convert_variant_ctor(tcx, ctor_def_id.expect_local()); lower_variant_ctor(tcx, ctor_def_id.expect_local());
} }
} }
} }
@ -975,7 +974,7 @@ impl<'tcx> FieldUniquenessCheckContext<'tcx> {
} }
} }
fn convert_variant( fn lower_variant(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
variant_did: Option<LocalDefId>, variant_did: Option<LocalDefId>,
ident: Ident, ident: Ident,
@ -1060,7 +1059,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
}; };
distance_from_explicit += 1; distance_from_explicit += 1;
convert_variant( lower_variant(
tcx, tcx,
Some(v.def_id), Some(v.def_id),
v.ident, v.ident,
@ -1080,7 +1079,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
ItemKind::Struct(..) => AdtKind::Struct, ItemKind::Struct(..) => AdtKind::Struct,
_ => AdtKind::Union, _ => AdtKind::Union,
}; };
let variants = std::iter::once(convert_variant( let variants = std::iter::once(lower_variant(
tcx, tcx,
None, None,
item.ident, item.ident,
@ -1284,7 +1283,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<ty::PolyFnSig<
if let Item(hir::Item { kind: ItemKind::Impl(i), .. }) = tcx.parent_hir_node(hir_id) if let Item(hir::Item { kind: ItemKind::Impl(i), .. }) = tcx.parent_hir_node(hir_id)
&& i.of_trait.is_some() && i.of_trait.is_some()
{ {
icx.astconv().ty_of_fn( icx.lowerer().lower_fn_ty(
hir_id, hir_id,
sig.header.unsafety, sig.header.unsafety,
sig.header.abi, sig.header.abi,
@ -1301,9 +1300,14 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<ty::PolyFnSig<
kind: TraitItemKind::Fn(FnSig { header, decl, span: _ }, _), kind: TraitItemKind::Fn(FnSig { header, decl, span: _ }, _),
generics, generics,
.. ..
}) => { }) => icx.lowerer().lower_fn_ty(
icx.astconv().ty_of_fn(hir_id, header.unsafety, header.abi, decl, Some(generics), None) hir_id,
} header.unsafety,
header.abi,
decl,
Some(generics),
None,
),
ForeignItem(&hir::ForeignItem { kind: ForeignItemKind::Fn(fn_decl, _, _), .. }) => { ForeignItem(&hir::ForeignItem { kind: ForeignItemKind::Fn(fn_decl, _, _), .. }) => {
let abi = tcx.hir().get_foreign_abi(hir_id); let abi = tcx.hir().get_foreign_abi(hir_id);
@ -1411,7 +1415,7 @@ fn infer_return_ty_for_fn_sig<'tcx>(
)) ))
} }
} }
None => icx.astconv().ty_of_fn( None => icx.lowerer().lower_fn_ty(
hir_id, hir_id,
sig.header.unsafety, sig.header.unsafety,
sig.header.abi, sig.header.abi,
@ -1529,19 +1533,19 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::ImplTrai
impl_ impl_
.of_trait .of_trait
.as_ref() .as_ref()
.map(|ast_trait_ref| { .map(|hir_trait_ref| {
let selfty = tcx.type_of(def_id).instantiate_identity(); let self_ty = tcx.type_of(def_id).instantiate_identity();
let trait_ref = if let Some(ErrorGuaranteed { .. }) = check_impl_constness( let trait_ref = if let Some(ErrorGuaranteed { .. }) = check_impl_constness(
tcx, tcx,
tcx.is_const_trait_impl_raw(def_id.to_def_id()), tcx.is_const_trait_impl_raw(def_id.to_def_id()),
ast_trait_ref, hir_trait_ref,
) { ) {
// we have a const impl, but for a trait without `#[const_trait]`, so // 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 // 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 // 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 mut path_segments = hir_trait_ref.path.segments.to_vec();
let last_segment = path_segments.len() - 1; let last_segment = path_segments.len() - 1;
let mut args = *path_segments[last_segment].args(); let mut args = *path_segments[last_segment].args();
let last_arg = args.args.len() - 1; let last_arg = args.args.len() - 1;
@ -1549,19 +1553,19 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::ImplTrai
args.args = &args.args[..args.args.len() - 1]; args.args = &args.args[..args.args.len() - 1];
path_segments[last_segment].args = Some(tcx.hir_arena.alloc(args)); path_segments[last_segment].args = Some(tcx.hir_arena.alloc(args));
let path = hir::Path { let path = hir::Path {
span: ast_trait_ref.path.span, span: hir_trait_ref.path.span,
res: ast_trait_ref.path.res, res: hir_trait_ref.path.res,
segments: tcx.hir_arena.alloc_slice(&path_segments), segments: tcx.hir_arena.alloc_slice(&path_segments),
}; };
let trait_ref = tcx.hir_arena.alloc(hir::TraitRef { path: tcx.hir_arena.alloc(path), hir_ref_id: ast_trait_ref.hir_ref_id }); let trait_ref = tcx.hir_arena.alloc(hir::TraitRef { path: tcx.hir_arena.alloc(path), hir_ref_id: hir_trait_ref.hir_ref_id });
icx.astconv().instantiate_mono_trait_ref(trait_ref, selfty) icx.lowerer().lower_impl_trait_ref(trait_ref, self_ty)
} else { } else {
icx.astconv().instantiate_mono_trait_ref(ast_trait_ref, selfty) icx.lowerer().lower_impl_trait_ref(hir_trait_ref, self_ty)
}; };
ty::ImplTraitHeader { ty::ImplTraitHeader {
trait_ref: ty::EarlyBinder::bind(trait_ref), trait_ref: ty::EarlyBinder::bind(trait_ref),
unsafety: impl_.unsafety, unsafety: impl_.unsafety,
polarity: polarity_of_impl(tcx, def_id, impl_, item.span) polarity: polarity_of_impl(tcx, def_id, impl_, item.span)
} }
}) })
} }
@ -1569,20 +1573,20 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::ImplTrai
fn check_impl_constness( fn check_impl_constness(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
is_const: bool, is_const: bool,
ast_trait_ref: &hir::TraitRef<'_>, hir_trait_ref: &hir::TraitRef<'_>,
) -> Option<ErrorGuaranteed> { ) -> Option<ErrorGuaranteed> {
if !is_const { if !is_const {
return None; return None;
} }
let trait_def_id = ast_trait_ref.trait_def_id()?; let trait_def_id = hir_trait_ref.trait_def_id()?;
if tcx.has_attr(trait_def_id, sym::const_trait) { if tcx.has_attr(trait_def_id, sym::const_trait) {
return None; return None;
} }
let trait_name = tcx.item_name(trait_def_id).to_string(); let trait_name = tcx.item_name(trait_def_id).to_string();
Some(tcx.dcx().emit_err(errors::ConstImplForNonConstTrait { Some(tcx.dcx().emit_err(errors::ConstImplForNonConstTrait {
trait_ref_span: ast_trait_ref.path.span, trait_ref_span: hir_trait_ref.path.span,
trait_name, trait_name,
local_trait_span: local_trait_span:
trait_def_id.as_local().map(|_| tcx.def_span(trait_def_id).shrink_to_lo()), trait_def_id.as_local().map(|_| tcx.def_span(trait_def_id).shrink_to_lo()),
@ -1678,19 +1682,19 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
}; };
let hir_id = tcx.local_def_id_to_hir_id(def_id); let hir_id = tcx.local_def_id_to_hir_id(def_id);
let fty = let fty =
ItemCtxt::new(tcx, def_id).astconv().ty_of_fn(hir_id, unsafety, abi, decl, None, None); ItemCtxt::new(tcx, def_id).lowerer().lower_fn_ty(hir_id, unsafety, abi, decl, None, None);
// Feature gate SIMD types in FFI, since I am not sure that the // Feature gate SIMD types in FFI, since I am not sure that the
// ABIs are handled at all correctly. -huonw // ABIs are handled at all correctly. -huonw
if abi != abi::Abi::RustIntrinsic && !tcx.features().simd_ffi { if abi != abi::Abi::RustIntrinsic && !tcx.features().simd_ffi {
let check = |ast_ty: &hir::Ty<'_>, ty: Ty<'_>| { let check = |hir_ty: &hir::Ty<'_>, ty: Ty<'_>| {
if ty.is_simd() { if ty.is_simd() {
let snip = tcx let snip = tcx
.sess .sess
.source_map() .source_map()
.span_to_snippet(ast_ty.span) .span_to_snippet(hir_ty.span)
.map_or_else(|_| String::new(), |s| format!(" `{s}`")); .map_or_else(|_| String::new(), |s| format!(" `{s}`"));
tcx.dcx().emit_err(errors::SIMDFFIHighlyExperimental { span: ast_ty.span, snip }); tcx.dcx().emit_err(errors::SIMDFFIHighlyExperimental { span: hir_ty.span, snip });
} }
}; };
for (input, ty) in iter::zip(decl.inputs, fty.inputs().skip_binder()) { for (input, ty) in iter::zip(decl.inputs, fty.inputs().skip_binder()) {

View File

@ -218,8 +218,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
Deny, Deny,
} }
let no_generics = hir::Generics::empty(); let hir_generics = node.generics().unwrap_or(hir::Generics::empty());
let ast_generics = node.generics().unwrap_or(no_generics);
let (opt_self, allow_defaults) = match node { let (opt_self, allow_defaults) = match node {
Node::Item(item) => { Node::Item(item) => {
match item.kind { match item.kind {
@ -275,13 +274,13 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
generics.parent_count + generics.params.len() generics.parent_count + generics.params.len()
}); });
let mut params: Vec<_> = Vec::with_capacity(ast_generics.params.len() + has_self as usize); let mut params: Vec<_> = Vec::with_capacity(hir_generics.params.len() + has_self as usize);
if let Some(opt_self) = opt_self { if let Some(opt_self) = opt_self {
params.push(opt_self); params.push(opt_self);
} }
let early_lifetimes = super::early_bound_lifetimes_from_generics(tcx, ast_generics); let early_lifetimes = super::early_bound_lifetimes_from_generics(tcx, hir_generics);
params.extend(early_lifetimes.enumerate().map(|(i, param)| ty::GenericParamDef { params.extend(early_lifetimes.enumerate().map(|(i, param)| ty::GenericParamDef {
name: param.name.ident().name, name: param.name.ident().name,
index: own_start + i as u32, index: own_start + i as u32,
@ -302,7 +301,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
const TYPE_DEFAULT_NOT_ALLOWED: &'static str = "defaults for type parameters are only allowed in \ const TYPE_DEFAULT_NOT_ALLOWED: &'static str = "defaults for type parameters are only allowed in \
`struct`, `enum`, `type`, or `trait` definitions"; `struct`, `enum`, `type`, or `trait` definitions";
params.extend(ast_generics.params.iter().filter_map(|param| match param.kind { params.extend(hir_generics.params.iter().filter_map(|param| match param.kind {
GenericParamKind::Lifetime { .. } => None, GenericParamKind::Lifetime { .. } => None,
GenericParamKind::Type { default, synthetic, .. } => { GenericParamKind::Type { default, synthetic, .. } => {
if default.is_some() { if default.is_some() {

View File

@ -1,5 +1,5 @@
use super::ItemCtxt; use super::ItemCtxt;
use crate::astconv::{AstConv, PredicateFilter}; use crate::hir_ty_lowering::{HirTyLowerer, PredicateFilter};
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_infer::traits::util; use rustc_infer::traits::util;
@ -18,7 +18,7 @@ use rustc_span::Span;
fn associated_type_bounds<'tcx>( fn associated_type_bounds<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
assoc_item_def_id: LocalDefId, assoc_item_def_id: LocalDefId,
ast_bounds: &'tcx [hir::GenericBound<'tcx>], hir_bounds: &'tcx [hir::GenericBound<'tcx>],
span: Span, span: Span,
filter: PredicateFilter, filter: PredicateFilter,
) -> &'tcx [(ty::Clause<'tcx>, Span)] { ) -> &'tcx [(ty::Clause<'tcx>, Span)] {
@ -29,9 +29,9 @@ fn associated_type_bounds<'tcx>(
); );
let icx = ItemCtxt::new(tcx, assoc_item_def_id); let icx = ItemCtxt::new(tcx, assoc_item_def_id);
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, filter); let mut bounds = icx.lowerer().lower_mono_bounds(item_ty, hir_bounds, filter);
// Associated types are implicitly sized unless a `?Sized` bound is found // Associated types are implicitly sized unless a `?Sized` bound is found
icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span); icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
let trait_def_id = tcx.local_parent(assoc_item_def_id); let trait_def_id = tcx.local_parent(assoc_item_def_id);
let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id); let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id);
@ -62,16 +62,16 @@ fn associated_type_bounds<'tcx>(
fn opaque_type_bounds<'tcx>( fn opaque_type_bounds<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
opaque_def_id: LocalDefId, opaque_def_id: LocalDefId,
ast_bounds: &'tcx [hir::GenericBound<'tcx>], hir_bounds: &'tcx [hir::GenericBound<'tcx>],
item_ty: Ty<'tcx>, item_ty: Ty<'tcx>,
span: Span, span: Span,
filter: PredicateFilter, filter: PredicateFilter,
) -> &'tcx [(ty::Clause<'tcx>, Span)] { ) -> &'tcx [(ty::Clause<'tcx>, Span)] {
ty::print::with_reduced_queries!({ ty::print::with_reduced_queries!({
let icx = ItemCtxt::new(tcx, opaque_def_id); let icx = ItemCtxt::new(tcx, opaque_def_id);
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, filter); let mut bounds = icx.lowerer().lower_mono_bounds(item_ty, hir_bounds, filter);
// Opaque types are implicitly sized unless a `?Sized` bound is found // Opaque types are implicitly sized unless a `?Sized` bound is found
icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span); icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
debug!(?bounds); debug!(?bounds);
tcx.arena.alloc_from_iter(bounds.clauses()) tcx.arena.alloc_from_iter(bounds.clauses())
@ -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); let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter) 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 // Since RPITITs are lowered as projections in `<dyn HirTyLowerer>::lower_ty`, when we're
// for the item bounds of the *opaques* in a trait's default method signature, we // asking for the item bounds of the *opaques* in a trait's default method signature, we
// need to map these projections back to opaques. // need to map these projections back to opaques.
hir::Node::Item(hir::Item { hir::Node::Item(hir::Item {
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait: true, origin, .. }), kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait: true, origin, .. }),

View File

@ -1,7 +1,7 @@
use crate::astconv::{AstConv, OnlySelfBounds, PredicateFilter};
use crate::bounds::Bounds; use crate::bounds::Bounds;
use crate::collect::ItemCtxt; use crate::collect::ItemCtxt;
use crate::constrained_generic_params as cgp; use crate::constrained_generic_params as cgp;
use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter};
use hir::{HirId, Node}; use hir::{HirId, Node};
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
use rustc_hir as hir; use rustc_hir as hir;
@ -123,7 +123,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
// Preserving the order of insertion is important here so as not to break UI tests. // Preserving the order of insertion is important here so as not to break UI tests.
let mut predicates: FxIndexSet<(ty::Clause<'_>, Span)> = FxIndexSet::default(); let mut predicates: FxIndexSet<(ty::Clause<'_>, Span)> = FxIndexSet::default();
let ast_generics = node.generics().unwrap_or(NO_GENERICS); let hir_generics = node.generics().unwrap_or(NO_GENERICS);
if let Node::Item(item) = node { if let Node::Item(item) = node {
match item.kind { match item.kind {
ItemKind::Impl(impl_) => { ItemKind::Impl(impl_) => {
@ -149,8 +149,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
// like `trait Foo: A + B + C`. // like `trait Foo: A + B + C`.
if let Some(self_bounds) = is_trait { if let Some(self_bounds) = is_trait {
predicates.extend( predicates.extend(
icx.astconv() icx.lowerer()
.compute_bounds(tcx.types.self_param, self_bounds, PredicateFilter::All) .lower_mono_bounds(tcx.types.self_param, self_bounds, PredicateFilter::All)
.clauses(), .clauses(),
); );
} }
@ -170,19 +170,19 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
// Collect the predicates that were written inline by the user on each // Collect the predicates that were written inline by the user on each
// type parameter (e.g., `<T: Foo>`). Also add `ConstArgHasType` predicates // type parameter (e.g., `<T: Foo>`). Also add `ConstArgHasType` predicates
// for each const parameter. // for each const parameter.
for param in ast_generics.params { for param in hir_generics.params {
match param.kind { match param.kind {
// We already dealt with early bound lifetimes above. // We already dealt with early bound lifetimes above.
GenericParamKind::Lifetime { .. } => (), GenericParamKind::Lifetime { .. } => (),
GenericParamKind::Type { .. } => { GenericParamKind::Type { .. } => {
let param_ty = icx.astconv().hir_id_to_bound_ty(param.hir_id); let param_ty = icx.lowerer().lower_ty_param(param.hir_id);
let mut bounds = Bounds::default(); let mut bounds = Bounds::default();
// Params are implicitly sized unless a `?Sized` bound is found // Params are implicitly sized unless a `?Sized` bound is found
icx.astconv().add_implicitly_sized( icx.lowerer().add_sized_bound(
&mut bounds, &mut bounds,
param_ty, param_ty,
&[], &[],
Some((param.def_id, ast_generics.predicates)), Some((param.def_id, hir_generics.predicates)),
param.span, param.span,
); );
trace!(?bounds); trace!(?bounds);
@ -194,7 +194,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
.type_of(param.def_id.to_def_id()) .type_of(param.def_id.to_def_id())
.no_bound_vars() .no_bound_vars()
.expect("const parameters cannot be generic"); .expect("const parameters cannot be generic");
let ct = icx.astconv().hir_id_to_bound_const(param.hir_id, ct_ty); let ct = icx.lowerer().lower_const_param(param.hir_id, ct_ty);
predicates.insert(( predicates.insert((
ty::ClauseKind::ConstArgHasType(ct, ct_ty).to_predicate(tcx), ty::ClauseKind::ConstArgHasType(ct, ct_ty).to_predicate(tcx),
param.span, param.span,
@ -205,10 +205,10 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
trace!(?predicates); trace!(?predicates);
// Add in the bounds that appear in the where-clause. // Add in the bounds that appear in the where-clause.
for predicate in ast_generics.predicates { for predicate in hir_generics.predicates {
match predicate { match predicate {
hir::WherePredicate::BoundPredicate(bound_pred) => { hir::WherePredicate::BoundPredicate(bound_pred) => {
let ty = icx.to_ty(bound_pred.bounded_ty); let ty = icx.lower_ty(bound_pred.bounded_ty);
let bound_vars = tcx.late_bound_vars(bound_pred.hir_id); let bound_vars = tcx.late_bound_vars(bound_pred.hir_id);
// Keep the type around in a dummy predicate, in case of no bounds. // Keep the type around in a dummy predicate, in case of no bounds.
// That way, `where Ty:` is not a complete noop (see #53696) and `Ty` // That way, `where Ty:` is not a complete noop (see #53696) and `Ty`
@ -232,7 +232,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
} }
let mut bounds = Bounds::default(); let mut bounds = Bounds::default();
icx.astconv().add_bounds( icx.lowerer().lower_poly_bounds(
ty, ty,
bound_pred.bounds.iter(), bound_pred.bounds.iter(),
&mut bounds, &mut bounds,
@ -243,11 +243,11 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
} }
hir::WherePredicate::RegionPredicate(region_pred) => { hir::WherePredicate::RegionPredicate(region_pred) => {
let r1 = icx.astconv().ast_region_to_region(region_pred.lifetime, None); let r1 = icx.lowerer().lower_lifetime(region_pred.lifetime, None);
predicates.extend(region_pred.bounds.iter().map(|bound| { predicates.extend(region_pred.bounds.iter().map(|bound| {
let (r2, span) = match bound { let (r2, span) = match bound {
hir::GenericBound::Outlives(lt) => { hir::GenericBound::Outlives(lt) => {
(icx.astconv().ast_region_to_region(lt, None), lt.ident.span) (icx.lowerer().lower_lifetime(lt, None), lt.ident.span)
} }
bound => { bound => {
span_bug!( span_bug!(
@ -542,8 +542,8 @@ pub(super) fn explicit_predicates_of<'tcx>(
} }
/// Ensures that the super-predicates of the trait with a `DefId` /// Ensures that the super-predicates of the trait with a `DefId`
/// of `trait_def_id` are converted and stored. This also ensures that /// of `trait_def_id` are lowered and stored. This also ensures that
/// the transitive super-predicates are converted. /// the transitive super-predicates are lowered.
pub(super) fn super_predicates_of( pub(super) fn super_predicates_of(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
trait_def_id: LocalDefId, 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` /// Ensures that the super-predicates of the trait with a `DefId`
/// of `trait_def_id` are converted and stored. This also ensures that /// of `trait_def_id` are lowered and stored. This also ensures that
/// the transitive super-predicates are converted. /// the transitive super-predicates are lowered.
pub(super) fn implied_predicates_with_filter( pub(super) fn implied_predicates_with_filter(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
trait_def_id: DefId, trait_def_id: DefId,
@ -601,9 +601,9 @@ pub(super) fn implied_predicates_with_filter(
let icx = ItemCtxt::new(tcx, trait_def_id); let icx = ItemCtxt::new(tcx, trait_def_id);
let self_param_ty = tcx.types.self_param; let self_param_ty = tcx.types.self_param;
let superbounds = icx.astconv().compute_bounds(self_param_ty, bounds, filter); let superbounds = icx.lowerer().lower_mono_bounds(self_param_ty, bounds, filter);
let where_bounds_that_match = icx.type_parameter_bounds_in_generics( let where_bounds_that_match = icx.probe_ty_param_bounds_in_generics(
generics, generics,
item.owner_id.def_id, item.owner_id.def_id,
self_param_ty, self_param_ty,
@ -615,7 +615,7 @@ pub(super) fn implied_predicates_with_filter(
&*tcx.arena.alloc_from_iter(superbounds.clauses().chain(where_bounds_that_match)); &*tcx.arena.alloc_from_iter(superbounds.clauses().chain(where_bounds_that_match));
debug!(?implied_bounds); 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 // turn, reach indirect supertraits, so we detect cycles now instead of
// overflowing during elaboration. Same for implied predicates, which // overflowing during elaboration. Same for implied predicates, which
// make sure we walk into associated type bounds. // make sure we walk into associated type bounds.
@ -656,7 +656,7 @@ pub(super) fn type_param_predicates(
use rustc_hir::*; use rustc_hir::*;
use rustc_middle::ty::Ty; 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 // written inline like `<T: Foo>` or in a where-clause like
// `where T: Foo`. // `where T: Foo`.
@ -676,7 +676,7 @@ pub(super) fn type_param_predicates(
let mut result = parent let mut result = parent
.map(|parent| { .map(|parent| {
let icx = ItemCtxt::new(tcx, parent); let icx = ItemCtxt::new(tcx, parent);
icx.get_type_parameter_bounds(DUMMY_SP, def_id, assoc_name) icx.probe_ty_param_bounds(DUMMY_SP, def_id, assoc_name)
}) })
.unwrap_or_default(); .unwrap_or_default();
let mut extend = None; let mut extend = None;
@ -684,7 +684,7 @@ pub(super) fn type_param_predicates(
let item_hir_id = tcx.local_def_id_to_hir_id(item_def_id); let item_hir_id = tcx.local_def_id_to_hir_id(item_def_id);
let hir_node = tcx.hir_node(item_hir_id); let hir_node = tcx.hir_node(item_hir_id);
let Some(ast_generics) = hir_node.generics() else { return result }; let Some(hir_generics) = hir_node.generics() else { return result };
if let Node::Item(item) = hir_node if let Node::Item(item) = hir_node
&& let ItemKind::Trait(..) = item.kind && let ItemKind::Trait(..) = item.kind
// Implied `Self: Trait` and supertrait bounds. // Implied `Self: Trait` and supertrait bounds.
@ -696,8 +696,8 @@ pub(super) fn type_param_predicates(
let icx = ItemCtxt::new(tcx, item_def_id); let icx = ItemCtxt::new(tcx, item_def_id);
let extra_predicates = extend.into_iter().chain( let extra_predicates = extend.into_iter().chain(
icx.type_parameter_bounds_in_generics( icx.probe_ty_param_bounds_in_generics(
ast_generics, hir_generics,
def_id, def_id,
ty, ty,
PredicateFilter::SelfThatDefines(assoc_name), PredicateFilter::SelfThatDefines(assoc_name),
@ -714,21 +714,22 @@ pub(super) fn type_param_predicates(
} }
impl<'tcx> ItemCtxt<'tcx> { impl<'tcx> ItemCtxt<'tcx> {
/// Finds bounds from `hir::Generics`. This requires scanning through the /// Finds bounds from `hir::Generics`.
/// AST. We do this to avoid having to convert *all* the bounds, which ///
/// would create artificial cycles. Instead, we can only convert the /// This requires scanning through the HIR.
/// bounds for a type parameter `X` if `X::Foo` is used. /// We do this to avoid having to lower *all* the bounds, which would create artificial cycles.
#[instrument(level = "trace", skip(self, ast_generics))] /// Instead, we can only lower the bounds for a type parameter `X` if `X::Foo` is used.
fn type_parameter_bounds_in_generics( #[instrument(level = "trace", skip(self, hir_generics))]
fn probe_ty_param_bounds_in_generics(
&self, &self,
ast_generics: &'tcx hir::Generics<'tcx>, hir_generics: &'tcx hir::Generics<'tcx>,
param_def_id: LocalDefId, param_def_id: LocalDefId,
ty: Ty<'tcx>, ty: Ty<'tcx>,
filter: PredicateFilter, filter: PredicateFilter,
) -> Vec<(ty::Clause<'tcx>, Span)> { ) -> Vec<(ty::Clause<'tcx>, Span)> {
let mut bounds = Bounds::default(); let mut bounds = Bounds::default();
for predicate in ast_generics.predicates { for predicate in hir_generics.predicates {
let hir::WherePredicate::BoundPredicate(predicate) = predicate else { let hir::WherePredicate::BoundPredicate(predicate) = predicate else {
continue; continue;
}; };
@ -750,13 +751,13 @@ impl<'tcx> ItemCtxt<'tcx> {
let bound_ty = if predicate.is_param_bound(param_def_id.to_def_id()) { let bound_ty = if predicate.is_param_bound(param_def_id.to_def_id()) {
ty ty
} else if matches!(filter, PredicateFilter::All) { } else if matches!(filter, PredicateFilter::All) {
self.to_ty(predicate.bounded_ty) self.lower_ty(predicate.bounded_ty)
} else { } else {
continue; continue;
}; };
let bound_vars = self.tcx.late_bound_vars(predicate.hir_id); let bound_vars = self.tcx.late_bound_vars(predicate.hir_id);
self.astconv().add_bounds( self.lowerer().lower_poly_bounds(
bound_ty, bound_ty,
predicate.bounds.iter().filter(|bound| { predicate.bounds.iter().filter(|bound| {
assoc_name assoc_name

View File

@ -1917,18 +1917,18 @@ fn is_late_bound_map(
/// ///
/// If we conservatively considered `'a` unconstrained then we could break users who had written code before /// 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 /// 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`. /// 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. /// We must therefore "look into" the `Alias` to see whether we should consider `'a` constrained or not.
/// ///
/// See #100508 #85533 #47511 for additional context /// See #100508 #85533 #47511 for additional context
struct ConstrainedCollectorPostAstConv { struct ConstrainedCollectorPostHirTyLowering {
arg_is_constrained: Box<[bool]>, arg_is_constrained: Box<[bool]>,
} }
use ty::Ty; use ty::Ty;
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ConstrainedCollectorPostAstConv { impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ConstrainedCollectorPostHirTyLowering {
fn visit_ty(&mut self, t: Ty<'tcx>) { fn visit_ty(&mut self, t: Ty<'tcx>) {
match t.kind() { match t.kind() {
ty::Param(param_ty) => { ty::Param(param_ty) => {
@ -1970,10 +1970,10 @@ fn is_late_bound_map(
None, None,
hir::Path { res: Res::Def(DefKind::TyAlias, alias_def), segments, span }, hir::Path { res: Res::Def(DefKind::TyAlias, alias_def), segments, span },
)) => { )) => {
// See comments on `ConstrainedCollectorPostAstConv` for why this arm does not just consider // See comments on `ConstrainedCollectorPostHirTyLowering` for why this arm does not
// args to be unconstrained. // just consider args to be unconstrained.
let generics = self.tcx.generics_of(alias_def); let generics = self.tcx.generics_of(alias_def);
let mut walker = ConstrainedCollectorPostAstConv { let mut walker = ConstrainedCollectorPostHirTyLowering {
arg_is_constrained: vec![false; generics.params.len()].into_boxed_slice(), arg_is_constrained: vec![false; generics.params.len()].into_boxed_slice(),
}; };
walker.visit_ty(self.tcx.type_of(alias_def).instantiate_identity()); walker.visit_ty(self.tcx.type_of(alias_def).instantiate_identity());

View File

@ -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 // 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)), .. }) => { 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. // 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. // ty which is a fully resolved projection.
// For the code example above, this would mean converting Self::Assoc<3> // For the code example above, this would mean lowering `Self::Assoc<3>`
// into a ty::Alias(ty::Projection, <Self as Foo>::Assoc<3>) // to a ty::Alias(ty::Projection, `<Self as Foo>::Assoc<3>`).
let item_def_id = tcx let item_def_id = tcx
.hir() .hir()
.parent_owner_iter(hir_id) .parent_owner_iter(hir_id)
@ -108,7 +108,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
.unwrap() .unwrap()
.0 .0
.def_id; .def_id;
let ty = ItemCtxt::new(tcx, item_def_id).to_ty(hir_ty); let ty = ItemCtxt::new(tcx, item_def_id).lower_ty(hir_ty);
// Iterate through the generics of the projection to find the one that corresponds to // Iterate through the generics of the projection to find the one that corresponds to
// the def_id that this query was called with. We filter to only type and const args here // the def_id that this query was called with. We filter to only type and const args here
@ -369,8 +369,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
) )
}) })
}) })
.unwrap_or_else(|| icx.to_ty(ty)), .unwrap_or_else(|| icx.lower_ty(ty)),
TraitItemKind::Type(_, Some(ty)) => icx.to_ty(ty), TraitItemKind::Type(_, Some(ty)) => icx.lower_ty(ty),
TraitItemKind::Type(_, None) => { TraitItemKind::Type(_, None) => {
span_bug!(item.span, "associated type missing default"); span_bug!(item.span, "associated type missing default");
} }
@ -392,7 +392,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
"associated constant", "associated constant",
) )
} else { } else {
icx.to_ty(ty) icx.lower_ty(ty)
} }
} }
ImplItemKind::Type(ty) => { ImplItemKind::Type(ty) => {
@ -400,7 +400,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
check_feature_inherent_assoc_ty(tcx, item.span); check_feature_inherent_assoc_ty(tcx, item.span);
} }
icx.to_ty(ty) icx.lower_ty(ty)
} }
}, },
@ -416,17 +416,17 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
"static variable", "static variable",
) )
} else { } else {
icx.to_ty(ty) icx.lower_ty(ty)
} }
} }
ItemKind::Const(ty, _, body_id) => { ItemKind::Const(ty, _, body_id) => {
if ty.is_suggestable_infer_ty() { if ty.is_suggestable_infer_ty() {
infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident, "constant") infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident, "constant")
} else { } else {
icx.to_ty(ty) icx.lower_ty(ty)
} }
} }
ItemKind::TyAlias(self_ty, _) => icx.to_ty(self_ty), ItemKind::TyAlias(self_ty, _) => icx.lower_ty(self_ty),
ItemKind::Impl(hir::Impl { self_ty, .. }) => match self_ty.find_self_aliases() { ItemKind::Impl(hir::Impl { self_ty, .. }) => match self_ty.find_self_aliases() {
spans if spans.len() > 0 => { spans if spans.len() > 0 => {
let guar = tcx let guar = tcx
@ -434,7 +434,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
.emit_err(crate::errors::SelfInImplSelf { span: spans.into(), note: () }); .emit_err(crate::errors::SelfInImplSelf { span: spans.into(), note: () });
Ty::new_error(tcx, guar) Ty::new_error(tcx, guar)
} }
_ => icx.to_ty(*self_ty), _ => icx.lower_ty(*self_ty),
}, },
ItemKind::Fn(..) => { ItemKind::Fn(..) => {
let args = ty::GenericArgs::identity_for_item(tcx, def_id); let args = ty::GenericArgs::identity_for_item(tcx, def_id);
@ -466,7 +466,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
let args = ty::GenericArgs::identity_for_item(tcx, def_id); let args = ty::GenericArgs::identity_for_item(tcx, def_id);
Ty::new_fn_def(tcx, def_id.to_def_id(), args) Ty::new_fn_def(tcx, def_id.to_def_id(), args)
} }
ForeignItemKind::Static(t, _) => icx.to_ty(t), ForeignItemKind::Static(t, _) => icx.lower_ty(t),
ForeignItemKind::Type => Ty::new_foreign(tcx, def_id.to_def_id()), ForeignItemKind::Type => Ty::new_foreign(tcx, def_id.to_def_id()),
}, },
@ -480,7 +480,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
} }
}, },
Node::Field(field) => icx.to_ty(field.ty), Node::Field(field) => icx.lower_ty(field.ty),
Node::Expr(&Expr { kind: ExprKind::Closure { .. }, .. }) => { Node::Expr(&Expr { kind: ExprKind::Closure { .. }, .. }) => {
tcx.typeck(def_id).node_type(hir_id) tcx.typeck(def_id).node_type(hir_id)
@ -495,7 +495,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
Node::GenericParam(param) => match &param.kind { Node::GenericParam(param) => match &param.kind {
GenericParamKind::Type { default: Some(ty), .. } GenericParamKind::Type { default: Some(ty), .. }
| GenericParamKind::Const { ty, .. } => icx.to_ty(ty), | GenericParamKind::Const { ty, .. } => icx.lower_ty(ty),
x => bug!("unexpected non-type Node::GenericParam: {:?}", x), x => bug!("unexpected non-type Node::GenericParam: {:?}", x),
}, },

View File

@ -12,17 +12,19 @@ use rustc_trait_selection::traits;
use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
use smallvec::SmallVec; use smallvec::SmallVec;
use crate::astconv::{AstConv, OnlySelfBounds, PredicateFilter};
use crate::bounds::Bounds; use crate::bounds::Bounds;
use crate::errors; use crate::errors;
use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter};
impl<'tcx> dyn AstConv<'tcx> + '_ { impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
/// Sets `implicitly_sized` to true on `Bounds` if necessary /// Add a `Sized` bound to the `bounds` if appropriate.
pub(crate) fn add_implicitly_sized( ///
/// Doesn't add the bound if the HIR bounds contain any of `Sized`, `?Sized` or `!Sized`.
pub(crate) fn add_sized_bound(
&self, &self,
bounds: &mut Bounds<'tcx>, bounds: &mut Bounds<'tcx>,
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
ast_bounds: &'tcx [hir::GenericBound<'tcx>], hir_bounds: &'tcx [hir::GenericBound<'tcx>],
self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>, self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
span: Span, span: Span,
) { ) {
@ -33,9 +35,9 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
// Try to find an unbound in bounds. // Try to find an unbound in bounds.
let mut unbounds: SmallVec<[_; 1]> = SmallVec::new(); let mut unbounds: SmallVec<[_; 1]> = SmallVec::new();
let mut search_bounds = |ast_bounds: &'tcx [hir::GenericBound<'tcx>]| { let mut search_bounds = |hir_bounds: &'tcx [hir::GenericBound<'tcx>]| {
for ab in ast_bounds { for hir_bound in hir_bounds {
let hir::GenericBound::Trait(ptr, modifier) = ab else { let hir::GenericBound::Trait(ptr, modifier) = hir_bound else {
continue; continue;
}; };
match modifier { match modifier {
@ -58,7 +60,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
} }
} }
}; };
search_bounds(ast_bounds); search_bounds(hir_bounds);
if let Some((self_ty, where_clause)) = self_ty_where_predicates { if let Some((self_ty, where_clause)) = self_ty_where_predicates {
for clause in where_clause { for clause in where_clause {
if let hir::WherePredicate::BoundPredicate(pred) = clause if let hir::WherePredicate::BoundPredicate(pred) = clause
@ -101,34 +103,40 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
} }
} }
/// This helper takes a *converted* parameter type (`param_ty`) /// Lower HIR bounds into `bounds` given the self type `param_ty` and the overarching late-bound vars if any.
/// and an *unconverted* list of bounds:
/// ///
/// ```text /// ### Examples
/// fn foo<T: Debug> ///
/// ^ ^^^^^ `ast_bounds` parameter, in HIR form /// ```ignore (illustrative)
/// | /// fn foo<T>() where for<'a> T: Trait<'a> + Copy {}
/// `param_ty`, in ty form /// // ^^^^^^^ ^ ^^^^^^^^^^^^^^^^ `hir_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!
/// // ^ ^^^^^^^^^^^^^^^^^^^^^^^^ `hir_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 /// There is an implied binder around `param_ty` and `hir_bounds`.
/// `param_ty` and `ast_bounds`. See `instantiate_poly_trait_ref` /// See `lower_poly_trait_ref` for more details.
/// for more details. #[instrument(level = "debug", skip(self, hir_bounds, bounds))]
#[instrument(level = "debug", skip(self, ast_bounds, bounds))] pub(crate) fn lower_poly_bounds<'hir, I: Iterator<Item = &'hir hir::GenericBound<'tcx>>>(
pub(crate) fn add_bounds<'hir, I: Iterator<Item = &'hir hir::GenericBound<'tcx>>>(
&self, &self,
param_ty: Ty<'tcx>, param_ty: Ty<'tcx>,
ast_bounds: I, hir_bounds: I,
bounds: &mut Bounds<'tcx>, bounds: &mut Bounds<'tcx>,
bound_vars: &'tcx ty::List<ty::BoundVariableKind>, bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
only_self_bounds: OnlySelfBounds, only_self_bounds: OnlySelfBounds,
) where ) where
'tcx: 'hir, 'tcx: 'hir,
{ {
for ast_bound in ast_bounds { for hir_bound in hir_bounds {
match ast_bound { match hir_bound {
hir::GenericBound::Trait(poly_trait_ref, modifier) => { hir::GenericBound::Trait(poly_trait_ref, modifier) => {
let (constness, polarity) = match modifier { let (constness, polarity) = match modifier {
hir::TraitBoundModifier::Const => { hir::TraitBoundModifier::Const => {
@ -145,7 +153,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
} }
hir::TraitBoundModifier::Maybe => continue, hir::TraitBoundModifier::Maybe => continue,
}; };
let _ = self.instantiate_poly_trait_ref( let _ = self.lower_poly_trait_ref(
&poly_trait_ref.trait_ref, &poly_trait_ref.trait_ref,
poly_trait_ref.span, poly_trait_ref.span,
constness, constness,
@ -156,7 +164,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
); );
} }
hir::GenericBound::Outlives(lifetime) => { hir::GenericBound::Outlives(lifetime) => {
let region = self.ast_region_to_region(lifetime, None); let region = self.lower_lifetime(lifetime, None);
bounds.push_region_bound( bounds.push_region_bound(
self.tcx(), self.tcx(),
ty::Binder::bind_with_vars( ty::Binder::bind_with_vars(
@ -170,26 +178,19 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
} }
} }
/// Translates a list of bounds from the HIR into the `Bounds` data structure. /// Lower HIR bounds into `bounds` given the self type `param_ty` and *no* overarching late-bound vars.
/// The self-type for the bounds is given by `param_ty`.
/// ///
/// Example: /// ### Example
/// ///
/// ```ignore (illustrative) /// ```ignore (illustrative)
/// fn foo<T: Bar + Baz>() { } /// fn foo<T: Bar + Baz>() { }
/// // ^ ^^^^^^^^^ ast_bounds /// // ^ ^^^^^^^^^ hir_bounds
/// // param_ty /// // param_ty
/// ``` /// ```
/// pub(crate) fn lower_mono_bounds(
/// 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 compute_bounds(
&self, &self,
param_ty: Ty<'tcx>, param_ty: Ty<'tcx>,
ast_bounds: &[hir::GenericBound<'tcx>], hir_bounds: &[hir::GenericBound<'tcx>],
filter: PredicateFilter, filter: PredicateFilter,
) -> Bounds<'tcx> { ) -> Bounds<'tcx> {
let mut bounds = Bounds::default(); let mut bounds = Bounds::default();
@ -201,9 +202,9 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => OnlySelfBounds(true), PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => OnlySelfBounds(true),
}; };
self.add_bounds( self.lower_poly_bounds(
param_ty, param_ty,
ast_bounds.iter().filter(|bound| match filter { hir_bounds.iter().filter(|bound| match filter {
PredicateFilter::All PredicateFilter::All
| PredicateFilter::SelfOnly | PredicateFilter::SelfOnly
| PredicateFilter::SelfAndAssociatedTypeBounds => true, | PredicateFilter::SelfAndAssociatedTypeBounds => true,
@ -227,14 +228,16 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
bounds bounds
} }
/// Given an HIR binding like `Item = Foo` or `Item: Foo`, pushes the corresponding predicates /// Lower an associated item binding from HIR into `bounds`.
/// onto `bounds`.
/// ///
/// **A note on binders:** given something like `T: for<'a> Iterator<Item = &'a u32>`, the /// ### A Note on Binders
/// `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))] #[instrument(level = "debug", skip(self, bounds, dup_bindings, path_span))]
pub(super) fn add_predicates_for_ast_type_binding( pub(super) fn lower_assoc_item_binding(
&self, &self,
hir_ref_id: hir::HirId, hir_ref_id: hir::HirId,
trait_ref: ty::PolyTraitRef<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>,
@ -244,22 +247,6 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
path_span: Span, path_span: Span,
only_self_bounds: OnlySelfBounds, only_self_bounds: OnlySelfBounds,
) -> Result<(), ErrorGuaranteed> { ) -> 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 tcx = self.tcx();
let assoc_kind = if binding.gen_args.parenthesized let assoc_kind = if binding.gen_args.parenthesized
@ -272,7 +259,15 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
ty::AssocKind::Type ty::AssocKind::Type
}; };
let candidate = if self.trait_defines_associated_item_named( // 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(), trait_ref.def_id(),
assoc_kind, assoc_kind,
binding.ident, binding.ident,
@ -282,7 +277,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
} else { } else {
// Otherwise, we have to walk through the supertraits to find // Otherwise, we have to walk through the supertraits to find
// one that does define it. // one that does define it.
self.one_bound_for_assoc_item( self.probe_single_bound_for_assoc_item(
|| traits::supertraits(tcx, trait_ref), || traits::supertraits(tcx, trait_ref),
trait_ref.skip_binder().print_only_trait_name(), trait_ref.skip_binder().print_only_trait_name(),
None, None,
@ -417,7 +412,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
infer_args: false, infer_args: false,
}; };
let alias_args = self.create_args_for_associated_item( let alias_args = self.lower_generic_args_of_assoc_item(
path_span, path_span,
assoc_item.def_id, assoc_item.def_id,
&item_segment, &item_segment,
@ -449,9 +444,11 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
span: binding.span, 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 } => { hir::TypeBindingKind::Equality { term } => {
let term = match term { let term = match term {
hir::Term::Ty(ty) => self.ast_ty_to_ty(ty).into(), hir::Term::Ty(ty) => self.lower_ty(ty).into(),
hir::Term::Const(ct) => ty::Const::from_anon_const(tcx, ct.def_id).into(), hir::Term::Const(ct) => ty::Const::from_anon_const(tcx, ct.def_id).into(),
}; };
@ -490,10 +487,6 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
}, },
); );
// "Desugar" a constraint like `T: Iterator<Item = u32>` this to
// the "projection predicate" for:
//
// `<T as Iterator>::Item = u32`
bounds.push_projection_bound( bounds.push_projection_bound(
tcx, tcx,
projection_ty projection_ty
@ -501,22 +494,18 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
binding.span, binding.span,
); );
} }
hir::TypeBindingKind::Constraint { bounds: ast_bounds } => { // Lower a constraint like `Item: Debug` as found in HIR bound `T: Iterator<Item: Debug>`
// "Desugar" a constraint like `T: Iterator<Item: Debug>` to // to a bound involving a projection: `<T as Iterator>::Item: Debug`.
// hir::TypeBindingKind::Constraint { bounds: hir_bounds } => {
// `<T as Iterator>::Item: Debug` // 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.
// 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.
if !only_self_bounds.0 { 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()); let param_ty = Ty::new_alias(tcx, ty::Projection, projection_ty.skip_binder());
self.add_bounds( self.lower_poly_bounds(
param_ty, param_ty,
ast_bounds.iter(), hir_bounds.iter(),
bounds, bounds,
projection_ty.bound_vars(), projection_ty.bound_vars(),
only_self_bounds, only_self_bounds,

View File

@ -1,9 +1,9 @@
use crate::astconv::AstConv;
use crate::errors::{ use crate::errors::{
self, AssocTypeBindingNotAllowed, ManualImplementation, MissingTypeParams, self, AssocTypeBindingNotAllowed, ManualImplementation, MissingTypeParams,
ParenthesizedFnTraitExpansion, ParenthesizedFnTraitExpansion,
}; };
use crate::fluent_generated as fluent; use crate::fluent_generated as fluent;
use crate::hir_ty_lowering::HirTyLowerer;
use crate::traits::error_reporting::report_object_safety_error; use crate::traits::error_reporting::report_object_safety_error;
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::sorted_map::SortedMap;
@ -22,7 +22,7 @@ use rustc_span::symbol::{sym, Ident};
use rustc_span::{Span, Symbol, DUMMY_SP}; use rustc_span::{Span, Symbol, DUMMY_SP};
use rustc_trait_selection::traits::object_safety_violations_for_assoc_item; use rustc_trait_selection::traits::object_safety_violations_for_assoc_item;
impl<'tcx> dyn AstConv<'tcx> + '_ { impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
/// On missing type parameters, emit an E0393 error and provide a structured suggestion using /// On missing type parameters, emit an E0393 error and provide a structured suggestion using
/// the type parameter's name as a placeholder. /// the type parameter's name as a placeholder.
pub(crate) fn complain_about_missing_type_params( pub(crate) fn complain_about_missing_type_params(
@ -311,7 +311,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
// FIXME(associated_const_equality): This has quite a few false positives and negatives. // FIXME(associated_const_equality): This has quite a few false positives and negatives.
let wrap_in_braces_sugg = if let Some(binding) = binding let wrap_in_braces_sugg = if let Some(binding) = binding
&& let hir::TypeBindingKind::Equality { term: hir::Term::Ty(hir_ty) } = binding.kind && let hir::TypeBindingKind::Equality { term: hir::Term::Ty(hir_ty) } = binding.kind
&& let ty = self.ast_ty_to_ty(hir_ty) && let ty = self.lower_ty(hir_ty)
&& (ty.is_enum() || ty.references_error()) && (ty.is_enum() || ty.references_error())
&& tcx.features().associated_const_equality && tcx.features().associated_const_equality
{ {
@ -349,7 +349,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
}) })
} }
pub(super) fn report_ambiguous_associated_type( pub(super) fn report_ambiguous_assoc_ty(
&self, &self,
span: Span, span: Span,
types: &[String], types: &[String],
@ -458,7 +458,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
reported reported
} }
pub(crate) fn complain_about_ambiguous_inherent_assoc_type( pub(crate) fn complain_about_ambiguous_inherent_assoc_ty(
&self, &self,
name: Ident, name: Ident,
candidates: Vec<DefId>, candidates: Vec<DefId>,
@ -471,14 +471,14 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
"multiple applicable items in scope" "multiple applicable items in scope"
); );
err.span_label(name.span, format!("multiple `{name}` found")); err.span_label(name.span, format!("multiple `{name}` found"));
self.note_ambiguous_inherent_assoc_type(&mut err, candidates, span); self.note_ambiguous_inherent_assoc_ty(&mut err, candidates, span);
let reported = err.emit(); let reported = err.emit();
self.set_tainted_by_errors(reported); self.set_tainted_by_errors(reported);
reported reported
} }
// FIXME(fmease): Heavily adapted from `rustc_hir_typeck::method::suggest`. Deduplicate. // FIXME(fmease): Heavily adapted from `rustc_hir_typeck::method::suggest`. Deduplicate.
fn note_ambiguous_inherent_assoc_type( fn note_ambiguous_inherent_assoc_ty(
&self, &self,
err: &mut Diag<'_>, err: &mut Diag<'_>,
candidates: Vec<DefId>, candidates: Vec<DefId>,
@ -521,7 +521,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
} }
// FIXME(inherent_associated_types): Find similarly named associated types and suggest them. // FIXME(inherent_associated_types): Find similarly named associated types and suggest them.
pub(crate) fn complain_about_inherent_assoc_type_not_found( pub(crate) fn complain_about_inherent_assoc_ty_not_found(
&self, &self,
name: Ident, name: Ident,
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
@ -697,7 +697,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
/// reasonable suggestion on how to write it. For the case of multiple associated types in the /// reasonable suggestion on how to write it. For the case of multiple associated types in the
/// same trait bound have the same name (as they come from different supertraits), we instead /// same trait bound have the same name (as they come from different supertraits), we instead
/// emit a generic note suggesting using a `where` clause to constraint instead. /// emit a generic note suggesting using a `where` clause to constraint instead.
pub(crate) fn complain_about_missing_associated_types( pub(crate) fn complain_about_missing_assoc_tys(
&self, &self,
associated_types: FxIndexMap<Span, FxIndexSet<DefId>>, associated_types: FxIndexMap<Span, FxIndexSet<DefId>>,
potential_assoc_types: Vec<Span>, potential_assoc_types: Vec<Span>,
@ -1027,7 +1027,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
} }
/// Emits an error regarding forbidden type binding associations /// Emits an error regarding forbidden type binding associations
pub fn prohibit_assoc_ty_binding( pub fn prohibit_assoc_item_binding(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
span: Span, span: Span,
segment: Option<(&hir::PathSegment<'_>, Span)>, segment: Option<(&hir::PathSegment<'_>, Span)>,

View File

@ -1,7 +1,7 @@
use super::IsMethodCall; use super::IsMethodCall;
use crate::astconv::{ use crate::hir_ty_lowering::{
errors::prohibit_assoc_ty_binding, CreateInstantiationsForGenericArgsCtxt, ExplicitLateBound, errors::prohibit_assoc_item_binding, ExplicitLateBound, GenericArgCountMismatch,
GenericArgCountMismatch, GenericArgCountResult, GenericArgPosition, GenericArgCountResult, GenericArgPosition, GenericArgsLowerer,
}; };
use crate::structured_errors::{GenericArgsInfo, StructuredDiag, WrongNumberOfGenericArgs}; use crate::structured_errors::{GenericArgsInfo, StructuredDiag, WrongNumberOfGenericArgs};
use rustc_ast::ast::ParamKindOrd; use rustc_ast::ast::ParamKindOrd;
@ -143,24 +143,22 @@ fn generic_arg_mismatch_err(
err.emit() err.emit()
} }
/// Creates the relevant generic arguments /// Lower generic arguments from the HIR to the [`rustc_middle::ty`] representation.
/// corresponding to a set of generic parameters. This is a ///
/// rather complex function. Let us try to explain the role /// This is a rather complex function. Let us try to explain the role
/// of each of its parameters: /// of each of its parameters:
/// ///
/// To start, we are given the `def_id` of the thing whose generic /// To start, we are given the `def_id` of the thing whose generic parameters we
/// parameters we are instantiating, and a partial set of /// are creating, and a partial set of arguments `parent_args`. In general,
/// arguments `parent_args`. In general, the generic arguments /// the generic arguments for an item begin with arguments for all the "parents"
/// for an item begin with arguments for all the "parents" of /// of that item -- e.g., for a method it might include the parameters from the impl.
/// that item -- e.g., for a method it might include the
/// parameters from the impl.
/// ///
/// Therefore, the method begins by walking down these parents, /// Therefore, the method begins by walking down these parents,
/// starting with the outermost parent and proceed inwards until /// starting with the outermost parent and proceed inwards until
/// it reaches `def_id`. For each parent `P`, it will check `parent_args` /// 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, /// 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 /// we can append those and move on. Otherwise, it uses the provided
/// three callback functions: /// [`GenericArgsLowerer`] `ctx` which has the following methods:
/// ///
/// - `args_for_def_id`: given the `DefId` `P`, supplies back the /// - `args_for_def_id`: given the `DefId` `P`, supplies back the
/// generic arguments that were given to that parent from within /// generic arguments that were given to that parent from within
@ -168,18 +166,18 @@ fn generic_arg_mismatch_err(
/// might refer to the trait `Foo`, and the arguments might be /// might refer to the trait `Foo`, and the arguments might be
/// `[T]`. The boolean value indicates whether to infer values /// `[T]`. The boolean value indicates whether to infer values
/// for arguments whose values were not explicitly provided. /// for arguments whose values were not explicitly provided.
/// - `provided_kind`: given the generic parameter and the value from `args_for_def_id`, /// - `provided_kind`: given the generic parameter and the value
/// instantiate a `GenericArg`. /// from `args_for_def_id`, creating a `GenericArg`.
/// - `inferred_kind`: if no parameter was provided, and inference is enabled, then /// - `inferred_kind`: if no parameter was provided, and inference
/// creates a suitable inference variable. /// is enabled, then creates a suitable inference variable.
pub fn create_args_for_parent_generic_args<'tcx: 'a, 'a>( pub fn lower_generic_args<'tcx: 'a, 'a>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
def_id: DefId, def_id: DefId,
parent_args: &[ty::GenericArg<'tcx>], parent_args: &[ty::GenericArg<'tcx>],
has_self: bool, has_self: bool,
self_ty: Option<Ty<'tcx>>, self_ty: Option<Ty<'tcx>>,
arg_count: &GenericArgCountResult, arg_count: &GenericArgCountResult,
ctx: &mut impl CreateInstantiationsForGenericArgsCtxt<'a, 'tcx>, ctx: &mut impl GenericArgsLowerer<'a, 'tcx>,
) -> GenericArgsRef<'tcx> { ) -> GenericArgsRef<'tcx> {
// Collect the segments of the path; we need to instantiate arguments // Collect the segments of the path; we need to instantiate arguments
// for parameters throughout the entire path (wherever there are // for parameters throughout the entire path (wherever there are
@ -456,7 +454,7 @@ pub(crate) fn check_generic_arg_count(
if gen_pos != GenericArgPosition::Type if gen_pos != GenericArgPosition::Type
&& let Some(b) = gen_args.bindings.first() && let Some(b) = gen_args.bindings.first()
{ {
prohibit_assoc_ty_binding(tcx, b.span, None); prohibit_assoc_item_binding(tcx, b.span, None);
} }
let explicit_late_bound = let explicit_late_bound =

View File

@ -6,9 +6,9 @@ use rustc_lint_defs::{builtin::BARE_TRAIT_OBJECTS, Applicability};
use rustc_span::Span; use rustc_span::Span;
use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName; use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName;
use super::AstConv; use super::HirTyLowerer;
impl<'tcx> dyn AstConv<'tcx> + '_ { impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
/// Make sure that we are in the condition to suggest the blanket implementation. /// Make sure that we are in the condition to suggest the blanket implementation.
pub(super) fn maybe_lint_blanket_trait_impl<G: EmissionGuarantee>( pub(super) fn maybe_lint_blanket_trait_impl<G: EmissionGuarantee>(
&self, &self,

View File

@ -1,6 +1,6 @@
use crate::astconv::{GenericArgCountMismatch, GenericArgCountResult, OnlySelfBounds};
use crate::bounds::Bounds; use crate::bounds::Bounds;
use crate::errors::TraitObjectDeclaredWithNoTraits; use crate::errors::TraitObjectDeclaredWithNoTraits;
use crate::hir_ty_lowering::{GenericArgCountMismatch, GenericArgCountResult, OnlySelfBounds};
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_errors::{codes::*, struct_span_code_err}; use rustc_errors::{codes::*, struct_span_code_err};
use rustc_hir as hir; use rustc_hir as hir;
@ -11,14 +11,16 @@ use rustc_middle::ty::{self, Ty};
use rustc_middle::ty::{DynKind, ToPredicate}; use rustc_middle::ty::{DynKind, ToPredicate};
use rustc_span::Span; use rustc_span::Span;
use rustc_trait_selection::traits::error_reporting::report_object_safety_error; use rustc_trait_selection::traits::error_reporting::report_object_safety_error;
use rustc_trait_selection::traits::{self, astconv_object_safety_violations}; use rustc_trait_selection::traits::{self, hir_ty_lowering_object_safety_violations};
use smallvec::{smallvec, SmallVec}; use smallvec::{smallvec, SmallVec};
use super::AstConv; use super::HirTyLowerer;
impl<'tcx> dyn AstConv<'tcx> + '_ { impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
pub(super) fn conv_object_ty_poly_trait_ref( /// Lower a trait object type from the HIR to our internal notion of a type.
#[instrument(level = "debug", skip_all, ret)]
pub(super) fn lower_trait_object_ty(
&self, &self,
span: Span, span: Span,
hir_id: hir::HirId, hir_id: hir::HirId,
@ -37,7 +39,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
correct: correct:
Err(GenericArgCountMismatch { invalid_args: cur_potential_assoc_types, .. }), Err(GenericArgCountMismatch { invalid_args: cur_potential_assoc_types, .. }),
.. ..
} = self.instantiate_poly_trait_ref( } = self.lower_poly_trait_ref(
&trait_bound.trait_ref, &trait_bound.trait_ref,
trait_bound.span, trait_bound.span,
ty::BoundConstness::NotConst, ty::BoundConstness::NotConst,
@ -133,7 +135,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
// to avoid ICEs. // to avoid ICEs.
for item in &regular_traits { for item in &regular_traits {
let object_safety_violations = let object_safety_violations =
astconv_object_safety_violations(tcx, item.trait_ref().def_id()); hir_ty_lowering_object_safety_violations(tcx, item.trait_ref().def_id());
if !object_safety_violations.is_empty() { if !object_safety_violations.is_empty() {
let reported = report_object_safety_error( let reported = report_object_safety_error(
tcx, tcx,
@ -156,7 +158,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
for (base_trait_ref, span) in regular_traits_refs_spans { for (base_trait_ref, span) in regular_traits_refs_spans {
let base_pred: ty::Predicate<'tcx> = base_trait_ref.to_predicate(tcx); let base_pred: ty::Predicate<'tcx> = base_trait_ref.to_predicate(tcx);
for pred in traits::elaborate(tcx, [base_pred]).filter_only_self() { for pred in traits::elaborate(tcx, [base_pred]).filter_only_self() {
debug!("conv_object_ty_poly_trait_ref: observing object predicate `{:?}`", pred); debug!("observing object predicate `{pred:?}`");
let bound_predicate = pred.kind(); let bound_predicate = pred.kind();
match bound_predicate.skip_binder() { match bound_predicate.skip_binder() {
@ -231,7 +233,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
def_ids.retain(|def_id| !tcx.generics_require_sized_self(def_id)); def_ids.retain(|def_id| !tcx.generics_require_sized_self(def_id));
} }
self.complain_about_missing_associated_types( self.complain_about_missing_assoc_tys(
associated_types, associated_types,
potential_assoc_types, potential_assoc_types,
hir_trait_bounds, hir_trait_bounds,
@ -243,8 +245,8 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
// the bounds // the bounds
let mut duplicates = FxHashSet::default(); let mut duplicates = FxHashSet::default();
auto_traits.retain(|i| duplicates.insert(i.trait_ref().def_id())); auto_traits.retain(|i| duplicates.insert(i.trait_ref().def_id()));
debug!("regular_traits: {:?}", regular_traits); debug!(?regular_traits);
debug!("auto_traits: {:?}", auto_traits); debug!(?auto_traits);
// Erase the `dummy_self` (`trait_object_dummy_self`) used above. // Erase the `dummy_self` (`trait_object_dummy_self`) used above.
let existential_trait_refs = regular_traits.iter().map(|i| { let existential_trait_refs = regular_traits.iter().map(|i| {
@ -362,11 +364,11 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
// Use explicitly-specified region bound. // Use explicitly-specified region bound.
let region_bound = if !lifetime.is_elided() { let region_bound = if !lifetime.is_elided() {
self.ast_region_to_region(lifetime, None) self.lower_lifetime(lifetime, None)
} else { } else {
self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| { self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| {
if tcx.named_bound_var(lifetime.hir_id).is_some() { if tcx.named_bound_var(lifetime.hir_id).is_some() {
self.ast_region_to_region(lifetime, None) self.lower_lifetime(lifetime, None)
} else { } else {
self.re_infer(None, span).unwrap_or_else(|| { self.re_infer(None, span).unwrap_or_else(|| {
let err = struct_span_code_err!( let err = struct_span_code_err!(
@ -389,10 +391,8 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
} }
}) })
}; };
debug!("region_bound: {:?}", region_bound); debug!(?region_bound);
let ty = Ty::new_dynamic(tcx, existential_predicates, region_bound, representation); Ty::new_dynamic(tcx, existential_predicates, region_bound, representation)
debug!("trait_object_type: {:?}", ty);
ty
} }
} }

View File

@ -68,7 +68,7 @@ fn diagnostic_hir_wf_check<'tcx>(
let infcx = self.tcx.infer_ctxt().build(); let infcx = self.tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(&infcx); let ocx = ObligationCtxt::new(&infcx);
let tcx_ty = self.icx.to_ty(ty); let tcx_ty = self.icx.lower_ty(ty);
// This visitor can walk into binders, resulting in the `tcx_ty` to // This visitor can walk into binders, resulting in the `tcx_ty` to
// potentially reference escaping bound variables. We simply erase // potentially reference escaping bound variables. We simply erase
// those here. // those here.

View File

@ -30,8 +30,8 @@ several major phases:
The type checker is defined into various submodules which are documented The type checker is defined into various submodules which are documented
independently: independently:
- astconv: converts the AST representation of types - hir_ty_lowering: lowers type-system entities from the [HIR][hir] to the
into the `ty` representation. [`rustc_middle::ty`] representation.
- collect: computes the types of each top-level item and enters them into - collect: computes the types of each top-level item and enters them into
the `tcx.types` table for later use. the `tcx.types` table for later use.
@ -82,11 +82,11 @@ extern crate rustc_middle;
// These are used by Clippy. // These are used by Clippy.
pub mod check; pub mod check;
pub mod astconv;
pub mod autoderef; pub mod autoderef;
mod bounds; mod bounds;
mod check_unused; mod check_unused;
mod coherence; mod coherence;
pub mod hir_ty_lowering;
// FIXME: This module shouldn't be public. // FIXME: This module shouldn't be public.
pub mod collect; pub mod collect;
mod constrained_generic_params; mod constrained_generic_params;
@ -211,12 +211,20 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
Ok(()) Ok(())
} }
/// A quasi-deprecated helper used in rustdoc and clippy to get /// Lower a [`hir::Ty`] to a [`Ty`].
/// the type from a HIR node. ///
pub fn hir_ty_to_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> { /// <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" // In case there are any projections, etc., find the "environment"
// def-ID that will be used to determine the traits/predicates in // def-ID that will be used to determine the traits/predicates in
// scope. This is derived from the enclosing item-like thing. // scope. This is derived from the enclosing item-like thing.
let env_def_id = tcx.hir().get_parent_item(hir_ty.hir_id); let env_def_id = tcx.hir().get_parent_item(hir_ty.hir_id);
collect::ItemCtxt::new(tcx, env_def_id.def_id).to_ty(hir_ty) collect::ItemCtxt::new(tcx, env_def_id.def_id).lower_ty(hir_ty)
} }

View File

@ -1,6 +1,6 @@
//! Constraint construction and representation //! 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. //! We walk the set of items and, for each member, generate new constraints.
use hir::def_id::{DefId, LocalDefId}; use hir::def_id::{DefId, LocalDefId};

View File

@ -5,7 +5,7 @@ use super::{check_fn, CoroutineTypes, Expectation, FnCtxt};
use rustc_errors::ErrorGuaranteed; use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::lang_items::LangItem; use rustc_hir::lang_items::LangItem;
use rustc_hir_analysis::astconv::AstConv; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes}; use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes};
use rustc_infer::infer::{InferOk, InferResult}; use rustc_infer::infer::{InferOk, InferResult};
@ -784,7 +784,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
decl: &hir::FnDecl<'tcx>, decl: &hir::FnDecl<'tcx>,
closure_kind: hir::ClosureKind, closure_kind: hir::ClosureKind,
) -> ty::PolyFnSig<'tcx> { ) -> ty::PolyFnSig<'tcx> {
let astconv = self.astconv(); let lowerer = self.lowerer();
trace!("decl = {:#?}", decl); trace!("decl = {:#?}", decl);
debug!(?closure_kind); debug!(?closure_kind);
@ -793,9 +793,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let bound_vars = self.tcx.late_bound_vars(hir_id); let bound_vars = self.tcx.late_bound_vars(hir_id);
// First, convert the types that the user supplied (if any). // First, convert the types that the user supplied (if any).
let supplied_arguments = decl.inputs.iter().map(|a| astconv.ast_ty_to_ty(a)); let supplied_arguments = decl.inputs.iter().map(|a| lowerer.lower_ty(a));
let supplied_return = match decl.output { let supplied_return = match decl.output {
hir::FnRetTy::Return(ref output) => astconv.ast_ty_to_ty(output), hir::FnRetTy::Return(ref output) => lowerer.lower_ty(output),
hir::FnRetTy::DefaultReturn(_) => match closure_kind { hir::FnRetTy::DefaultReturn(_) => match closure_kind {
// In the case of the async block that we create for a function body, // In the case of the async block that we create for a function body,
// we expect the return type of the block to match that of the enclosing // we expect the return type of the block to match that of the enclosing
@ -813,7 +813,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// easily (and locally) prove that we // easily (and locally) prove that we
// *have* reported an // *have* reported an
// error. --nikomatsakis // error. --nikomatsakis
astconv.ty_infer(None, decl.output.span()) lowerer.ty_infer(None, decl.output.span())
}) })
} }
// All `gen {}` and `async gen {}` must return unit. // All `gen {}` and `async gen {}` must return unit.
@ -832,7 +832,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
| hir::ClosureKind::Coroutine(hir::CoroutineKind::Coroutine(_)) | hir::ClosureKind::Coroutine(hir::CoroutineKind::Coroutine(_))
| hir::ClosureKind::Closure | hir::ClosureKind::Closure
| hir::ClosureKind::CoroutineClosure(_) => { | hir::ClosureKind::CoroutineClosure(_) => {
astconv.ty_infer(None, decl.output.span()) lowerer.ty_infer(None, decl.output.span())
} }
}, },
}; };
@ -989,17 +989,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
decl: &hir::FnDecl<'tcx>, decl: &hir::FnDecl<'tcx>,
guar: ErrorGuaranteed, guar: ErrorGuaranteed,
) -> ty::PolyFnSig<'tcx> { ) -> ty::PolyFnSig<'tcx> {
let astconv = self.astconv(); let lowerer = self.lowerer();
let err_ty = Ty::new_error(self.tcx, guar); let err_ty = Ty::new_error(self.tcx, guar);
let supplied_arguments = decl.inputs.iter().map(|a| { let supplied_arguments = decl.inputs.iter().map(|a| {
// Convert the types that the user supplied (if any), but ignore them. // Convert the types that the user supplied (if any), but ignore them.
astconv.ast_ty_to_ty(a); lowerer.lower_ty(a);
err_ty err_ty
}); });
if let hir::FnRetTy::Return(ref output) = decl.output { if let hir::FnRetTy::Return(ref output) = decl.output {
astconv.ast_ty_to_ty(output); lowerer.lower_ty(output);
} }
let result = ty::Binder::dummy(self.tcx.mk_fn_sig( let result = ty::Binder::dummy(self.tcx.mk_fn_sig(

View File

@ -41,7 +41,7 @@ use rustc_hir as hir;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::Expr; use rustc_hir::Expr;
use rustc_hir_analysis::astconv::AstConv; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult}; use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult};
use rustc_infer::traits::TraitEngine; use rustc_infer::traits::TraitEngine;

View File

@ -35,8 +35,8 @@ use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor; use rustc_hir::intravisit::Visitor;
use rustc_hir::lang_items::LangItem; use rustc_hir::lang_items::LangItem;
use rustc_hir::{ExprKind, HirId, QPath}; use rustc_hir::{ExprKind, HirId, QPath};
use rustc_hir_analysis::astconv::AstConv as _;
use rustc_hir_analysis::check::ty_kind_suggestion; use rustc_hir_analysis::check::ty_kind_suggestion;
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer as _;
use rustc_infer::infer; use rustc_infer::infer;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::infer::DefineOpaqueTypes;
@ -333,7 +333,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
ExprKind::Cast(e, t) => self.check_expr_cast(e, t, expr), ExprKind::Cast(e, t) => self.check_expr_cast(e, t, expr),
ExprKind::Type(e, t) => { ExprKind::Type(e, t) => {
let ascribed_ty = self.to_ty_saving_user_provided_ty(t); let ascribed_ty = self.lower_ty_saving_user_provided_ty(t);
let ty = self.check_expr_with_hint(e, ascribed_ty); let ty = self.check_expr_with_hint(e, ascribed_ty);
self.demand_eqtype(e.span, ascribed_ty, ty); self.demand_eqtype(e.span, ascribed_ty, ty);
ascribed_ty ascribed_ty
@ -1375,7 +1375,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> Ty<'tcx> { ) -> Ty<'tcx> {
// Find the type of `e`. Supply hints based on the type we are casting to, // Find the type of `e`. Supply hints based on the type we are casting to,
// if appropriate. // if appropriate.
let t_cast = self.to_ty_saving_user_provided_ty(t); let t_cast = self.lower_ty_saving_user_provided_ty(t);
let t_cast = self.resolve_vars_if_possible(t_cast); let t_cast = self.resolve_vars_if_possible(t_cast);
let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast)); let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
let t_expr = self.resolve_vars_if_possible(t_expr); let t_expr = self.resolve_vars_if_possible(t_expr);
@ -1503,7 +1503,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expr: &'tcx hir::Expr<'tcx>, expr: &'tcx hir::Expr<'tcx>,
) -> Ty<'tcx> { ) -> Ty<'tcx> {
let tcx = self.tcx; let tcx = self.tcx;
let count = self.array_length_to_const(count); let count = self.lower_array_length(count);
if let Some(count) = count.try_eval_target_usize(tcx, self.param_env) { if let Some(count) = count.try_eval_target_usize(tcx, self.param_env) {
self.suggest_array_len(expr, count); self.suggest_array_len(expr, count);
} }
@ -1679,7 +1679,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
span: Span, span: Span,
variant: &'tcx ty::VariantDef, variant: &'tcx ty::VariantDef,
ast_fields: &'tcx [hir::ExprField<'tcx>], hir_fields: &'tcx [hir::ExprField<'tcx>],
base_expr: &'tcx Option<&'tcx hir::Expr<'tcx>>, base_expr: &'tcx Option<&'tcx hir::Expr<'tcx>>,
) { ) {
let tcx = self.tcx; let tcx = self.tcx;
@ -1710,7 +1710,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut error_happened = false; let mut error_happened = false;
// Type-check each field. // Type-check each field.
for (idx, field) in ast_fields.iter().enumerate() { for (idx, field) in hir_fields.iter().enumerate() {
let ident = tcx.adjust_ident(field.ident, variant.def_id); let ident = tcx.adjust_ident(field.ident, variant.def_id);
let field_type = if let Some((i, v_field)) = remaining_fields.remove(&ident) { let field_type = if let Some((i, v_field)) = remaining_fields.remove(&ident) {
seen_fields.insert(ident, field.span); seen_fields.insert(ident, field.span);
@ -1739,7 +1739,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
variant, variant,
expr, expr,
field, field,
ast_fields, hir_fields,
adt.variant_descr(), adt.variant_descr(),
) )
}; };
@ -1754,7 +1754,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.demand_coerce_diag(field.expr, ty, field_type, None, AllowTwoPhase::No); self.demand_coerce_diag(field.expr, ty, field_type, None, AllowTwoPhase::No);
if let Some(diag) = diag { if let Some(diag) = diag {
if idx == ast_fields.len() - 1 { if idx == hir_fields.len() - 1 {
if remaining_fields.is_empty() { if remaining_fields.is_empty() {
self.suggest_fru_from_range_and_emit(field, variant, args, diag); self.suggest_fru_from_range_and_emit(field, variant, args, diag);
} else { } else {
@ -1768,7 +1768,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Make sure the programmer specified correct number of fields. // Make sure the programmer specified correct number of fields.
if adt_kind == AdtKind::Union { if adt_kind == AdtKind::Union {
if ast_fields.len() != 1 { if hir_fields.len() != 1 {
struct_span_code_err!( struct_span_code_err!(
tcx.dcx(), tcx.dcx(),
span, span,
@ -1905,14 +1905,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.collect(); .collect();
if !private_fields.is_empty() { if !private_fields.is_empty() {
self.report_private_fields(adt_ty, span, expr.span, private_fields, ast_fields); self.report_private_fields(adt_ty, span, expr.span, private_fields, hir_fields);
} else { } else {
self.report_missing_fields( self.report_missing_fields(
adt_ty, adt_ty,
span, span,
remaining_fields, remaining_fields,
variant, variant,
ast_fields, hir_fields,
args, args,
); );
} }
@ -1949,7 +1949,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span: Span, span: Span,
remaining_fields: UnordMap<Ident, (FieldIdx, &ty::FieldDef)>, remaining_fields: UnordMap<Ident, (FieldIdx, &ty::FieldDef)>,
variant: &'tcx ty::VariantDef, variant: &'tcx ty::VariantDef,
ast_fields: &'tcx [hir::ExprField<'tcx>], hir_fields: &'tcx [hir::ExprField<'tcx>],
args: GenericArgsRef<'tcx>, args: GenericArgsRef<'tcx>,
) { ) {
let len = remaining_fields.len(); let len = remaining_fields.len();
@ -1986,8 +1986,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
); );
err.span_label(span, format!("missing {remaining_fields_names}{truncated_fields_error}")); err.span_label(span, format!("missing {remaining_fields_names}{truncated_fields_error}"));
if let Some(last) = ast_fields.last() { if let Some(hir_field) = hir_fields.last() {
self.suggest_fru_from_range_and_emit(last, variant, args, err); self.suggest_fru_from_range_and_emit(hir_field, variant, args, err);
} else { } else {
err.emit(); err.emit();
} }
@ -3283,7 +3283,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fields: &[Ident], fields: &[Ident],
expr: &'tcx hir::Expr<'tcx>, expr: &'tcx hir::Expr<'tcx>,
) -> Ty<'tcx> { ) -> Ty<'tcx> {
let container = self.to_ty(container).normalized; let container = self.lower_ty(container).normalized;
if let Some(ident_2) = fields.get(1) if let Some(ident_2) = fields.get(1)
&& !self.tcx.features().offset_of_nested && !self.tcx.features().offset_of_nested

View File

@ -11,12 +11,12 @@ use rustc_hir::def::{CtorOf, DefKind, Res};
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::lang_items::LangItem; use rustc_hir::lang_items::LangItem;
use rustc_hir::{ExprKind, GenericArg, Node, QPath}; use rustc_hir::{ExprKind, GenericArg, Node, QPath};
use rustc_hir_analysis::astconv::generics::{ use rustc_hir_analysis::hir_ty_lowering::generics::{
check_generic_arg_count_for_call, create_args_for_parent_generic_args, check_generic_arg_count_for_call, lower_generic_args,
}; };
use rustc_hir_analysis::astconv::{ use rustc_hir_analysis::hir_ty_lowering::{
AstConv, CreateInstantiationsForGenericArgsCtxt, ExplicitLateBound, GenericArgCountMismatch, ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, GenericArgsLowerer,
GenericArgCountResult, IsMethodCall, PathSeg, GenericPathSegment, HirTyLowerer, IsMethodCall,
}; };
use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse}; use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282; use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
@ -394,20 +394,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
} }
pub fn to_ty(&self, ast_t: &hir::Ty<'tcx>) -> LoweredTy<'tcx> { pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> LoweredTy<'tcx> {
let t = self.astconv().ast_ty_to_ty(ast_t); let ty = self.lowerer().lower_ty(hir_ty);
self.register_wf_obligation(t.into(), ast_t.span, traits::WellFormed(None)); self.register_wf_obligation(ty.into(), hir_ty.span, traits::WellFormed(None));
LoweredTy::from_raw(self, ast_t.span, t) LoweredTy::from_raw(self, hir_ty.span, ty)
} }
pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty<'tcx>) -> Ty<'tcx> { #[instrument(level = "debug", skip_all)]
let ty = self.to_ty(ast_ty); pub fn lower_ty_saving_user_provided_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
debug!("to_ty_saving_user_provided_ty: ty={:?}", ty); let ty = self.lower_ty(hir_ty);
debug!(?ty);
if Self::can_contain_user_lifetime_bounds(ty.raw) { if Self::can_contain_user_lifetime_bounds(ty.raw) {
let c_ty = self.canonicalize_response(UserType::Ty(ty.raw)); let c_ty = self.canonicalize_response(UserType::Ty(ty.raw));
debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty); debug!(?c_ty);
self.typeck_results.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty); self.typeck_results.borrow_mut().user_provided_types_mut().insert(hir_ty.hir_id, c_ty);
} }
ty.normalized ty.normalized
@ -424,7 +425,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
} }
pub fn array_length_to_const(&self, length: &hir::ArrayLen) -> ty::Const<'tcx> { pub fn lower_array_length(&self, length: &hir::ArrayLen) -> ty::Const<'tcx> {
match length { match length {
hir::ArrayLen::Infer(inf) => self.ct_infer(self.tcx.types.usize, None, inf.span), hir::ArrayLen::Infer(inf) => self.ct_infer(self.tcx.types.usize, None, inf.span),
hir::ArrayLen::Body(anon_const) => { hir::ArrayLen::Body(anon_const) => {
@ -436,20 +437,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
} }
pub fn const_arg_to_const( pub fn lower_const_arg(&self, hir_ct: &hir::AnonConst, param_def_id: DefId) -> ty::Const<'tcx> {
&self, let did = hir_ct.def_id;
ast_c: &hir::AnonConst,
param_def_id: DefId,
) -> ty::Const<'tcx> {
let did = ast_c.def_id;
self.tcx.feed_anon_const_type(did, self.tcx.type_of(param_def_id)); self.tcx.feed_anon_const_type(did, self.tcx.type_of(param_def_id));
let c = ty::Const::from_anon_const(self.tcx, did); let ct = ty::Const::from_anon_const(self.tcx, did);
self.register_wf_obligation( self.register_wf_obligation(
c.into(), ct.into(),
self.tcx.hir().span(ast_c.hir_id), self.tcx.hir().span(hir_ct.hir_id),
ObligationCauseCode::WellFormed(None), ObligationCauseCode::WellFormed(None),
); );
c ct
} }
// If the type given by the user has free regions, save it for later, since // If the type given by the user has free regions, save it for later, since
@ -827,12 +824,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
QPath::Resolved(ref opt_qself, path) => { QPath::Resolved(ref opt_qself, path) => {
return ( return (
path.res, path.res,
opt_qself.as_ref().map(|qself| self.to_ty(qself)), opt_qself.as_ref().map(|qself| self.lower_ty(qself)),
path.segments, path.segments,
); );
} }
QPath::TypeRelative(ref qself, ref segment) => { 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 // If we're trying to call a nonexistent method on a trait
// (e.g. `MyTrait::missing_method`), then resolution will // (e.g. `MyTrait::missing_method`), then resolution will
// give us a `QPath::TypeRelative` with a trait object as // give us a `QPath::TypeRelative` with a trait object as
@ -841,7 +838,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// to be object-safe. // to be object-safe.
// We manually call `register_wf_obligation` in the success path // We manually call `register_wf_obligation` in the success path
// below. // below.
let ty = self.astconv().ast_ty_to_ty_in_path(qself); let ty = self.lowerer().lower_ty_in_path(qself);
(LoweredTy::from_raw(self, span, ty), qself, segment) (LoweredTy::from_raw(self, span, ty), qself, segment)
} }
QPath::LangItem(..) => { QPath::LangItem(..) => {
@ -1119,9 +1116,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> (Ty<'tcx>, Res) { ) -> (Ty<'tcx>, Res) {
let tcx = self.tcx; let tcx = self.tcx;
let path_segs = match res { let generic_segments = match res {
Res::Local(_) | Res::SelfCtor(_) => vec![], Res::Local(_) | Res::SelfCtor(_) => vec![],
Res::Def(kind, def_id) => self.astconv().def_ids_for_value_path_segments( Res::Def(kind, def_id) => self.lowerer().probe_generic_path_segments(
segments, segments,
self_ty.map(|ty| ty.raw), self_ty.map(|ty| ty.raw),
kind, kind,
@ -1178,14 +1175,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// provided (if any) into their appropriate spaces. We'll also report // provided (if any) into their appropriate spaces. We'll also report
// errors if type parameters are provided in an inappropriate place. // errors if type parameters are provided in an inappropriate place.
let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect(); let indices: FxHashSet<_> =
let generics_has_err = self.astconv().prohibit_generics( generic_segments.iter().map(|GenericPathSegment(_, index)| index).collect();
let generics_has_err = self.lowerer().prohibit_generic_args(
segments.iter().enumerate().filter_map(|(index, seg)| { segments.iter().enumerate().filter_map(|(index, seg)| {
if !generic_segs.contains(&index) || is_alias_variant_ctor { if !indices.contains(&index) || is_alias_variant_ctor { Some(seg) } else { None }
Some(seg)
} else {
None
}
}), }),
|_| {}, |_| {},
); );
@ -1212,7 +1206,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut infer_args_for_err = FxHashSet::default(); let mut infer_args_for_err = FxHashSet::default();
let mut explicit_late_bound = ExplicitLateBound::No; let mut explicit_late_bound = ExplicitLateBound::No;
for &PathSeg(def_id, index) in &path_segs { for &GenericPathSegment(def_id, index) in &generic_segments {
let seg = &segments[index]; let seg = &segments[index];
let generics = tcx.generics_of(def_id); let generics = tcx.generics_of(def_id);
@ -1233,8 +1227,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
} }
let has_self = let has_self = generic_segments
path_segs.last().is_some_and(|PathSeg(def_id, _)| tcx.generics_of(*def_id).has_self); .last()
.is_some_and(|GenericPathSegment(def_id, _)| tcx.generics_of(*def_id).has_self);
let (res, self_ctor_args) = if let Res::SelfCtor(impl_def_id) = res { let (res, self_ctor_args) = if let Res::SelfCtor(impl_def_id) = res {
let ty = LoweredTy::from_raw( let ty = LoweredTy::from_raw(
@ -1294,22 +1289,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}, },
}; };
struct CreateCtorInstantiationsContext<'a, 'tcx> { struct CtorGenericArgsCtxt<'a, 'tcx> {
fcx: &'a FnCtxt<'a, 'tcx>, fcx: &'a FnCtxt<'a, 'tcx>,
span: Span, span: Span,
path_segs: &'a [PathSeg], generic_segments: &'a [GenericPathSegment],
infer_args_for_err: &'a FxHashSet<usize>, infer_args_for_err: &'a FxHashSet<usize>,
segments: &'tcx [hir::PathSegment<'tcx>], segments: &'tcx [hir::PathSegment<'tcx>],
} }
impl<'tcx, 'a> CreateInstantiationsForGenericArgsCtxt<'a, 'tcx> impl<'tcx, 'a> GenericArgsLowerer<'a, 'tcx> for CtorGenericArgsCtxt<'a, 'tcx> {
for CreateCtorInstantiationsContext<'a, 'tcx>
{
fn args_for_def_id( fn args_for_def_id(
&mut self, &mut self,
def_id: DefId, def_id: DefId,
) -> (Option<&'a hir::GenericArgs<'tcx>>, bool) { ) -> (Option<&'a hir::GenericArgs<'tcx>>, bool) {
if let Some(&PathSeg(_, index)) = if let Some(&GenericPathSegment(_, index)) =
self.path_segs.iter().find(|&PathSeg(did, _)| *did == def_id) self.generic_segments.iter().find(|&GenericPathSegment(did, _)| *did == def_id)
{ {
// If we've encountered an `impl Trait`-related error, we're just // If we've encountered an `impl Trait`-related error, we're just
// going to infer the arguments for better error messages. // going to infer the arguments for better error messages.
@ -1332,13 +1325,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> ty::GenericArg<'tcx> { ) -> ty::GenericArg<'tcx> {
match (&param.kind, arg) { match (&param.kind, arg) {
(GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => { (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
self.fcx.astconv().ast_region_to_region(lt, Some(param)).into() self.fcx.lowerer().lower_lifetime(lt, Some(param)).into()
} }
(GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => { (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
self.fcx.to_ty(ty).raw.into() self.fcx.lower_ty(ty).raw.into()
} }
(GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => { (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => {
self.fcx.const_arg_to_const(&ct.value, param.def_id).into() self.fcx.lower_const_arg(&ct.value, param.def_id).into()
} }
(GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => { (GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => {
self.fcx.ty_infer(Some(param), inf.span).into() self.fcx.ty_infer(Some(param), inf.span).into()
@ -1420,17 +1413,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
let args_raw = self_ctor_args.unwrap_or_else(|| { let args_raw = self_ctor_args.unwrap_or_else(|| {
create_args_for_parent_generic_args( lower_generic_args(
tcx, tcx,
def_id, def_id,
&[], &[],
has_self, has_self,
self_ty.map(|s| s.raw), self_ty.map(|s| s.raw),
&arg_count, &arg_count,
&mut CreateCtorInstantiationsContext { &mut CtorGenericArgsCtxt {
fcx: self, fcx: self,
span, span,
path_segs: &path_segs, generic_segments: &generic_segments,
infer_args_for_err: &infer_args_for_err, infer_args_for_err: &infer_args_for_err,
segments, segments,
}, },

View File

@ -24,9 +24,9 @@ use rustc_hir::def::{CtorOf, DefKind, Res};
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor; use rustc_hir::intravisit::Visitor;
use rustc_hir::{ExprKind, Node, QPath}; use rustc_hir::{ExprKind, Node, QPath};
use rustc_hir_analysis::astconv::AstConv;
use rustc_hir_analysis::check::intrinsicck::InlineAsmCtxt; use rustc_hir_analysis::check::intrinsicck::InlineAsmCtxt;
use rustc_hir_analysis::check::potentially_plural_count; use rustc_hir_analysis::check::potentially_plural_count;
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
use rustc_hir_analysis::structured_errors::StructuredDiag; use rustc_hir_analysis::structured_errors::StructuredDiag;
use rustc_index::IndexVec; use rustc_index::IndexVec;
use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt}; use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt};
@ -1961,16 +1961,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> (Res, LoweredTy<'tcx>) { ) -> (Res, LoweredTy<'tcx>) {
match *qpath { match *qpath {
QPath::Resolved(ref maybe_qself, path) => { QPath::Resolved(ref maybe_qself, path) => {
let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself).raw); let self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself).raw);
let ty = self.astconv().res_to_ty(self_ty, path, hir_id, true); let ty = self.lowerer().lower_path(self_ty, path, hir_id, true);
(path.res, LoweredTy::from_raw(self, path_span, ty)) (path.res, LoweredTy::from_raw(self, path_span, ty))
} }
QPath::TypeRelative(qself, segment) => { QPath::TypeRelative(qself, segment) => {
let ty = self.to_ty(qself); let ty = self.lower_ty(qself);
let result = self let result = self
.astconv() .lowerer()
.associated_path_to_ty(hir_id, path_span, ty.raw, qself, segment, true); .lower_assoc_path(hir_id, path_span, ty.raw, qself, segment, true);
let ty = result let ty = result
.map(|(ty, _, _)| ty) .map(|(ty, _, _)| ty)
.unwrap_or_else(|guar| Ty::new_error(self.tcx(), guar)); .unwrap_or_else(|guar| Ty::new_error(self.tcx(), guar));

View File

@ -12,7 +12,7 @@ use hir::def_id::CRATE_DEF_ID;
use rustc_errors::{DiagCtxt, ErrorGuaranteed}; use rustc_errors::{DiagCtxt, ErrorGuaranteed};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir_analysis::astconv::AstConv; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
use rustc_infer::infer; use rustc_infer::infer;
use rustc_infer::infer::error_reporting::sub_relations::SubRelations; use rustc_infer::infer::error_reporting::sub_relations::SubRelations;
use rustc_infer::infer::error_reporting::TypeErrCtxt; use rustc_infer::infer::error_reporting::TypeErrCtxt;
@ -212,7 +212,7 @@ impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> {
} }
} }
impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { impl<'a, 'tcx> HirTyLowerer<'tcx> for FnCtxt<'a, 'tcx> {
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
self.tcx self.tcx
} }
@ -221,31 +221,8 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
self.body_id.to_def_id() self.body_id.to_def_id()
} }
fn get_type_parameter_bounds( fn allow_infer(&self) -> bool {
&self, true
_: Span,
def_id: LocalDefId,
_: Ident,
) -> ty::GenericPredicates<'tcx> {
let tcx = self.tcx;
let item_def_id = tcx.hir().ty_param_owner(def_id);
let generics = tcx.generics_of(item_def_id);
let index = generics.param_def_id_to_index[&def_id.to_def_id()];
// HACK(eddyb) should get the original `Span`.
let span = tcx.def_span(def_id);
ty::GenericPredicates {
parent: None,
predicates: tcx.arena.alloc_from_iter(
self.param_env.caller_bounds().iter().filter_map(|predicate| {
match predicate.kind().skip_binder() {
ty::ClauseKind::Trait(data) if data.self_ty().is_param(index) => {
Some((predicate, span))
}
_ => None,
}
}),
),
}
} }
fn re_infer(&self, def: Option<&ty::GenericParamDef>, span: Span) -> Option<ty::Region<'tcx>> { fn re_infer(&self, def: Option<&ty::GenericParamDef>, span: Span) -> Option<ty::Region<'tcx>> {
@ -256,10 +233,6 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
Some(self.next_region_var(v)) Some(self.next_region_var(v))
} }
fn allow_ty_infer(&self) -> bool {
true
}
fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> { fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
match param { match param {
Some(param) => self.var_for_def(span, param).as_type().unwrap(), Some(param) => self.var_for_def(span, param).as_type().unwrap(),
@ -292,7 +265,34 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
} }
} }
fn projected_ty_from_poly_trait_ref( fn probe_ty_param_bounds(
&self,
_: Span,
def_id: LocalDefId,
_: Ident,
) -> ty::GenericPredicates<'tcx> {
let tcx = self.tcx;
let item_def_id = tcx.hir().ty_param_owner(def_id);
let generics = tcx.generics_of(item_def_id);
let index = generics.param_def_id_to_index[&def_id.to_def_id()];
// HACK(eddyb) should get the original `Span`.
let span = tcx.def_span(def_id);
ty::GenericPredicates {
parent: None,
predicates: tcx.arena.alloc_from_iter(
self.param_env.caller_bounds().iter().filter_map(|predicate| {
match predicate.kind().skip_binder() {
ty::ClauseKind::Trait(data) if data.self_ty().is_param(index) => {
Some((predicate, span))
}
_ => None,
}
}),
),
}
}
fn lower_assoc_ty(
&self, &self,
span: Span, span: Span,
item_def_id: DefId, item_def_id: DefId,
@ -305,7 +305,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
poly_trait_ref, poly_trait_ref,
); );
let item_args = self.astconv().create_args_for_associated_item( let item_args = self.lowerer().lower_generic_args_of_assoc_item(
span, span,
item_def_id, item_def_id,
item_segment, item_segment,
@ -328,10 +328,6 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
} }
} }
fn set_tainted_by_errors(&self, e: ErrorGuaranteed) {
self.infcx.set_tainted_by_errors(e)
}
fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span) { fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span) {
// FIXME: normalization and escaping regions // FIXME: normalization and escaping regions
let ty = if !ty.has_escaping_bound_vars() { let ty = if !ty.has_escaping_bound_vars() {
@ -355,13 +351,17 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
fn infcx(&self) -> Option<&infer::InferCtxt<'tcx>> { fn infcx(&self) -> Option<&infer::InferCtxt<'tcx>> {
Some(&self.infcx) Some(&self.infcx)
} }
fn set_tainted_by_errors(&self, e: ErrorGuaranteed) {
self.infcx.set_tainted_by_errors(e)
}
} }
/// The `ty` representation of a user-provided type. Depending on the use-site /// 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. /// 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`, /// This is a bridge between the interface of HIR ty lowering, which outputs a raw
/// and the API in this module, which expect `Ty` to be fully normalized. /// `Ty`, and the API in this module, which expect `Ty` to be fully normalized.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct LoweredTy<'tcx> { pub struct LoweredTy<'tcx> {
/// The unnormalized type provided by the user. /// The unnormalized type provided by the user.

View File

@ -21,7 +21,7 @@ use rustc_hir::{
CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, GenericBound, HirId, Node, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, GenericBound, HirId, Node,
Path, QPath, Stmt, StmtKind, TyKind, WherePredicate, Path, QPath, Stmt, StmtKind, TyKind, WherePredicate,
}; };
use rustc_hir_analysis::astconv::AstConv; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
use rustc_infer::traits::{self}; use rustc_infer::traits::{self};
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;
use rustc_middle::middle::stability::EvalResult; use rustc_middle::middle::stability::EvalResult;
@ -877,7 +877,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Only point to return type if the expected type is the return type, as if they // Only point to return type if the expected type is the return type, as if they
// are not, the expectation must have been caused by something else. // are not, the expectation must have been caused by something else.
debug!("return type {:?}", hir_ty); debug!("return type {:?}", hir_ty);
let ty = self.astconv().ast_ty_to_ty(hir_ty); let ty = self.lowerer().lower_ty(hir_ty);
debug!("return type {:?}", ty); debug!("return type {:?}", ty);
debug!("expected type {:?}", expected); debug!("expected type {:?}", expected);
let bound_vars = self.tcx.late_bound_vars(hir_ty.hir_id.owner.into()); let bound_vars = self.tcx.late_bound_vars(hir_ty.hir_id.owner.into());
@ -957,8 +957,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
bounded_ty, 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.astconv().ast_ty_to_ty(bounded_ty); let ty = self.lowerer().lower_ty(bounded_ty);
Some((ty, bounds)) Some((ty, bounds))
} }
_ => None, _ => None,
@ -996,7 +996,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let all_bounds_str = all_matching_bounds_strs.join(" + "); let all_bounds_str = all_matching_bounds_strs.join(" + ");
let ty_param_used_in_fn_params = fn_parameters.iter().any(|param| { let ty_param_used_in_fn_params = fn_parameters.iter().any(|param| {
let ty = self.astconv().ast_ty_to_ty( param); let ty = self.lowerer().lower_ty( param);
matches!(ty.kind(), ty::Param(fn_param_ty_param) if expected_ty_as_param == fn_param_ty_param) matches!(ty.kind(), ty::Param(fn_param_ty_param) if expected_ty_as_param == fn_param_ty_param)
}); });
@ -1071,7 +1071,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let can_return = match fn_decl.output { let can_return = match fn_decl.output {
hir::FnRetTy::Return(ty) => { hir::FnRetTy::Return(ty) => {
let ty = self.astconv().ast_ty_to_ty(ty); let ty = self.lowerer().lower_ty(ty);
let bound_vars = self.tcx.late_bound_vars(fn_id); let bound_vars = self.tcx.late_bound_vars(fn_id);
let ty = self let ty = self
.tcx .tcx

View File

@ -93,7 +93,7 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
fn declare(&mut self, decl: Declaration<'tcx>) { fn declare(&mut self, decl: Declaration<'tcx>) {
let local_ty = match decl.ty { let local_ty = match decl.ty {
Some(ref ty) => { Some(ref ty) => {
let o_ty = self.fcx.to_ty(ty); let o_ty = self.fcx.lower_ty(ty);
let c_ty = let c_ty =
self.fcx.inh.infcx.canonicalize_user_type_annotation(UserType::Ty(o_ty.raw)); self.fcx.inh.infcx.canonicalize_user_type_annotation(UserType::Ty(o_ty.raw));

View File

@ -57,8 +57,8 @@ use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir::intravisit::Visitor; use rustc_hir::intravisit::Visitor;
use rustc_hir::{HirIdMap, Node}; use rustc_hir::{HirIdMap, Node};
use rustc_hir_analysis::astconv::AstConv;
use rustc_hir_analysis::check::check_abi; use rustc_hir_analysis::check::check_abi;
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::traits::{ObligationCauseCode, ObligationInspector, WellFormedLoc}; use rustc_infer::traits::{ObligationCauseCode, ObligationInspector, WellFormedLoc};
use rustc_middle::query::Providers; use rustc_middle::query::Providers;
@ -178,7 +178,7 @@ fn typeck_with_fallback<'tcx>(
if let Some(hir::FnSig { header, decl, .. }) = fn_sig { if let Some(hir::FnSig { header, decl, .. }) = fn_sig {
let fn_sig = if decl.output.get_infer_ret_ty().is_some() { let fn_sig = if decl.output.get_infer_ret_ty().is_some() {
fcx.astconv().ty_of_fn(id, header.unsafety, header.abi, decl, None, None) fcx.lowerer().lower_fn_ty(id, header.unsafety, header.abi, decl, None, None)
} else { } else {
tcx.fn_sig(def_id).instantiate_identity() tcx.fn_sig(def_id).instantiate_identity()
}; };

View File

@ -4,10 +4,10 @@ use crate::{callee, FnCtxt};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::GenericArg; use rustc_hir::GenericArg;
use rustc_hir_analysis::astconv::generics::{ use rustc_hir_analysis::hir_ty_lowering::generics::{
check_generic_arg_count_for_call, create_args_for_parent_generic_args, check_generic_arg_count_for_call, lower_generic_args,
}; };
use rustc_hir_analysis::astconv::{AstConv, CreateInstantiationsForGenericArgsCtxt, IsMethodCall}; use rustc_hir_analysis::hir_ty_lowering::{GenericArgsLowerer, HirTyLowerer, IsMethodCall};
use rustc_infer::infer::{self, DefineOpaqueTypes, InferOk}; use rustc_infer::infer::{self, DefineOpaqueTypes, InferOk};
use rustc_middle::traits::{ObligationCauseCode, UnifyReceiverContext}; use rustc_middle::traits::{ObligationCauseCode, UnifyReceiverContext};
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
@ -366,14 +366,12 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
// combining parameters from the type and those from the method. // combining parameters from the type and those from the method.
assert_eq!(generics.parent_count, parent_args.len()); assert_eq!(generics.parent_count, parent_args.len());
struct MethodInstantiationsCtxt<'a, 'tcx> { struct GenericArgsCtxt<'a, 'tcx> {
cfcx: &'a ConfirmContext<'a, 'tcx>, cfcx: &'a ConfirmContext<'a, 'tcx>,
pick: &'a probe::Pick<'tcx>, pick: &'a probe::Pick<'tcx>,
seg: &'a hir::PathSegment<'tcx>, seg: &'a hir::PathSegment<'tcx>,
} }
impl<'a, 'tcx> CreateInstantiationsForGenericArgsCtxt<'a, 'tcx> impl<'a, 'tcx> GenericArgsLowerer<'a, 'tcx> for GenericArgsCtxt<'a, 'tcx> {
for MethodInstantiationsCtxt<'a, 'tcx>
{
fn args_for_def_id( fn args_for_def_id(
&mut self, &mut self,
def_id: DefId, def_id: DefId,
@ -393,13 +391,13 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
) -> ty::GenericArg<'tcx> { ) -> ty::GenericArg<'tcx> {
match (&param.kind, arg) { match (&param.kind, arg) {
(GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => { (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
self.cfcx.fcx.astconv().ast_region_to_region(lt, Some(param)).into() self.cfcx.fcx.lowerer().lower_lifetime(lt, Some(param)).into()
} }
(GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => { (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
self.cfcx.to_ty(ty).raw.into() self.cfcx.lower_ty(ty).raw.into()
} }
(GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => { (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => {
self.cfcx.const_arg_to_const(&ct.value, param.def_id).into() self.cfcx.lower_const_arg(&ct.value, param.def_id).into()
} }
(GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => { (GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => {
self.cfcx.ty_infer(Some(param), inf.span).into() self.cfcx.ty_infer(Some(param), inf.span).into()
@ -432,14 +430,14 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
} }
} }
let args = create_args_for_parent_generic_args( let args = lower_generic_args(
self.tcx, self.tcx,
pick.item.def_id, pick.item.def_id,
parent_args, parent_args,
false, false,
None, None,
&arg_count_correct, &arg_count_correct,
&mut MethodInstantiationsCtxt { cfcx: self, pick, seg }, &mut GenericArgsCtxt { cfcx: self, pick, seg },
); );
// When the method is confirmed, the `args` includes // When the method is confirmed, the `args` includes

View File

@ -3264,8 +3264,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Colon, Colon,
Nothing, Nothing,
} }
let ast_generics = hir.get_generics(id.owner.def_id).unwrap(); let hir_generics = hir.get_generics(id.owner.def_id).unwrap();
let trait_def_ids: DefIdSet = ast_generics let trait_def_ids: DefIdSet = hir_generics
.bounds_for_param(def_id) .bounds_for_param(def_id)
.flat_map(|bp| bp.bounds.iter()) .flat_map(|bp| bp.bounds.iter())
.filter_map(|bound| bound.trait_ref()?.trait_def_id()) .filter_map(|bound| bound.trait_ref()?.trait_def_id())
@ -3277,7 +3277,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
"restrict type parameter `{}` with", "restrict type parameter `{}` with",
param.name.ident(), param.name.ident(),
)); ));
let bounds_span = ast_generics.bounds_span_for_suggestions(def_id); let bounds_span = hir_generics.bounds_span_for_suggestions(def_id);
if rcvr_ty.is_ref() && param.is_impl_trait() && bounds_span.is_some() { if rcvr_ty.is_ref() && param.is_impl_trait() && bounds_span.is_some() {
err.multipart_suggestions( err.multipart_suggestions(
msg, msg,

View File

@ -1062,7 +1062,7 @@ pub enum ExpnKind {
Macro(MacroKind, Symbol), Macro(MacroKind, Symbol),
/// Transform done by the compiler on the AST. /// Transform done by the compiler on the AST.
AstPass(AstPass), AstPass(AstPass),
/// Desugaring done by the compiler during HIR lowering. /// Desugaring done by the compiler during AST lowering.
Desugaring(DesugaringKind), Desugaring(DesugaringKind),
} }

View File

@ -1,5 +1,5 @@
//! Computes a normalizes-to (projection) goal for inherent associated types, //! 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: //! which impl the IAT is being projected from, we just:
//! 1. instantiate generic parameters, //! 1. instantiate generic parameters,
//! 2. equate the self type, and //! 2. equate the self type, and

View File

@ -46,7 +46,7 @@ pub use self::coherence::{IsFirstInputType, OrphanCheckErr, OverlapResult};
pub use self::engine::{ObligationCtxt, TraitEngineExt}; pub use self::engine::{ObligationCtxt, TraitEngineExt};
pub use self::fulfill::{FulfillmentContext, PendingPredicateObligation}; pub use self::fulfill::{FulfillmentContext, PendingPredicateObligation};
pub use self::normalize::NormalizeExt; pub use self::normalize::NormalizeExt;
pub use self::object_safety::astconv_object_safety_violations; pub use self::object_safety::hir_ty_lowering_object_safety_violations;
pub use self::object_safety::is_vtable_safe_method; pub use self::object_safety::is_vtable_safe_method;
pub use self::object_safety::object_safety_violations_for_assoc_item; pub use self::object_safety::object_safety_violations_for_assoc_item;
pub use self::object_safety::ObjectSafetyViolation; pub use self::object_safety::ObjectSafetyViolation;

View File

@ -32,11 +32,13 @@ use std::ops::ControlFlow;
pub use crate::traits::{MethodViolationCode, ObjectSafetyViolation}; pub use crate::traits::{MethodViolationCode, ObjectSafetyViolation};
/// Returns the object safety violations that affect /// Returns the object safety violations that affect HIR ty lowering.
/// astconv -- currently, `Self` in supertraits. This is needed ///
/// Currently that is `Self` in supertraits. This is needed
/// because `object_safety_violations` can't be used during /// because `object_safety_violations` can't be used during
/// type collection. /// type collection.
pub fn astconv_object_safety_violations( #[instrument(level = "debug", skip(tcx))]
pub fn hir_ty_lowering_object_safety_violations(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
trait_def_id: DefId, trait_def_id: DefId,
) -> Vec<ObjectSafetyViolation> { ) -> Vec<ObjectSafetyViolation> {
@ -46,9 +48,7 @@ pub fn astconv_object_safety_violations(
.filter(|spans| !spans.is_empty()) .filter(|spans| !spans.is_empty())
.map(ObjectSafetyViolation::SupertraitSelf) .map(ObjectSafetyViolation::SupertraitSelf)
.collect(); .collect();
debug!(?violations);
debug!("astconv_object_safety_violations(trait_def_id={:?}) = {:?}", trait_def_id, violations);
violations violations
} }

View File

@ -1264,7 +1264,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`, // Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`,
// normalizing in the process, since `type_of` returns something directly from // 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( let source_tail = normalize_with_depth_to(
self, self,
obligation.param_env, obligation.param_env,

View File

@ -396,7 +396,7 @@ pub(crate) fn assoc_def(
// associated type. Normally this situation // associated type. Normally this situation
// could only arise through a compiler bug -- // could only arise through a compiler bug --
// if the user wrote a bad item name, it // if the user wrote a bad item name, it
// should have failed in astconv. // should have failed during HIR ty lowering.
bug!( bug!(
"No associated type `{}` for {}", "No associated type `{}` for {}",
tcx.item_name(assoc_def_id), tcx.item_name(assoc_def_id),

View File

@ -60,7 +60,7 @@ impl AliasKind {
/// Defines the kinds of types used by the type system. /// Defines the kinds of types used by the type system.
/// ///
/// Types written by the user start out as `hir::TyKind` and get /// 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")] #[cfg_attr(feature = "nightly", rustc_diagnostic_item = "IrTyKind")]
#[derive(derivative::Derivative)] #[derive(derivative::Derivative)]
#[derivative( #[derivative(

View File

@ -20,7 +20,7 @@ use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LocalDefId, LOCAL_CRATE}; use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LocalDefId, LOCAL_CRATE};
use rustc_hir::PredicateOrigin; use rustc_hir::PredicateOrigin;
use rustc_hir_analysis::hir_ty_to_ty; use rustc_hir_analysis::lower_ty;
use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData}; use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData};
use rustc_middle::metadata::Reexport; use rustc_middle::metadata::Reexport;
use rustc_middle::middle::resolve_bound_vars as rbv; use rustc_middle::middle::resolve_bound_vars as rbv;
@ -1260,12 +1260,8 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext
hir::TraitItemKind::Type(bounds, Some(default)) => { hir::TraitItemKind::Type(bounds, Some(default)) => {
let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)); let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx));
let bounds = bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(); let bounds = bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect();
let item_type = clean_middle_ty( let item_type =
ty::Binder::dummy(hir_ty_to_ty(cx.tcx, default)), clean_middle_ty(ty::Binder::dummy(lower_ty(cx.tcx, default)), cx, None, None);
cx,
None,
None,
);
AssocTypeItem( AssocTypeItem(
Box::new(TypeAlias { Box::new(TypeAlias {
type_: clean_ty(default, cx), type_: clean_ty(default, cx),
@ -1306,12 +1302,8 @@ pub(crate) fn clean_impl_item<'tcx>(
hir::ImplItemKind::Type(hir_ty) => { hir::ImplItemKind::Type(hir_ty) => {
let type_ = clean_ty(hir_ty, cx); let type_ = clean_ty(hir_ty, cx);
let generics = clean_generics(impl_.generics, cx); let generics = clean_generics(impl_.generics, cx);
let item_type = clean_middle_ty( let item_type =
ty::Binder::dummy(hir_ty_to_ty(cx.tcx, hir_ty)), clean_middle_ty(ty::Binder::dummy(lower_ty(cx.tcx, hir_ty)), cx, None, None);
cx,
None,
None,
);
AssocTypeItem( AssocTypeItem(
Box::new(TypeAlias { Box::new(TypeAlias {
type_, type_,
@ -1690,7 +1682,7 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type
} }
hir::QPath::Resolved(Some(qself), p) => { hir::QPath::Resolved(Some(qself), p) => {
// Try to normalize `<X as Y>::T` to a type // Try to normalize `<X as Y>::T` to a type
let ty = hir_ty_to_ty(cx.tcx, hir_ty); let ty = lower_ty(cx.tcx, hir_ty);
// `hir_to_ty` can return projection types with escaping vars for GATs, e.g. `<() as Trait>::Gat<'_>` // `hir_to_ty` can return projection types with escaping vars for GATs, e.g. `<() as Trait>::Gat<'_>`
if !ty.has_escaping_bound_vars() if !ty.has_escaping_bound_vars()
&& let Some(normalized_value) = normalize(cx, ty::Binder::dummy(ty)) && let Some(normalized_value) = normalize(cx, ty::Binder::dummy(ty))
@ -1716,7 +1708,7 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type
})) }))
} }
hir::QPath::TypeRelative(qself, segment) => { hir::QPath::TypeRelative(qself, segment) => {
let ty = hir_ty_to_ty(cx.tcx, hir_ty); let ty = lower_ty(cx.tcx, hir_ty);
let self_type = clean_ty(qself, cx); let self_type = clean_ty(qself, cx);
let (trait_, should_show_cast) = match ty.kind() { let (trait_, should_show_cast) = match ty.kind() {
@ -2742,12 +2734,8 @@ fn clean_maybe_renamed_item<'tcx>(
ItemKind::TyAlias(hir_ty, generics) => { ItemKind::TyAlias(hir_ty, generics) => {
*cx.current_type_aliases.entry(def_id).or_insert(0) += 1; *cx.current_type_aliases.entry(def_id).or_insert(0) += 1;
let rustdoc_ty = clean_ty(hir_ty, cx); let rustdoc_ty = clean_ty(hir_ty, cx);
let type_ = clean_middle_ty( let type_ =
ty::Binder::dummy(hir_ty_to_ty(cx.tcx, hir_ty)), clean_middle_ty(ty::Binder::dummy(lower_ty(cx.tcx, hir_ty)), cx, None, None);
cx,
None,
None,
);
let generics = clean_generics(generics, cx); let generics = clean_generics(generics, cx);
if let Some(count) = cx.current_type_aliases.get_mut(&def_id) { if let Some(count) = cx.current_type_aliases.get_mut(&def_id) {
*count -= 1; *count -= 1;

View File

@ -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 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... 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. 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 ## 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 [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 [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 [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 [middle_ty]: https://doc.rust-lang.org/nightly/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]: https://doc.rust-lang.org/nightly/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 [lower_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/fn.lower_ty.html

View File

@ -5,7 +5,7 @@ use rustc_errors::Diag;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::intravisit::{walk_body, walk_expr, walk_inf, walk_ty, Visitor}; use rustc_hir::intravisit::{walk_body, walk_expr, walk_inf, walk_ty, Visitor};
use rustc_hir::{Body, Expr, ExprKind, GenericArg, Item, ItemKind, QPath, TyKind}; use rustc_hir::{Body, Expr, ExprKind, GenericArg, Item, ItemKind, QPath, TyKind};
use rustc_hir_analysis::hir_ty_to_ty; use rustc_hir_analysis::lower_ty;
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::nested_filter; use rustc_middle::hir::nested_filter;
use rustc_middle::ty::{Ty, TypeckResults}; use rustc_middle::ty::{Ty, TypeckResults};
@ -227,7 +227,7 @@ impl<'tcx> ImplicitHasherType<'tcx> {
.collect(); .collect();
let params_len = params.len(); let params_len = params.len();
let ty = hir_ty_to_ty(cx.tcx, hir_ty); let ty = lower_ty(cx.tcx, hir_ty);
if is_type_diagnostic_item(cx, ty, sym::HashMap) && params_len == 2 { if is_type_diagnostic_item(cx, ty, sym::HashMap) && params_len == 2 {
Some(ImplicitHasherType::HashMap( Some(ImplicitHasherType::HashMap(

View File

@ -6,7 +6,7 @@ use rustc_hir::{
GenericArg, GenericBound, GenericBounds, ItemKind, PredicateOrigin, TraitBoundModifier, TyKind, TypeBinding, GenericArg, GenericBound, GenericBounds, ItemKind, PredicateOrigin, TraitBoundModifier, TyKind, TypeBinding,
WherePredicate, WherePredicate,
}; };
use rustc_hir_analysis::hir_ty_to_ty; use rustc_hir_analysis::lower_ty;
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, ClauseKind, Generics, Ty, TyCtxt}; use rustc_middle::ty::{self, ClauseKind, Generics, Ty, TyCtxt};
use rustc_session::declare_lint_pass; use rustc_session::declare_lint_pass;
@ -146,7 +146,7 @@ fn try_resolve_type<'tcx>(
index: usize, index: usize,
) -> Option<Ty<'tcx>> { ) -> Option<Ty<'tcx>> {
match args.get(index - 1) { match args.get(index - 1) {
Some(GenericArg::Type(ty)) => Some(hir_ty_to_ty(tcx, ty)), Some(GenericArg::Type(ty)) => Some(lower_ty(tcx, ty)),
Some(_) => None, Some(_) => None,
None => Some(tcx.type_of(generics.params[index].def_id).skip_binder()), None => Some(tcx.type_of(generics.params[index].def_id).skip_binder()),
} }

View File

@ -4,7 +4,7 @@ use clippy_utils::{path_def_id, qpath_generic_tys};
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir, QPath, TyKind}; use rustc_hir::{self as hir, QPath, TyKind};
use rustc_hir_analysis::hir_ty_to_ty; use rustc_hir_analysis::lower_ty;
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::TypeVisitableExt;
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
@ -56,10 +56,10 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>, qpath:
}; };
let inner_span = match qpath_generic_tys(inner_qpath).next() { let inner_span = match qpath_generic_tys(inner_qpath).next() {
Some(hir_ty) => { 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 // here because `mod.rs` guarantees this lint is only run on types outside of bodies and
// is not run on locals. // is not run on locals.
let ty = hir_ty_to_ty(cx.tcx, hir_ty); let ty = lower_ty(cx.tcx, hir_ty);
if ty.has_escaping_bound_vars() || !ty.is_sized(cx.tcx, cx.param_env) { if ty.has_escaping_bound_vars() || !ty.is_sized(cx.tcx, cx.param_env) {
return false; return false;
} }

View File

@ -4,7 +4,7 @@ use clippy_utils::source::snippet;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir, GenericArg, LangItem, QPath, TyKind}; use rustc_hir::{self as hir, GenericArg, LangItem, QPath, TyKind};
use rustc_hir_analysis::hir_ty_to_ty; use rustc_hir_analysis::lower_ty;
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::TypeVisitableExt;
@ -35,7 +35,7 @@ pub(super) fn check<'tcx>(
&& let Some(GenericArg::Type(boxed_ty)) = last.args.first() && let Some(GenericArg::Type(boxed_ty)) = last.args.first()
// extract allocator from the Box for later // extract allocator from the Box for later
&& let boxed_alloc_ty = last.args.get(1) && let boxed_alloc_ty = last.args.get(1)
&& let ty_ty = hir_ty_to_ty(cx.tcx, boxed_ty) && let ty_ty = lower_ty(cx.tcx, boxed_ty)
&& !ty_ty.has_escaping_bound_vars() && !ty_ty.has_escaping_bound_vars()
&& ty_ty.is_sized(cx.tcx, cx.param_env) && ty_ty.is_sized(cx.tcx, cx.param_env)
&& let Ok(ty_ty_size) = cx.layout_of(ty_ty).map(|l| l.size.bytes()) && let Ok(ty_ty_size) = cx.layout_of(ty_ty).map(|l| l.size.bytes())
@ -55,7 +55,7 @@ pub(super) fn check<'tcx>(
} }
}, },
(Some(GenericArg::Type(l)), Some(GenericArg::Type(r))) => (Some(GenericArg::Type(l)), Some(GenericArg::Type(r))) =>
hir_ty_to_ty(cx.tcx, l) == hir_ty_to_ty(cx.tcx, r), lower_ty(cx.tcx, l) == lower_ty(cx.tcx, r),
_ => false _ => false
} }
{ {

View File

@ -7,7 +7,7 @@ use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::{walk_body, walk_expr, FnKind, Visitor}; use rustc_hir::intravisit::{walk_body, walk_expr, FnKind, Visitor};
use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId, Item, ItemKind, Node, QPath, TyKind}; use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId, Item, ItemKind, Node, QPath, TyKind};
use rustc_hir_analysis::hir_ty_to_ty; use rustc_hir_analysis::lower_ty;
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::map::Map; use rustc_middle::hir::map::Map;
use rustc_middle::hir::nested_filter; use rustc_middle::hir::nested_filter;
@ -74,7 +74,7 @@ fn get_hir_ty_def_id<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: rustc_hir::Ty<'tcx>) -> Op
match qpath { match qpath {
QPath::Resolved(_, path) => path.res.opt_def_id(), QPath::Resolved(_, path) => path.res.opt_def_id(),
QPath::TypeRelative(_, _) => { QPath::TypeRelative(_, _) => {
let ty = hir_ty_to_ty(tcx, &hir_ty); let ty = lower_ty(tcx, &hir_ty);
match ty.kind() { match ty.kind() {
ty::Alias(ty::Projection, proj) => { ty::Alias(ty::Projection, proj) => {

View File

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint; use clippy_utils::diagnostics::span_lint;
use rustc_hir::intravisit::FnKind; use rustc_hir::intravisit::FnKind;
use rustc_hir::{Body, Expr, ExprKind, FnDecl, FnRetTy, TyKind, UnOp}; use rustc_hir::{Body, Expr, ExprKind, FnDecl, FnRetTy, TyKind, UnOp};
use rustc_hir_analysis::hir_ty_to_ty; use rustc_hir_analysis::lower_ty;
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;
use rustc_session::declare_lint_pass; use rustc_session::declare_lint_pass;
@ -71,7 +71,7 @@ impl LateLintPass<'_> for UninhabitedReferences {
} }
if let FnRetTy::Return(hir_ty) = fndecl.output if let FnRetTy::Return(hir_ty) = fndecl.output
&& let TyKind::Ref(_, mut_ty) = hir_ty.kind && let TyKind::Ref(_, mut_ty) = hir_ty.kind
&& hir_ty_to_ty(cx.tcx, mut_ty.ty).is_privately_uninhabited(cx.tcx, cx.param_env) && lower_ty(cx.tcx, mut_ty.ty).is_privately_uninhabited(cx.tcx, cx.param_env)
{ {
span_lint( span_lint(
cx, cx,

View File

@ -11,7 +11,7 @@ use rustc_hir::{
self as hir, Expr, ExprKind, FnRetTy, FnSig, GenericArgsParentheses, GenericParam, GenericParamKind, HirId, Impl, self as hir, Expr, ExprKind, FnRetTy, FnSig, GenericArgsParentheses, GenericParam, GenericParamKind, HirId, Impl,
ImplItemKind, Item, ItemKind, Pat, PatKind, Path, QPath, Ty, TyKind, ImplItemKind, Item, ItemKind, Pat, PatKind, Path, QPath, Ty, TyKind,
}; };
use rustc_hir_analysis::hir_ty_to_ty; use rustc_hir_analysis::lower_ty;
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::Ty as MiddleTy; use rustc_middle::ty::Ty as MiddleTy;
use rustc_session::impl_lint_pass; use rustc_session::impl_lint_pass;
@ -193,7 +193,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
} }
fn check_body(&mut self, _: &LateContext<'_>, _: &hir::Body<'_>) { 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`. // 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. // 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() { if let Some(&mut StackItem::Check { ref mut in_body, .. }) = self.stack.last_mut() {
@ -224,7 +224,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
&& let ty = if in_body > 0 { && let ty = if in_body > 0 {
cx.typeck_results().node_type(hir_ty.hir_id) cx.typeck_results().node_type(hir_ty.hir_id)
} else { } else {
hir_ty_to_ty(cx.tcx, hir_ty) lower_ty(cx.tcx, hir_ty)
} }
&& let impl_ty = cx.tcx.type_of(impl_id).instantiate_identity() && let impl_ty = cx.tcx.type_of(impl_id).instantiate_identity()
&& same_type_and_consts(ty, impl_ty) && same_type_and_consts(ty, impl_ty)

View File

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::ty::{is_normalizable, is_type_diagnostic_item}; use clippy_utils::ty::{is_normalizable, is_type_diagnostic_item};
use rustc_hir::{self as hir, HirId, ItemKind, Node}; use rustc_hir::{self as hir, HirId, ItemKind, Node};
use rustc_hir_analysis::hir_ty_to_ty; use rustc_hir_analysis::lower_ty;
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::layout::LayoutOf as _; use rustc_middle::ty::layout::LayoutOf as _;
use rustc_middle::ty::{Adt, Ty, TypeVisitableExt}; use rustc_middle::ty::{Adt, Ty, TypeVisitableExt};
@ -91,5 +91,5 @@ fn ty_from_hir_ty<'tcx>(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'t
None None
} }
}) })
.unwrap_or_else(|| hir_ty_to_ty(cx.tcx, hir_ty)) .unwrap_or_else(|| lower_ty(cx.tcx, hir_ty))
} }

View File

@ -1,5 +1,5 @@
//! This is a minimal reproducer for the ICE in https://github.com/rust-lang/rust-clippy/pull/6179. //! 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)] #![warn(clippy::use_self)]
#![allow(dead_code, clippy::let_with_type_underscore)] #![allow(dead_code, clippy::let_with_type_underscore)]

View File

@ -1,5 +1,5 @@
//@ run-pass //@ 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 //@ pretty-expanded FIXME #23616

View File

@ -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. // This `FreshTy(0)` can leak into substs, causing ICEs in several places.
#![feature(trait_alias)] #![feature(trait_alias)]

View File

@ -499,6 +499,10 @@ of `ObligationCtxt`.
""" """
cc = ["@lcnr", "@compiler-errors"] cc = ["@lcnr", "@compiler-errors"]
[mentions."compiler/rustc_hir_analysis/src/hir_ty_lowering"]
message = "HIR ty lowering was modified"
cc = ["@fmease"]
[mentions."compiler/rustc_error_codes/src/lib.rs"] [mentions."compiler/rustc_error_codes/src/lib.rs"]
message = "Some changes occurred in diagnostic error codes" message = "Some changes occurred in diagnostic error codes"
cc = ["@GuillaumeGomez"] cc = ["@GuillaumeGomez"]