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)]
pub enum GenericBound {
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));
match use_tree.kind {
UseTreeKind::Simple(rename) => {
// The extra IDs are handled during HIR lowering.
// The extra IDs are handled during AST lowering.
visit_opt!(visitor, visit_ident, rename);
}
UseTreeKind::Glob => {}

View File

@ -29,11 +29,12 @@
//! item id (`item_id`) in case of impl trait or path resolution id (`path_id`) otherwise.
//!
//! Since we do not have a proper way to obtain function type information by path resolution
//! in AST, we mark each function parameter type as `InferDelegation` and inherit it in `AstConv`.
//! in AST, we mark each function parameter type as `InferDelegation` and inherit it during
//! HIR ty lowering.
//!
//! Similarly generics, predicates and header are set to the "default" values.
//! In case of discrepancy with callee function the `NotSupportedDelegation` error will
//! also be emitted in `AstConv`.
//! also be emitted during HIR ty lowering.
use crate::{ImplTraitPosition, ResolverAstLoweringExt};
@ -129,7 +130,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
) -> &'hir hir::FnDecl<'hir> {
let args_count = if let Some(local_sig_id) = sig_id.as_local() {
// Map may be filled incorrectly due to recursive delegation.
// Error will be emmited later in astconv.
// Error will be emitted later during HIR ty lowering.
self.resolver.fn_parameter_counts.get(&local_sig_id).cloned().unwrap_or_default()
} else {
self.tcx.fn_arg_names(sig_id).len()

View File

@ -1427,8 +1427,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
// Error if `?Trait` bounds in where clauses don't refer directly to type parameters.
// Note: we used to clone these bounds directly onto the type parameter (and avoid lowering
// these into hir when we lower thee where clauses), but this makes it quite difficult to
// keep track of the Span info. Now, `add_implicitly_sized` in `AstConv` checks both param bounds and
// where clauses for `?Sized`.
// keep track of the Span info. Now, `<dyn HirTyLowerer>::add_implicit_sized_bound`
// checks both param bounds and where clauses for `?Sized`.
for pred in &generics.where_clause.predicates {
let WherePredicate::BoundPredicate(bound_pred) = pred else {
continue;

View File

@ -428,10 +428,6 @@ pub enum TraitBoundModifier {
MaybeConst,
}
/// The AST represents all type param bounds as types.
/// `typeck::collect::compute_bounds` matches these against
/// the "special" built-in traits (see `middle::lang_items`) and
/// detects `Copy`, `Send` and `Sync`.
#[derive(Clone, Copy, Debug, HashStable_Generic)]
pub enum GenericBound<'hir> {
Trait(PolyTraitRef<'hir>, TraitBoundModifier),
@ -1860,7 +1856,7 @@ pub enum ExprKind<'hir> {
/// Wraps the expression in a terminating scope.
/// This makes it semantically equivalent to `{ let _t = expr; _t }`.
///
/// This construct only exists to tweak the drop order in HIR lowering.
/// This construct only exists to tweak the drop order in AST lowering.
/// An example of that is the desugaring of `for` loops.
DropTemps(&'hir Expr<'hir>),
/// A `let $pat = $expr` expression.
@ -2293,7 +2289,7 @@ pub enum ImplItemKind<'hir> {
/// Bind a type to an associated type (i.e., `A = Foo`).
///
/// Bindings like `A: Debug` are represented as a special type `A =
/// $::Debug` that is understood by the astconv code.
/// $::Debug` that is understood by the HIR ty lowering code.
///
/// FIXME(alexreg): why have a separate type for the binding case,
/// wouldn't it be better to make the `ty` field an enum like the

View File

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

View File

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

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
// because an RPITIT was located within a missing item. Like if we have a sig
// returning `-> Missing<impl Sized>`, that gets converted to `-> [type error]`,
// returning `-> Missing<impl Sized>`, that gets converted to `-> {type error}`,
// and when walking through the signature we end up never collecting the def id
// of the `impl Sized`. Insert that here, so we don't ICE later.
for assoc_item in tcx.associated_types_for_impl_traits_in_associated_fn(trait_m.def_id) {

View File

@ -760,7 +760,7 @@ impl<'tcx> RegionResolutionVisitor<'tcx> {
fn enter_node_scope_with_dtor(&mut self, id: hir::ItemLocalId) {
// If node was previously marked as a terminating scope during the
// recursive visit of its parent node in the AST, then we need to
// recursive visit of its parent node in the HIR, then we need to
// account for the destruction scope representing the scope of
// the destructors that run immediately after it completes.
if self.terminating_scopes.contains(&id) {

View File

@ -272,7 +272,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
}
Some(ty::ImplPolarity::Negative) => {
let ast::ImplPolarity::Negative(span) = impl_.polarity else {
bug!("impl_polarity query disagrees with impl's polarity in AST");
bug!("impl_polarity query disagrees with impl's polarity in HIR");
};
// FIXME(#27579): what amount of WF checking do we need for neg impls?
if let hir::Defaultness::Default { .. } = impl_.defaultness {
@ -1866,7 +1866,7 @@ fn check_variances_for_type_defn<'tcx>(
.iter()
.filter_map(|predicate| match 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)),
_ => None,
}

View File

@ -40,9 +40,9 @@ use std::cell::Cell;
use std::iter;
use std::ops::Bound;
use crate::astconv::AstConv;
use crate::check::intrinsic::intrinsic_operation_unsafety;
use crate::errors;
use crate::hir_ty_lowering::HirTyLowerer;
pub use type_of::test_opaque_hidden_types;
mod generics_of;
@ -88,13 +88,12 @@ pub fn provide(providers: &mut Providers) {
///////////////////////////////////////////////////////////////////////////
/// Context specific to some particular item. This is what implements
/// [`AstConv`].
/// Context specific to some particular item. This is what implements [`HirTyLowerer`].
///
/// # `ItemCtxt` vs `FnCtxt`
///
/// `ItemCtxt` is primarily used to type-check item signatures and lower them
/// from HIR to their [`ty::Ty`] representation, which is exposed using [`AstConv`].
/// from HIR to their [`ty::Ty`] representation, which is exposed using [`HirTyLowerer`].
/// It's also used for the bodies of items like structs where the body (the fields)
/// are just signatures.
///
@ -111,11 +110,11 @@ pub fn provide(providers: &mut Providers) {
/// `ItemCtxt` has information about the predicates that are defined
/// on the trait. Unfortunately, this predicate information is
/// available in various different forms at various points in the
/// process. So we can't just store a pointer to e.g., the AST or the
/// process. So we can't just store a pointer to e.g., the HIR or the
/// parsed ty form, we have to be more flexible. To this end, the
/// `ItemCtxt` is parameterized by a `DefId` that it uses to satisfy
/// `get_type_parameter_bounds` requests, drawing the information from
/// the AST (`hir::Generics`), recursively.
/// `probe_ty_param_bounds` requests, drawing the information from
/// the HIR (`hir::Generics`), recursively.
pub struct ItemCtxt<'tcx> {
tcx: TyCtxt<'tcx>,
item_def_id: LocalDefId,
@ -277,7 +276,7 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'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);
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>) {
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);
}
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);
}
}
@ -344,8 +343,8 @@ impl<'tcx> ItemCtxt<'tcx> {
ItemCtxt { tcx, item_def_id, tainted_by_errors: Cell::new(None) }
}
pub fn to_ty(&self, ast_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
self.astconv().ast_ty_to_ty(ast_ty)
pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
self.lowerer().lower_ty(hir_ty)
}
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> {
self.tcx
}
@ -373,23 +372,14 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
self.item_def_id.to_def_id()
}
fn get_type_parameter_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 allow_infer(&self) -> bool {
false
}
fn re_infer(&self, _: Option<&ty::GenericParamDef>, _: Span) -> Option<ty::Region<'tcx>> {
None
}
fn allow_ty_infer(&self) -> bool {
false
}
fn ty_infer(&self, _: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
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")
}
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,
span: Span,
item_def_id: DefId,
@ -412,7 +411,7 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
poly_trait_ref: ty::PolyTraitRef<'tcx>,
) -> Ty<'tcx> {
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,
item_def_id,
item_segment,
@ -497,10 +496,6 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
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) {
// 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>> {
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.
@ -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()
}
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);
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;
match &it.kind {
@ -591,7 +591,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
tcx.ensure().generics_of(def_id);
tcx.ensure().type_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 { .. } => {
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() {
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 def_id = trait_item_id.owner_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);
}
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;
tcx.ensure().generics_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().type_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 repr_type = def.repr().discr_type();
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);
}
// Convert the ctor, if any. This also registers the variant as
// an item.
// Lower the ctor, if any. This also registers the variant as an item.
if let Some(ctor_def_id) = variant.ctor_def_id() {
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<'_>,
variant_did: Option<LocalDefId>,
ident: Ident,
@ -1060,7 +1059,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
};
distance_from_explicit += 1;
convert_variant(
lower_variant(
tcx,
Some(v.def_id),
v.ident,
@ -1080,7 +1079,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
ItemKind::Struct(..) => AdtKind::Struct,
_ => AdtKind::Union,
};
let variants = std::iter::once(convert_variant(
let variants = std::iter::once(lower_variant(
tcx,
None,
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)
&& i.of_trait.is_some()
{
icx.astconv().ty_of_fn(
icx.lowerer().lower_fn_ty(
hir_id,
sig.header.unsafety,
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: _ }, _),
generics,
..
}) => {
icx.astconv().ty_of_fn(hir_id, header.unsafety, header.abi, decl, Some(generics), None)
}
}) => icx.lowerer().lower_fn_ty(
hir_id,
header.unsafety,
header.abi,
decl,
Some(generics),
None,
),
ForeignItem(&hir::ForeignItem { kind: ForeignItemKind::Fn(fn_decl, _, _), .. }) => {
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,
sig.header.unsafety,
sig.header.abi,
@ -1529,19 +1533,19 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::ImplTrai
impl_
.of_trait
.as_ref()
.map(|ast_trait_ref| {
let selfty = tcx.type_of(def_id).instantiate_identity();
.map(|hir_trait_ref| {
let self_ty = tcx.type_of(def_id).instantiate_identity();
let trait_ref = if let Some(ErrorGuaranteed { .. }) = check_impl_constness(
tcx,
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
// without the host param. If we continue with the HIR trait ref, we get
// ICEs for generic arg count mismatch. We do a little HIR editing to
// make astconv happy.
let mut path_segments = ast_trait_ref.path.segments.to_vec();
// make HIR ty lowering happy.
let mut path_segments = hir_trait_ref.path.segments.to_vec();
let last_segment = path_segments.len() - 1;
let mut args = *path_segments[last_segment].args();
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];
path_segments[last_segment].args = Some(tcx.hir_arena.alloc(args));
let path = hir::Path {
span: ast_trait_ref.path.span,
res: ast_trait_ref.path.res,
span: hir_trait_ref.path.span,
res: hir_trait_ref.path.res,
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 });
icx.astconv().instantiate_mono_trait_ref(trait_ref, selfty)
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.lowerer().lower_impl_trait_ref(trait_ref, self_ty)
} else {
icx.astconv().instantiate_mono_trait_ref(ast_trait_ref, selfty)
icx.lowerer().lower_impl_trait_ref(hir_trait_ref, self_ty)
};
ty::ImplTraitHeader {
trait_ref: ty::EarlyBinder::bind(trait_ref),
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(
tcx: TyCtxt<'_>,
is_const: bool,
ast_trait_ref: &hir::TraitRef<'_>,
hir_trait_ref: &hir::TraitRef<'_>,
) -> Option<ErrorGuaranteed> {
if !is_const {
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) {
return None;
}
let trait_name = tcx.item_name(trait_def_id).to_string();
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,
local_trait_span:
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 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
// ABIs are handled at all correctly. -huonw
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() {
let snip = tcx
.sess
.source_map()
.span_to_snippet(ast_ty.span)
.span_to_snippet(hir_ty.span)
.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()) {

View File

@ -218,8 +218,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
Deny,
}
let no_generics = hir::Generics::empty();
let ast_generics = node.generics().unwrap_or(no_generics);
let hir_generics = node.generics().unwrap_or(hir::Generics::empty());
let (opt_self, allow_defaults) = match node {
Node::Item(item) => {
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()
});
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 {
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 {
name: param.name.ident().name,
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 \
`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::Type { default, synthetic, .. } => {
if default.is_some() {

View File

@ -1,5 +1,5 @@
use super::ItemCtxt;
use crate::astconv::{AstConv, PredicateFilter};
use crate::hir_ty_lowering::{HirTyLowerer, PredicateFilter};
use rustc_data_structures::fx::FxIndexSet;
use rustc_hir as hir;
use rustc_infer::traits::util;
@ -18,7 +18,7 @@ use rustc_span::Span;
fn associated_type_bounds<'tcx>(
tcx: TyCtxt<'tcx>,
assoc_item_def_id: LocalDefId,
ast_bounds: &'tcx [hir::GenericBound<'tcx>],
hir_bounds: &'tcx [hir::GenericBound<'tcx>],
span: Span,
filter: PredicateFilter,
) -> &'tcx [(ty::Clause<'tcx>, Span)] {
@ -29,9 +29,9 @@ fn associated_type_bounds<'tcx>(
);
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
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_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id);
@ -62,16 +62,16 @@ fn associated_type_bounds<'tcx>(
fn opaque_type_bounds<'tcx>(
tcx: TyCtxt<'tcx>,
opaque_def_id: LocalDefId,
ast_bounds: &'tcx [hir::GenericBound<'tcx>],
hir_bounds: &'tcx [hir::GenericBound<'tcx>],
item_ty: Ty<'tcx>,
span: Span,
filter: PredicateFilter,
) -> &'tcx [(ty::Clause<'tcx>, Span)] {
ty::print::with_reduced_queries!({
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
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);
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);
opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter)
}
// Since RPITITs are astconv'd as projections in `ast_ty_to_ty`, when we're asking
// for the item bounds of the *opaques* in a trait's default method signature, we
// Since RPITITs are lowered as projections in `<dyn HirTyLowerer>::lower_ty`, when we're
// asking for the item bounds of the *opaques* in a trait's default method signature, we
// need to map these projections back to opaques.
hir::Node::Item(hir::Item {
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait: true, origin, .. }),

View File

@ -1,7 +1,7 @@
use crate::astconv::{AstConv, OnlySelfBounds, PredicateFilter};
use crate::bounds::Bounds;
use crate::collect::ItemCtxt;
use crate::constrained_generic_params as cgp;
use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter};
use hir::{HirId, Node};
use rustc_data_structures::fx::FxIndexSet;
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.
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 {
match item.kind {
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`.
if let Some(self_bounds) = is_trait {
predicates.extend(
icx.astconv()
.compute_bounds(tcx.types.self_param, self_bounds, PredicateFilter::All)
icx.lowerer()
.lower_mono_bounds(tcx.types.self_param, self_bounds, PredicateFilter::All)
.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
// type parameter (e.g., `<T: Foo>`). Also add `ConstArgHasType` predicates
// for each const parameter.
for param in ast_generics.params {
for param in hir_generics.params {
match param.kind {
// We already dealt with early bound lifetimes above.
GenericParamKind::Lifetime { .. } => (),
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();
// Params are implicitly sized unless a `?Sized` bound is found
icx.astconv().add_implicitly_sized(
icx.lowerer().add_sized_bound(
&mut bounds,
param_ty,
&[],
Some((param.def_id, ast_generics.predicates)),
Some((param.def_id, hir_generics.predicates)),
param.span,
);
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())
.no_bound_vars()
.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((
ty::ClauseKind::ConstArgHasType(ct, ct_ty).to_predicate(tcx),
param.span,
@ -205,10 +205,10 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
trace!(?predicates);
// Add in the bounds that appear in the where-clause.
for predicate in ast_generics.predicates {
for predicate in hir_generics.predicates {
match predicate {
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);
// 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`
@ -232,7 +232,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
}
let mut bounds = Bounds::default();
icx.astconv().add_bounds(
icx.lowerer().lower_poly_bounds(
ty,
bound_pred.bounds.iter(),
&mut bounds,
@ -243,11 +243,11 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
}
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| {
let (r2, span) = match bound {
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 => {
span_bug!(
@ -542,8 +542,8 @@ pub(super) fn explicit_predicates_of<'tcx>(
}
/// Ensures that the super-predicates of the trait with a `DefId`
/// of `trait_def_id` are converted and stored. This also ensures that
/// the transitive super-predicates are converted.
/// of `trait_def_id` are lowered and stored. This also ensures that
/// the transitive super-predicates are lowered.
pub(super) fn super_predicates_of(
tcx: TyCtxt<'_>,
trait_def_id: LocalDefId,
@ -574,8 +574,8 @@ pub(super) fn implied_predicates_of(
}
/// Ensures that the super-predicates of the trait with a `DefId`
/// of `trait_def_id` are converted and stored. This also ensures that
/// the transitive super-predicates are converted.
/// of `trait_def_id` are lowered and stored. This also ensures that
/// the transitive super-predicates are lowered.
pub(super) fn implied_predicates_with_filter(
tcx: TyCtxt<'_>,
trait_def_id: DefId,
@ -601,9 +601,9 @@ pub(super) fn implied_predicates_with_filter(
let icx = ItemCtxt::new(tcx, trait_def_id);
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,
item.owner_id.def_id,
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));
debug!(?implied_bounds);
// Now require that immediate supertraits are converted, which will, in
// Now require that immediate supertraits are lowered, which will, in
// turn, reach indirect supertraits, so we detect cycles now instead of
// overflowing during elaboration. Same for implied predicates, which
// make sure we walk into associated type bounds.
@ -656,7 +656,7 @@ pub(super) fn type_param_predicates(
use rustc_hir::*;
use rustc_middle::ty::Ty;
// In the AST, bounds can derive from two places. Either
// In the HIR, bounds can derive from two places. Either
// written inline like `<T: Foo>` or in a where-clause like
// `where T: Foo`.
@ -676,7 +676,7 @@ pub(super) fn type_param_predicates(
let mut result = parent
.map(|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();
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 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
&& let ItemKind::Trait(..) = item.kind
// 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 extra_predicates = extend.into_iter().chain(
icx.type_parameter_bounds_in_generics(
ast_generics,
icx.probe_ty_param_bounds_in_generics(
hir_generics,
def_id,
ty,
PredicateFilter::SelfThatDefines(assoc_name),
@ -714,21 +714,22 @@ pub(super) fn type_param_predicates(
}
impl<'tcx> ItemCtxt<'tcx> {
/// Finds bounds from `hir::Generics`. This requires scanning through the
/// AST. We do this to avoid having to convert *all* the bounds, which
/// would create artificial cycles. Instead, we can only convert the
/// bounds for a type parameter `X` if `X::Foo` is used.
#[instrument(level = "trace", skip(self, ast_generics))]
fn type_parameter_bounds_in_generics(
/// Finds bounds from `hir::Generics`.
///
/// This requires scanning through the HIR.
/// We do this to avoid having to lower *all* the bounds, which would create artificial cycles.
/// Instead, we can only lower the bounds for a type parameter `X` if `X::Foo` is used.
#[instrument(level = "trace", skip(self, hir_generics))]
fn probe_ty_param_bounds_in_generics(
&self,
ast_generics: &'tcx hir::Generics<'tcx>,
hir_generics: &'tcx hir::Generics<'tcx>,
param_def_id: LocalDefId,
ty: Ty<'tcx>,
filter: PredicateFilter,
) -> Vec<(ty::Clause<'tcx>, Span)> {
let mut bounds = Bounds::default();
for predicate in ast_generics.predicates {
for predicate in hir_generics.predicates {
let hir::WherePredicate::BoundPredicate(predicate) = predicate else {
continue;
};
@ -750,13 +751,13 @@ impl<'tcx> ItemCtxt<'tcx> {
let bound_ty = if predicate.is_param_bound(param_def_id.to_def_id()) {
ty
} else if matches!(filter, PredicateFilter::All) {
self.to_ty(predicate.bounded_ty)
self.lower_ty(predicate.bounded_ty)
} else {
continue;
};
let bound_vars = self.tcx.late_bound_vars(predicate.hir_id);
self.astconv().add_bounds(
self.lowerer().lower_poly_bounds(
bound_ty,
predicate.bounds.iter().filter(|bound| {
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
/// we started correctly handling aliases. If we considered `'a` constrained then it would become late bound
/// causing an error during astconv as the `'a` is not constrained by the input type `<() as Trait<'a>>::Assoc`
/// causing an error during HIR ty lowering as the `'a` is not constrained by the input type `<() as Trait<'a>>::Assoc`
/// but appears in the output type `<() as Trait<'a>>::Assoc`.
///
/// We must therefore "look into" the `Alias` to see whether we should consider `'a` constrained or not.
///
/// See #100508 #85533 #47511 for additional context
struct ConstrainedCollectorPostAstConv {
struct ConstrainedCollectorPostHirTyLowering {
arg_is_constrained: Box<[bool]>,
}
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>) {
match t.kind() {
ty::Param(param_ty) => {
@ -1970,10 +1970,10 @@ fn is_late_bound_map(
None,
hir::Path { res: Res::Def(DefKind::TyAlias, alias_def), segments, span },
)) => {
// See comments on `ConstrainedCollectorPostAstConv` for why this arm does not just consider
// args to be unconstrained.
// See comments on `ConstrainedCollectorPostHirTyLowering` for why this arm does not
// just consider args to be unconstrained.
let generics = self.tcx.generics_of(alias_def);
let mut walker = ConstrainedCollectorPostAstConv {
let mut walker = ConstrainedCollectorPostHirTyLowering {
arg_is_constrained: vec![false; generics.params.len()].into_boxed_slice(),
};
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
Node::Ty(hir_ty @ hir::Ty { kind: TyKind::Path(QPath::TypeRelative(_, segment)), .. }) => {
// Find the Item containing the associated type so we can create an ItemCtxt.
// Using the ItemCtxt convert the HIR for the unresolved assoc type into a
// Using the ItemCtxt lower the HIR for the unresolved assoc type into a
// ty which is a fully resolved projection.
// For the code example above, this would mean converting Self::Assoc<3>
// into a ty::Alias(ty::Projection, <Self as Foo>::Assoc<3>)
// For the code example above, this would mean lowering `Self::Assoc<3>`
// to a ty::Alias(ty::Projection, `<Self as Foo>::Assoc<3>`).
let item_def_id = tcx
.hir()
.parent_owner_iter(hir_id)
@ -108,7 +108,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
.unwrap()
.0
.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
// 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)),
TraitItemKind::Type(_, Some(ty)) => icx.to_ty(ty),
.unwrap_or_else(|| icx.lower_ty(ty)),
TraitItemKind::Type(_, Some(ty)) => icx.lower_ty(ty),
TraitItemKind::Type(_, None) => {
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",
)
} else {
icx.to_ty(ty)
icx.lower_ty(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);
}
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",
)
} else {
icx.to_ty(ty)
icx.lower_ty(ty)
}
}
ItemKind::Const(ty, _, body_id) => {
if ty.is_suggestable_infer_ty() {
infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident, "constant")
} 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() {
spans if spans.len() > 0 => {
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: () });
Ty::new_error(tcx, guar)
}
_ => icx.to_ty(*self_ty),
_ => icx.lower_ty(*self_ty),
},
ItemKind::Fn(..) => {
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);
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()),
},
@ -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 { .. }, .. }) => {
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 {
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),
},

View File

@ -12,17 +12,19 @@ use rustc_trait_selection::traits;
use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
use smallvec::SmallVec;
use crate::astconv::{AstConv, OnlySelfBounds, PredicateFilter};
use crate::bounds::Bounds;
use crate::errors;
use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter};
impl<'tcx> dyn AstConv<'tcx> + '_ {
/// Sets `implicitly_sized` to true on `Bounds` if necessary
pub(crate) fn add_implicitly_sized(
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
/// Add a `Sized` bound to the `bounds` if appropriate.
///
/// Doesn't add the bound if the HIR bounds contain any of `Sized`, `?Sized` or `!Sized`.
pub(crate) fn add_sized_bound(
&self,
bounds: &mut Bounds<'tcx>,
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>])>,
span: Span,
) {
@ -33,9 +35,9 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
// Try to find an unbound in bounds.
let mut unbounds: SmallVec<[_; 1]> = SmallVec::new();
let mut search_bounds = |ast_bounds: &'tcx [hir::GenericBound<'tcx>]| {
for ab in ast_bounds {
let hir::GenericBound::Trait(ptr, modifier) = ab else {
let mut search_bounds = |hir_bounds: &'tcx [hir::GenericBound<'tcx>]| {
for hir_bound in hir_bounds {
let hir::GenericBound::Trait(ptr, modifier) = hir_bound else {
continue;
};
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 {
for clause in where_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`)
/// and an *unconverted* list of bounds:
/// Lower HIR bounds into `bounds` given the self type `param_ty` and the overarching late-bound vars if any.
///
/// ```text
/// fn foo<T: Debug>
/// ^ ^^^^^ `ast_bounds` parameter, in HIR form
/// |
/// `param_ty`, in ty form
/// ### Examples
///
/// ```ignore (illustrative)
/// fn foo<T>() where for<'a> T: Trait<'a> + Copy {}
/// // ^^^^^^^ ^ ^^^^^^^^^^^^^^^^ `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
/// `param_ty` and `ast_bounds`. See `instantiate_poly_trait_ref`
/// for more details.
#[instrument(level = "debug", skip(self, ast_bounds, bounds))]
pub(crate) fn add_bounds<'hir, I: Iterator<Item = &'hir hir::GenericBound<'tcx>>>(
/// There is an implied binder around `param_ty` and `hir_bounds`.
/// See `lower_poly_trait_ref` for more details.
#[instrument(level = "debug", skip(self, hir_bounds, bounds))]
pub(crate) fn lower_poly_bounds<'hir, I: Iterator<Item = &'hir hir::GenericBound<'tcx>>>(
&self,
param_ty: Ty<'tcx>,
ast_bounds: I,
hir_bounds: I,
bounds: &mut Bounds<'tcx>,
bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
only_self_bounds: OnlySelfBounds,
) where
'tcx: 'hir,
{
for ast_bound in ast_bounds {
match ast_bound {
for hir_bound in hir_bounds {
match hir_bound {
hir::GenericBound::Trait(poly_trait_ref, modifier) => {
let (constness, polarity) = match modifier {
hir::TraitBoundModifier::Const => {
@ -145,7 +153,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
}
hir::TraitBoundModifier::Maybe => continue,
};
let _ = self.instantiate_poly_trait_ref(
let _ = self.lower_poly_trait_ref(
&poly_trait_ref.trait_ref,
poly_trait_ref.span,
constness,
@ -156,7 +164,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
);
}
hir::GenericBound::Outlives(lifetime) => {
let region = self.ast_region_to_region(lifetime, None);
let region = self.lower_lifetime(lifetime, None);
bounds.push_region_bound(
self.tcx(),
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.
/// The self-type for the bounds is given by `param_ty`.
/// Lower HIR bounds into `bounds` given the self type `param_ty` and *no* overarching late-bound vars.
///
/// Example:
/// ### Example
///
/// ```ignore (illustrative)
/// fn foo<T: Bar + Baz>() { }
/// // ^ ^^^^^^^^^ ast_bounds
/// // ^ ^^^^^^^^^ hir_bounds
/// // param_ty
/// ```
///
/// The `sized_by_default` parameter indicates if, in this context, the `param_ty` should be
/// considered `Sized` unless there is an explicit `?Sized` bound. This would be true in the
/// example above, but is not true in supertrait listings like `trait Foo: Bar + Baz`.
///
/// `span` should be the declaration size of the parameter.
pub(crate) fn compute_bounds(
pub(crate) fn lower_mono_bounds(
&self,
param_ty: Ty<'tcx>,
ast_bounds: &[hir::GenericBound<'tcx>],
hir_bounds: &[hir::GenericBound<'tcx>],
filter: PredicateFilter,
) -> Bounds<'tcx> {
let mut bounds = Bounds::default();
@ -201,9 +202,9 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => OnlySelfBounds(true),
};
self.add_bounds(
self.lower_poly_bounds(
param_ty,
ast_bounds.iter().filter(|bound| match filter {
hir_bounds.iter().filter(|bound| match filter {
PredicateFilter::All
| PredicateFilter::SelfOnly
| PredicateFilter::SelfAndAssociatedTypeBounds => true,
@ -227,14 +228,16 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
bounds
}
/// Given an HIR binding like `Item = Foo` or `Item: Foo`, pushes the corresponding predicates
/// onto `bounds`.
/// Lower an associated item binding from HIR into `bounds`.
///
/// **A note on binders:** given something like `T: for<'a> Iterator<Item = &'a u32>`, the
/// `trait_ref` here will be `for<'a> T: Iterator`. The `binding` data however is from *inside*
/// the binder (e.g., `&'a u32`) and hence may reference bound regions.
/// ### A Note on Binders
///
/// Given something like `T: for<'a> Iterator<Item = &'a u32>`,
/// the `trait_ref` here will be `for<'a> T: Iterator`.
/// The `binding` data however is from *inside* the binder
/// (e.g., `&'a u32`) and hence may reference bound regions.
#[instrument(level = "debug", skip(self, bounds, dup_bindings, path_span))]
pub(super) fn add_predicates_for_ast_type_binding(
pub(super) fn lower_assoc_item_binding(
&self,
hir_ref_id: hir::HirId,
trait_ref: ty::PolyTraitRef<'tcx>,
@ -244,22 +247,6 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
path_span: Span,
only_self_bounds: OnlySelfBounds,
) -> Result<(), ErrorGuaranteed> {
// Given something like `U: SomeTrait<T = X>`, we want to produce a
// predicate like `<U as SomeTrait>::T = X`. This is somewhat
// subtle in the event that `T` is defined in a supertrait of
// `SomeTrait`, because in that case we need to upcast.
//
// That is, consider this case:
//
// ```
// trait SubTrait: SuperTrait<i32> { }
// trait SuperTrait<A> { type T; }
//
// ... B: SubTrait<T = foo> ...
// ```
//
// We want to produce `<B as SuperTrait<i32>>::T == foo`.
let tcx = self.tcx();
let assoc_kind = if binding.gen_args.parenthesized
@ -272,7 +259,15 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
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(),
assoc_kind,
binding.ident,
@ -282,7 +277,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
} else {
// Otherwise, we have to walk through the supertraits to find
// one that does define it.
self.one_bound_for_assoc_item(
self.probe_single_bound_for_assoc_item(
|| traits::supertraits(tcx, trait_ref),
trait_ref.skip_binder().print_only_trait_name(),
None,
@ -417,7 +412,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
infer_args: false,
};
let alias_args = self.create_args_for_associated_item(
let alias_args = self.lower_generic_args_of_assoc_item(
path_span,
assoc_item.def_id,
&item_segment,
@ -449,9 +444,11 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
span: binding.span,
}));
}
// Lower an equality constraint like `Item = u32` as found in HIR bound `T: Iterator<Item = u32>`
// to a projection predicate: `<T as Iterator>::Item = u32`.
hir::TypeBindingKind::Equality { term } => {
let term = match term {
hir::Term::Ty(ty) => self.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(),
};
@ -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(
tcx,
projection_ty
@ -501,22 +494,18 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
binding.span,
);
}
hir::TypeBindingKind::Constraint { bounds: ast_bounds } => {
// "Desugar" a constraint like `T: Iterator<Item: Debug>` to
//
// `<T as Iterator>::Item: Debug`
//
// Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty`
// parameter to have a skipped binder.
//
// NOTE: If `only_self_bounds` is true, do NOT expand this associated
// type bound into a trait predicate, since we only want to add predicates
// for the `Self` type.
// Lower a constraint like `Item: Debug` as found in HIR bound `T: Iterator<Item: Debug>`
// to a bound involving a projection: `<T as Iterator>::Item: Debug`.
hir::TypeBindingKind::Constraint { bounds: hir_bounds } => {
// NOTE: If `only_self_bounds` is true, do NOT expand this associated type bound into
// a trait predicate, since we only want to add predicates for the `Self` type.
if !only_self_bounds.0 {
// Calling `skip_binder` is okay, because `lower_bounds` expects the `param_ty`
// parameter to have a skipped binder.
let param_ty = Ty::new_alias(tcx, ty::Projection, projection_ty.skip_binder());
self.add_bounds(
self.lower_poly_bounds(
param_ty,
ast_bounds.iter(),
hir_bounds.iter(),
bounds,
projection_ty.bound_vars(),
only_self_bounds,

View File

@ -1,9 +1,9 @@
use crate::astconv::AstConv;
use crate::errors::{
self, AssocTypeBindingNotAllowed, ManualImplementation, MissingTypeParams,
ParenthesizedFnTraitExpansion,
};
use crate::fluent_generated as fluent;
use crate::hir_ty_lowering::HirTyLowerer;
use crate::traits::error_reporting::report_object_safety_error;
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
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_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
/// the type parameter's name as a placeholder.
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.
let wrap_in_braces_sugg = if let Some(binding) = binding
&& 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())
&& 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,
span: Span,
types: &[String],
@ -458,7 +458,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
reported
}
pub(crate) fn complain_about_ambiguous_inherent_assoc_type(
pub(crate) fn complain_about_ambiguous_inherent_assoc_ty(
&self,
name: Ident,
candidates: Vec<DefId>,
@ -471,14 +471,14 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
"multiple applicable items in scope"
);
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();
self.set_tainted_by_errors(reported);
reported
}
// FIXME(fmease): Heavily adapted from `rustc_hir_typeck::method::suggest`. Deduplicate.
fn note_ambiguous_inherent_assoc_type(
fn note_ambiguous_inherent_assoc_ty(
&self,
err: &mut Diag<'_>,
candidates: Vec<DefId>,
@ -521,7 +521,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
}
// 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,
name: Ident,
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
/// 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.
pub(crate) fn complain_about_missing_associated_types(
pub(crate) fn complain_about_missing_assoc_tys(
&self,
associated_types: FxIndexMap<Span, FxIndexSet<DefId>>,
potential_assoc_types: Vec<Span>,
@ -1027,7 +1027,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
}
/// Emits an error regarding forbidden type binding associations
pub fn prohibit_assoc_ty_binding(
pub fn prohibit_assoc_item_binding(
tcx: TyCtxt<'_>,
span: Span,
segment: Option<(&hir::PathSegment<'_>, Span)>,

View File

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

View File

@ -6,9 +6,9 @@ use rustc_lint_defs::{builtin::BARE_TRAIT_OBJECTS, Applicability};
use rustc_span::Span;
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.
pub(super) fn maybe_lint_blanket_trait_impl<G: EmissionGuarantee>(
&self,

View File

@ -1,6 +1,6 @@
use crate::astconv::{GenericArgCountMismatch, GenericArgCountResult, OnlySelfBounds};
use crate::bounds::Bounds;
use crate::errors::TraitObjectDeclaredWithNoTraits;
use crate::hir_ty_lowering::{GenericArgCountMismatch, GenericArgCountResult, OnlySelfBounds};
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_errors::{codes::*, struct_span_code_err};
use rustc_hir as hir;
@ -11,14 +11,16 @@ use rustc_middle::ty::{self, Ty};
use rustc_middle::ty::{DynKind, ToPredicate};
use rustc_span::Span;
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 super::AstConv;
use super::HirTyLowerer;
impl<'tcx> dyn AstConv<'tcx> + '_ {
pub(super) fn conv_object_ty_poly_trait_ref(
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
/// 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,
span: Span,
hir_id: hir::HirId,
@ -37,7 +39,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
correct:
Err(GenericArgCountMismatch { invalid_args: cur_potential_assoc_types, .. }),
..
} = self.instantiate_poly_trait_ref(
} = self.lower_poly_trait_ref(
&trait_bound.trait_ref,
trait_bound.span,
ty::BoundConstness::NotConst,
@ -133,7 +135,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
// to avoid ICEs.
for item in &regular_traits {
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() {
let reported = report_object_safety_error(
tcx,
@ -156,7 +158,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
for (base_trait_ref, span) in regular_traits_refs_spans {
let base_pred: ty::Predicate<'tcx> = base_trait_ref.to_predicate(tcx);
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();
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));
}
self.complain_about_missing_associated_types(
self.complain_about_missing_assoc_tys(
associated_types,
potential_assoc_types,
hir_trait_bounds,
@ -243,8 +245,8 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
// the bounds
let mut duplicates = FxHashSet::default();
auto_traits.retain(|i| duplicates.insert(i.trait_ref().def_id()));
debug!("regular_traits: {:?}", regular_traits);
debug!("auto_traits: {:?}", auto_traits);
debug!(?regular_traits);
debug!(?auto_traits);
// Erase the `dummy_self` (`trait_object_dummy_self`) used above.
let existential_trait_refs = regular_traits.iter().map(|i| {
@ -362,11 +364,11 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
// Use explicitly-specified region bound.
let region_bound = if !lifetime.is_elided() {
self.ast_region_to_region(lifetime, None)
self.lower_lifetime(lifetime, None)
} else {
self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| {
if tcx.named_bound_var(lifetime.hir_id).is_some() {
self.ast_region_to_region(lifetime, None)
self.lower_lifetime(lifetime, None)
} else {
self.re_infer(None, span).unwrap_or_else(|| {
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);
debug!("trait_object_type: {:?}", ty);
ty
Ty::new_dynamic(tcx, existential_predicates, region_bound, representation)
}
}

View File

@ -68,7 +68,7 @@ fn diagnostic_hir_wf_check<'tcx>(
let infcx = self.tcx.infer_ctxt().build();
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
// potentially reference escaping bound variables. We simply erase
// those here.

View File

@ -30,8 +30,8 @@ several major phases:
The type checker is defined into various submodules which are documented
independently:
- astconv: converts the AST representation of types
into the `ty` representation.
- hir_ty_lowering: lowers type-system entities from the [HIR][hir] to the
[`rustc_middle::ty`] representation.
- collect: computes the types of each top-level item and enters them into
the `tcx.types` table for later use.
@ -82,11 +82,11 @@ extern crate rustc_middle;
// These are used by Clippy.
pub mod check;
pub mod astconv;
pub mod autoderef;
mod bounds;
mod check_unused;
mod coherence;
pub mod hir_ty_lowering;
// FIXME: This module shouldn't be public.
pub mod collect;
mod constrained_generic_params;
@ -211,12 +211,20 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
Ok(())
}
/// A quasi-deprecated helper used in rustdoc and clippy to get
/// the type from a HIR node.
pub fn hir_ty_to_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
/// Lower a [`hir::Ty`] to a [`Ty`].
///
/// <div class="warning">
///
/// This function is **quasi-deprecated**. It can cause ICEs if called inside of a body
/// (of a function or constant) and especially if it contains inferred types (`_`).
///
/// It's used in rustdoc and Clippy.
///
/// </div>
pub fn lower_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
// In case there are any projections, etc., find the "environment"
// def-ID that will be used to determine the traits/predicates in
// scope. This is derived from the enclosing item-like thing.
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
//!
//! The second pass over the AST determines the set of constraints.
//! The second pass over the HIR determines the set of constraints.
//! We walk the set of items and, for each member, generate new constraints.
use hir::def_id::{DefId, LocalDefId};

View File

@ -5,7 +5,7 @@ use super::{check_fn, CoroutineTypes, Expectation, FnCtxt};
use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
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::{BoundRegionConversionTime, DefineOpaqueTypes};
use rustc_infer::infer::{InferOk, InferResult};
@ -784,7 +784,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
decl: &hir::FnDecl<'tcx>,
closure_kind: hir::ClosureKind,
) -> ty::PolyFnSig<'tcx> {
let astconv = self.astconv();
let lowerer = self.lowerer();
trace!("decl = {:#?}", decl);
debug!(?closure_kind);
@ -793,9 +793,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let bound_vars = self.tcx.late_bound_vars(hir_id);
// 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 {
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 {
// 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
@ -813,7 +813,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// easily (and locally) prove that we
// *have* reported an
// error. --nikomatsakis
astconv.ty_infer(None, decl.output.span())
lowerer.ty_infer(None, decl.output.span())
})
}
// 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::Closure
| 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>,
guar: ErrorGuaranteed,
) -> ty::PolyFnSig<'tcx> {
let astconv = self.astconv();
let lowerer = self.lowerer();
let err_ty = Ty::new_error(self.tcx, guar);
let supplied_arguments = decl.inputs.iter().map(|a| {
// Convert the types that the user supplied (if any), but ignore them.
astconv.ast_ty_to_ty(a);
lowerer.lower_ty(a);
err_ty
});
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(

View File

@ -41,7 +41,7 @@ use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::{self, Visitor};
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::{Coercion, DefineOpaqueTypes, InferOk, InferResult};
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::lang_items::LangItem;
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::hir_ty_lowering::HirTyLowerer as _;
use rustc_infer::infer;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
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::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);
self.demand_eqtype(e.span, ascribed_ty, ty);
ascribed_ty
@ -1375,7 +1375,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> Ty<'tcx> {
// Find the type of `e`. Supply hints based on the type we are casting to,
// 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_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
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>,
) -> Ty<'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) {
self.suggest_array_len(expr, count);
}
@ -1679,7 +1679,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expr: &hir::Expr<'_>,
span: Span,
variant: &'tcx ty::VariantDef,
ast_fields: &'tcx [hir::ExprField<'tcx>],
hir_fields: &'tcx [hir::ExprField<'tcx>],
base_expr: &'tcx Option<&'tcx hir::Expr<'tcx>>,
) {
let tcx = self.tcx;
@ -1710,7 +1710,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut error_happened = false;
// 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 field_type = if let Some((i, v_field)) = remaining_fields.remove(&ident) {
seen_fields.insert(ident, field.span);
@ -1739,7 +1739,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
variant,
expr,
field,
ast_fields,
hir_fields,
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);
if let Some(diag) = diag {
if idx == ast_fields.len() - 1 {
if idx == hir_fields.len() - 1 {
if remaining_fields.is_empty() {
self.suggest_fru_from_range_and_emit(field, variant, args, diag);
} else {
@ -1768,7 +1768,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Make sure the programmer specified correct number of fields.
if adt_kind == AdtKind::Union {
if ast_fields.len() != 1 {
if hir_fields.len() != 1 {
struct_span_code_err!(
tcx.dcx(),
span,
@ -1905,14 +1905,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.collect();
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 {
self.report_missing_fields(
adt_ty,
span,
remaining_fields,
variant,
ast_fields,
hir_fields,
args,
);
}
@ -1949,7 +1949,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span: Span,
remaining_fields: UnordMap<Ident, (FieldIdx, &ty::FieldDef)>,
variant: &'tcx ty::VariantDef,
ast_fields: &'tcx [hir::ExprField<'tcx>],
hir_fields: &'tcx [hir::ExprField<'tcx>],
args: GenericArgsRef<'tcx>,
) {
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}"));
if let Some(last) = ast_fields.last() {
self.suggest_fru_from_range_and_emit(last, variant, args, err);
if let Some(hir_field) = hir_fields.last() {
self.suggest_fru_from_range_and_emit(hir_field, variant, args, err);
} else {
err.emit();
}
@ -3283,7 +3283,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fields: &[Ident],
expr: &'tcx hir::Expr<'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)
&& !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::lang_items::LangItem;
use rustc_hir::{ExprKind, GenericArg, Node, QPath};
use rustc_hir_analysis::astconv::generics::{
check_generic_arg_count_for_call, create_args_for_parent_generic_args,
use rustc_hir_analysis::hir_ty_lowering::generics::{
check_generic_arg_count_for_call, lower_generic_args,
};
use rustc_hir_analysis::astconv::{
AstConv, CreateInstantiationsForGenericArgsCtxt, ExplicitLateBound, GenericArgCountMismatch,
GenericArgCountResult, IsMethodCall, PathSeg,
use rustc_hir_analysis::hir_ty_lowering::{
ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, GenericArgsLowerer,
GenericPathSegment, HirTyLowerer, IsMethodCall,
};
use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
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> {
let t = self.astconv().ast_ty_to_ty(ast_t);
self.register_wf_obligation(t.into(), ast_t.span, traits::WellFormed(None));
LoweredTy::from_raw(self, ast_t.span, t)
pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> LoweredTy<'tcx> {
let ty = self.lowerer().lower_ty(hir_ty);
self.register_wf_obligation(ty.into(), hir_ty.span, traits::WellFormed(None));
LoweredTy::from_raw(self, hir_ty.span, ty)
}
pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
let ty = self.to_ty(ast_ty);
debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
#[instrument(level = "debug", skip_all)]
pub fn lower_ty_saving_user_provided_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
let ty = self.lower_ty(hir_ty);
debug!(?ty);
if Self::can_contain_user_lifetime_bounds(ty.raw) {
let c_ty = self.canonicalize_response(UserType::Ty(ty.raw));
debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
self.typeck_results.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
debug!(?c_ty);
self.typeck_results.borrow_mut().user_provided_types_mut().insert(hir_ty.hir_id, c_ty);
}
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 {
hir::ArrayLen::Infer(inf) => self.ct_infer(self.tcx.types.usize, None, inf.span),
hir::ArrayLen::Body(anon_const) => {
@ -436,20 +437,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
pub fn const_arg_to_const(
&self,
ast_c: &hir::AnonConst,
param_def_id: DefId,
) -> ty::Const<'tcx> {
let did = ast_c.def_id;
pub fn lower_const_arg(&self, hir_ct: &hir::AnonConst, param_def_id: DefId) -> ty::Const<'tcx> {
let did = hir_ct.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(
c.into(),
self.tcx.hir().span(ast_c.hir_id),
ct.into(),
self.tcx.hir().span(hir_ct.hir_id),
ObligationCauseCode::WellFormed(None),
);
c
ct
}
// 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) => {
return (
path.res,
opt_qself.as_ref().map(|qself| self.to_ty(qself)),
opt_qself.as_ref().map(|qself| self.lower_ty(qself)),
path.segments,
);
}
QPath::TypeRelative(ref qself, ref segment) => {
// Don't use `self.to_ty`, since this will register a WF obligation.
// Don't use `self.lower_ty`, since this will register a WF obligation.
// If we're trying to call a nonexistent method on a trait
// (e.g. `MyTrait::missing_method`), then resolution will
// give us a `QPath::TypeRelative` with a trait object as
@ -841,7 +838,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// to be object-safe.
// We manually call `register_wf_obligation` in the success path
// 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)
}
QPath::LangItem(..) => {
@ -1119,9 +1116,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> (Ty<'tcx>, Res) {
let tcx = self.tcx;
let path_segs = match res {
let generic_segments = match res {
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,
self_ty.map(|ty| ty.raw),
kind,
@ -1178,14 +1175,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// provided (if any) into their appropriate spaces. We'll also report
// errors if type parameters are provided in an inappropriate place.
let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
let generics_has_err = self.astconv().prohibit_generics(
let indices: FxHashSet<_> =
generic_segments.iter().map(|GenericPathSegment(_, index)| index).collect();
let generics_has_err = self.lowerer().prohibit_generic_args(
segments.iter().enumerate().filter_map(|(index, seg)| {
if !generic_segs.contains(&index) || is_alias_variant_ctor {
Some(seg)
} else {
None
}
if !indices.contains(&index) || is_alias_variant_ctor { Some(seg) } else { None }
}),
|_| {},
);
@ -1212,7 +1206,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut infer_args_for_err = FxHashSet::default();
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 generics = tcx.generics_of(def_id);
@ -1233,8 +1227,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
let has_self =
path_segs.last().is_some_and(|PathSeg(def_id, _)| tcx.generics_of(*def_id).has_self);
let has_self = generic_segments
.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 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>,
span: Span,
path_segs: &'a [PathSeg],
generic_segments: &'a [GenericPathSegment],
infer_args_for_err: &'a FxHashSet<usize>,
segments: &'tcx [hir::PathSegment<'tcx>],
}
impl<'tcx, 'a> CreateInstantiationsForGenericArgsCtxt<'a, 'tcx>
for CreateCtorInstantiationsContext<'a, 'tcx>
{
impl<'tcx, 'a> GenericArgsLowerer<'a, 'tcx> for CtorGenericArgsCtxt<'a, 'tcx> {
fn args_for_def_id(
&mut self,
def_id: DefId,
) -> (Option<&'a hir::GenericArgs<'tcx>>, bool) {
if let Some(&PathSeg(_, index)) =
self.path_segs.iter().find(|&PathSeg(did, _)| *did == def_id)
if let Some(&GenericPathSegment(_, index)) =
self.generic_segments.iter().find(|&GenericPathSegment(did, _)| *did == def_id)
{
// If we've encountered an `impl Trait`-related error, we're just
// going to infer the arguments for better error messages.
@ -1332,13 +1325,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> ty::GenericArg<'tcx> {
match (&param.kind, arg) {
(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)) => {
self.fcx.to_ty(ty).raw.into()
self.fcx.lower_ty(ty).raw.into()
}
(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)) => {
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(|| {
create_args_for_parent_generic_args(
lower_generic_args(
tcx,
def_id,
&[],
has_self,
self_ty.map(|s| s.raw),
&arg_count,
&mut CreateCtorInstantiationsContext {
&mut CtorGenericArgsCtxt {
fcx: self,
span,
path_segs: &path_segs,
generic_segments: &generic_segments,
infer_args_for_err: &infer_args_for_err,
segments,
},

View File

@ -24,9 +24,9 @@ use rustc_hir::def::{CtorOf, DefKind, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor;
use rustc_hir::{ExprKind, Node, QPath};
use rustc_hir_analysis::astconv::AstConv;
use rustc_hir_analysis::check::intrinsicck::InlineAsmCtxt;
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_index::IndexVec;
use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt};
@ -1961,16 +1961,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> (Res, LoweredTy<'tcx>) {
match *qpath {
QPath::Resolved(ref maybe_qself, path) => {
let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself).raw);
let ty = self.astconv().res_to_ty(self_ty, path, hir_id, true);
let self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself).raw);
let ty = self.lowerer().lower_path(self_ty, path, hir_id, true);
(path.res, LoweredTy::from_raw(self, path_span, ty))
}
QPath::TypeRelative(qself, segment) => {
let ty = self.to_ty(qself);
let ty = self.lower_ty(qself);
let result = self
.astconv()
.associated_path_to_ty(hir_id, path_span, ty.raw, qself, segment, true);
.lowerer()
.lower_assoc_path(hir_id, path_span, ty.raw, qself, segment, true);
let ty = result
.map(|(ty, _, _)| ty)
.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_hir as hir;
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::error_reporting::sub_relations::SubRelations;
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> {
self.tcx
}
@ -221,31 +221,8 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
self.body_id.to_def_id()
}
fn get_type_parameter_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 allow_infer(&self) -> bool {
true
}
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))
}
fn allow_ty_infer(&self) -> bool {
true
}
fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
match param {
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,
span: Span,
item_def_id: DefId,
@ -305,7 +305,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
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,
item_def_id,
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) {
// FIXME: normalization and escaping regions
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>> {
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
/// we want to either use the unnormalized or the normalized form of this type.
///
/// This is a bridge between the interface of `AstConv`, which outputs a raw `Ty`,
/// and the API in this module, which expect `Ty` to be fully normalized.
/// This is a bridge between the interface of HIR ty lowering, which outputs a raw
/// `Ty`, and the API in this module, which expect `Ty` to be fully normalized.
#[derive(Clone, Copy, Debug)]
pub struct LoweredTy<'tcx> {
/// The unnormalized type provided by the user.

View File

@ -21,7 +21,7 @@ use rustc_hir::{
CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, GenericBound, HirId, Node,
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_middle::lint::in_external_macro;
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
// are not, the expectation must have been caused by something else.
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!("expected type {:?}", expected);
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,
..
}) => {
// FIXME: Maybe these calls to `ast_ty_to_ty` can be removed (and the ones below)
let ty = self.astconv().ast_ty_to_ty(bounded_ty);
// FIXME: Maybe these calls to `lower_ty` can be removed (and the ones below)
let ty = self.lowerer().lower_ty(bounded_ty);
Some((ty, bounds))
}
_ => None,
@ -996,7 +996,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let all_bounds_str = all_matching_bounds_strs.join(" + ");
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)
});
@ -1071,7 +1071,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let can_return = match fn_decl.output {
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 ty = self
.tcx

View File

@ -93,7 +93,7 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
fn declare(&mut self, decl: Declaration<'tcx>) {
let local_ty = match decl.ty {
Some(ref ty) => {
let o_ty = self.fcx.to_ty(ty);
let o_ty = self.fcx.lower_ty(ty);
let c_ty =
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::intravisit::Visitor;
use rustc_hir::{HirIdMap, Node};
use rustc_hir_analysis::astconv::AstConv;
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::traits::{ObligationCauseCode, ObligationInspector, WellFormedLoc};
use rustc_middle::query::Providers;
@ -178,7 +178,7 @@ fn typeck_with_fallback<'tcx>(
if let Some(hir::FnSig { header, decl, .. }) = fn_sig {
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 {
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::def_id::DefId;
use rustc_hir::GenericArg;
use rustc_hir_analysis::astconv::generics::{
check_generic_arg_count_for_call, create_args_for_parent_generic_args,
use rustc_hir_analysis::hir_ty_lowering::generics::{
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_middle::traits::{ObligationCauseCode, UnifyReceiverContext};
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.
assert_eq!(generics.parent_count, parent_args.len());
struct MethodInstantiationsCtxt<'a, 'tcx> {
struct GenericArgsCtxt<'a, 'tcx> {
cfcx: &'a ConfirmContext<'a, 'tcx>,
pick: &'a probe::Pick<'tcx>,
seg: &'a hir::PathSegment<'tcx>,
}
impl<'a, 'tcx> CreateInstantiationsForGenericArgsCtxt<'a, 'tcx>
for MethodInstantiationsCtxt<'a, 'tcx>
{
impl<'a, 'tcx> GenericArgsLowerer<'a, 'tcx> for GenericArgsCtxt<'a, 'tcx> {
fn args_for_def_id(
&mut self,
def_id: DefId,
@ -393,13 +391,13 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
) -> ty::GenericArg<'tcx> {
match (&param.kind, arg) {
(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)) => {
self.cfcx.to_ty(ty).raw.into()
self.cfcx.lower_ty(ty).raw.into()
}
(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)) => {
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,
pick.item.def_id,
parent_args,
false,
None,
&arg_count_correct,
&mut MethodInstantiationsCtxt { cfcx: self, pick, seg },
&mut GenericArgsCtxt { cfcx: self, pick, seg },
);
// When the method is confirmed, the `args` includes

View File

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

View File

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

View File

@ -1,5 +1,5 @@
//! Computes a normalizes-to (projection) goal for inherent associated types,
//! `#![feature(inherent_associated_type)]`. Since astconv already determines
//! `#![feature(inherent_associated_type)]`. Since HIR ty lowering already determines
//! which impl the IAT is being projected from, we just:
//! 1. instantiate generic parameters,
//! 2. equate the self type, and

View File

@ -46,7 +46,7 @@ pub use self::coherence::{IsFirstInputType, OrphanCheckErr, OverlapResult};
pub use self::engine::{ObligationCtxt, TraitEngineExt};
pub use self::fulfill::{FulfillmentContext, PendingPredicateObligation};
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::object_safety_violations_for_assoc_item;
pub use self::object_safety::ObjectSafetyViolation;

View File

@ -32,11 +32,13 @@ use std::ops::ControlFlow;
pub use crate::traits::{MethodViolationCode, ObjectSafetyViolation};
/// Returns the object safety violations that affect
/// astconv -- currently, `Self` in supertraits. This is needed
/// Returns the object safety violations that affect HIR ty lowering.
///
/// Currently that is `Self` in supertraits. This is needed
/// because `object_safety_violations` can't be used during
/// type collection.
pub fn astconv_object_safety_violations(
#[instrument(level = "debug", skip(tcx))]
pub fn hir_ty_lowering_object_safety_violations(
tcx: TyCtxt<'_>,
trait_def_id: DefId,
) -> Vec<ObjectSafetyViolation> {
@ -46,9 +48,7 @@ pub fn astconv_object_safety_violations(
.filter(|spans| !spans.is_empty())
.map(ObjectSafetyViolation::SupertraitSelf)
.collect();
debug!("astconv_object_safety_violations(trait_def_id={:?}) = {:?}", trait_def_id, violations);
debug!(?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>`,
// normalizing in the process, since `type_of` returns something directly from
// astconv (which means it's un-normalized).
// HIR ty lowering (which means it's un-normalized).
let source_tail = normalize_with_depth_to(
self,
obligation.param_env,

View File

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

View File

@ -60,7 +60,7 @@ impl AliasKind {
/// Defines the kinds of types used by the type system.
///
/// Types written by the user start out as `hir::TyKind` and get
/// converted to this representation using `AstConv::ast_ty_to_ty`.
/// converted to this representation using `<dyn HirTyLowerer>::lower_ty`.
#[cfg_attr(feature = "nightly", rustc_diagnostic_item = "IrTyKind")]
#[derive(derivative::Derivative)]
#[derivative(

View File

@ -20,7 +20,7 @@ use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LocalDefId, LOCAL_CRATE};
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_middle::metadata::Reexport;
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)) => {
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 item_type = clean_middle_ty(
ty::Binder::dummy(hir_ty_to_ty(cx.tcx, default)),
cx,
None,
None,
);
let item_type =
clean_middle_ty(ty::Binder::dummy(lower_ty(cx.tcx, default)), cx, None, None);
AssocTypeItem(
Box::new(TypeAlias {
type_: clean_ty(default, cx),
@ -1306,12 +1302,8 @@ pub(crate) fn clean_impl_item<'tcx>(
hir::ImplItemKind::Type(hir_ty) => {
let type_ = clean_ty(hir_ty, cx);
let generics = clean_generics(impl_.generics, cx);
let item_type = clean_middle_ty(
ty::Binder::dummy(hir_ty_to_ty(cx.tcx, hir_ty)),
cx,
None,
None,
);
let item_type =
clean_middle_ty(ty::Binder::dummy(lower_ty(cx.tcx, hir_ty)), cx, None, None);
AssocTypeItem(
Box::new(TypeAlias {
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) => {
// 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<'_>`
if !ty.has_escaping_bound_vars()
&& 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) => {
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 (trait_, should_show_cast) = match ty.kind() {
@ -2742,12 +2734,8 @@ fn clean_maybe_renamed_item<'tcx>(
ItemKind::TyAlias(hir_ty, generics) => {
*cx.current_type_aliases.entry(def_id).or_insert(0) += 1;
let rustdoc_ty = clean_ty(hir_ty, cx);
let type_ = clean_middle_ty(
ty::Binder::dummy(hir_ty_to_ty(cx.tcx, hir_ty)),
cx,
None,
None,
);
let type_ =
clean_middle_ty(ty::Binder::dummy(lower_ty(cx.tcx, hir_ty)), cx, None, None);
let generics = clean_generics(generics, cx);
if let Some(count) = cx.current_type_aliases.get_mut(&def_id) {
*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
understands that they're the same type, in-depth lifetimes, etc...
To get from a `hir::Ty` to a `ty::Ty`, you can use the [`hir_ty_to_ty`][hir_ty_to_ty] function outside of bodies or
To get from a `hir::Ty` to a `ty::Ty`, you can use the [`lower_ty`][lower_ty] function outside of bodies or
the [`TypeckResults::node_type()`][node_type] method inside of bodies.
> **Warning**: Don't use `hir_ty_to_ty` inside of bodies, because this can cause ICEs.
> **Warning**: Don't use `lower_ty` inside of bodies, because this can cause ICEs.
## Creating Types programmatically
@ -162,6 +162,6 @@ in this chapter:
[Ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html
[TyKind]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/ty_kind/enum.TyKind.html
[TypeckResults]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html
[middle_ty]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_middle/ty/struct.Ty.html
[hir_ty]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_hir/struct.Ty.html
[hir_ty_to_ty]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_hir_analysis/fn.hir_ty_to_ty.html
[middle_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html
[hir_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/struct.Ty.html
[lower_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/fn.lower_ty.html

View File

@ -5,7 +5,7 @@ use rustc_errors::Diag;
use rustc_hir as hir;
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_analysis::hir_ty_to_ty;
use rustc_hir_analysis::lower_ty;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::nested_filter;
use rustc_middle::ty::{Ty, TypeckResults};
@ -227,7 +227,7 @@ impl<'tcx> ImplicitHasherType<'tcx> {
.collect();
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 {
Some(ImplicitHasherType::HashMap(

View File

@ -6,7 +6,7 @@ use rustc_hir::{
GenericArg, GenericBound, GenericBounds, ItemKind, PredicateOrigin, TraitBoundModifier, TyKind, TypeBinding,
WherePredicate,
};
use rustc_hir_analysis::hir_ty_to_ty;
use rustc_hir_analysis::lower_ty;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, ClauseKind, Generics, Ty, TyCtxt};
use rustc_session::declare_lint_pass;
@ -146,7 +146,7 @@ fn try_resolve_type<'tcx>(
index: usize,
) -> Option<Ty<'tcx>> {
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,
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_hir::def_id::DefId;
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_middle::ty::TypeVisitableExt;
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() {
Some(hir_ty) => {
// Reallocation of a fat pointer causes it to become thin. `hir_ty_to_ty` is safe to use
// Reallocation of a fat pointer causes it to become thin. `lower_ty` is safe to use
// here because `mod.rs` guarantees this lint is only run on types outside of bodies and
// is not run on locals.
let ty = 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) {
return false;
}

View File

@ -4,7 +4,7 @@ use clippy_utils::source::snippet;
use rustc_errors::Applicability;
use rustc_hir::def_id::DefId;
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_middle::ty::layout::LayoutOf;
use rustc_middle::ty::TypeVisitableExt;
@ -35,7 +35,7 @@ pub(super) fn check<'tcx>(
&& let Some(GenericArg::Type(boxed_ty)) = last.args.first()
// extract allocator from the Box for later
&& 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.is_sized(cx.tcx, cx.param_env)
&& 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))) =>
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
}
{

View File

@ -7,7 +7,7 @@ use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefId, LocalDefId};
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_analysis::hir_ty_to_ty;
use rustc_hir_analysis::lower_ty;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::map::Map;
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 {
QPath::Resolved(_, path) => path.res.opt_def_id(),
QPath::TypeRelative(_, _) => {
let ty = hir_ty_to_ty(tcx, &hir_ty);
let ty = lower_ty(tcx, &hir_ty);
match ty.kind() {
ty::Alias(ty::Projection, proj) => {

View File

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint;
use rustc_hir::intravisit::FnKind;
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_middle::lint::in_external_macro;
use rustc_session::declare_lint_pass;
@ -71,7 +71,7 @@ impl LateLintPass<'_> for UninhabitedReferences {
}
if let FnRetTy::Return(hir_ty) = fndecl.output
&& 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(
cx,

View File

@ -11,7 +11,7 @@ use rustc_hir::{
self as hir, Expr, ExprKind, FnRetTy, FnSig, GenericArgsParentheses, GenericParam, GenericParamKind, HirId, Impl,
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_middle::ty::Ty as MiddleTy;
use rustc_session::impl_lint_pass;
@ -193,7 +193,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
}
fn check_body(&mut self, _: &LateContext<'_>, _: &hir::Body<'_>) {
// `hir_ty_to_ty` cannot be called in `Body`s or it will panic (sometimes). But in bodies
// `lower_ty` cannot be called in `Body`s or it will panic (sometimes). But in bodies
// we can use `cx.typeck_results.node_type(..)` to get the `ty::Ty` from a `hir::Ty`.
// However the `node_type()` method can *only* be called in bodies.
if let Some(&mut StackItem::Check { ref mut in_body, .. }) = self.stack.last_mut() {
@ -224,7 +224,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
&& let ty = if in_body > 0 {
cx.typeck_results().node_type(hir_ty.hir_id)
} 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()
&& same_type_and_consts(ty, impl_ty)

View File

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::ty::{is_normalizable, is_type_diagnostic_item};
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_middle::ty::layout::LayoutOf as _;
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
}
})
.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.
//! The ICE is mainly caused by using `hir_ty_to_ty`. See the discussion in the PR for details.
//! The ICE is mainly caused by using `lower_ty`. See the discussion in the PR for details.
#![warn(clippy::use_self)]
#![allow(dead_code, clippy::let_with_type_underscore)]

View File

@ -1,5 +1,5 @@
//@ run-pass
// Test that astconv doesn't forget about mutability of &mut str
// Test that HIR ty lowering doesn't forget about mutability of `&mut str`.
//@ pretty-expanded FIXME #23616

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.
#![feature(trait_alias)]

View File

@ -499,6 +499,10 @@ of `ObligationCtxt`.
"""
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"]
message = "Some changes occurred in diagnostic error codes"
cc = ["@GuillaumeGomez"]