mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 08:44:35 +00:00
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:
commit
eff958c59e
@ -303,10 +303,6 @@ impl TraitBoundModifiers {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The AST represents all type param bounds as types.
|
|
||||||
/// `typeck::collect::compute_bounds` matches these against
|
|
||||||
/// the "special" built-in traits (see `middle::lang_items`) and
|
|
||||||
/// detects `Copy`, `Send` and `Sync`.
|
|
||||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
pub enum GenericBound {
|
pub enum GenericBound {
|
||||||
Trait(PolyTraitRef, TraitBoundModifiers),
|
Trait(PolyTraitRef, TraitBoundModifiers),
|
||||||
|
@ -480,7 +480,7 @@ pub fn walk_use_tree<'a, V: Visitor<'a>>(
|
|||||||
try_visit!(visitor.visit_path(&use_tree.prefix, id));
|
try_visit!(visitor.visit_path(&use_tree.prefix, id));
|
||||||
match use_tree.kind {
|
match use_tree.kind {
|
||||||
UseTreeKind::Simple(rename) => {
|
UseTreeKind::Simple(rename) => {
|
||||||
// The extra IDs are handled during HIR lowering.
|
// The extra IDs are handled during AST lowering.
|
||||||
visit_opt!(visitor, visit_ident, rename);
|
visit_opt!(visitor, visit_ident, rename);
|
||||||
}
|
}
|
||||||
UseTreeKind::Glob => {}
|
UseTreeKind::Glob => {}
|
||||||
|
@ -29,11 +29,12 @@
|
|||||||
//! item id (`item_id`) in case of impl trait or path resolution id (`path_id`) otherwise.
|
//! item id (`item_id`) in case of impl trait or path resolution id (`path_id`) otherwise.
|
||||||
//!
|
//!
|
||||||
//! Since we do not have a proper way to obtain function type information by path resolution
|
//! Since we do not have a proper way to obtain function type information by path resolution
|
||||||
//! in AST, we mark each function parameter type as `InferDelegation` and inherit it in `AstConv`.
|
//! in AST, we mark each function parameter type as `InferDelegation` and inherit it during
|
||||||
|
//! HIR ty lowering.
|
||||||
//!
|
//!
|
||||||
//! Similarly generics, predicates and header are set to the "default" values.
|
//! Similarly generics, predicates and header are set to the "default" values.
|
||||||
//! In case of discrepancy with callee function the `NotSupportedDelegation` error will
|
//! In case of discrepancy with callee function the `NotSupportedDelegation` error will
|
||||||
//! also be emitted in `AstConv`.
|
//! also be emitted during HIR ty lowering.
|
||||||
|
|
||||||
use crate::{ImplTraitPosition, ResolverAstLoweringExt};
|
use crate::{ImplTraitPosition, ResolverAstLoweringExt};
|
||||||
|
|
||||||
@ -129,7 +130,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
) -> &'hir hir::FnDecl<'hir> {
|
) -> &'hir hir::FnDecl<'hir> {
|
||||||
let args_count = if let Some(local_sig_id) = sig_id.as_local() {
|
let args_count = if let Some(local_sig_id) = sig_id.as_local() {
|
||||||
// Map may be filled incorrectly due to recursive delegation.
|
// Map may be filled incorrectly due to recursive delegation.
|
||||||
// Error will be emmited later in astconv.
|
// Error will be emitted later during HIR ty lowering.
|
||||||
self.resolver.fn_parameter_counts.get(&local_sig_id).cloned().unwrap_or_default()
|
self.resolver.fn_parameter_counts.get(&local_sig_id).cloned().unwrap_or_default()
|
||||||
} else {
|
} else {
|
||||||
self.tcx.fn_arg_names(sig_id).len()
|
self.tcx.fn_arg_names(sig_id).len()
|
||||||
|
@ -1427,8 +1427,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
// Error if `?Trait` bounds in where clauses don't refer directly to type parameters.
|
// Error if `?Trait` bounds in where clauses don't refer directly to type parameters.
|
||||||
// Note: we used to clone these bounds directly onto the type parameter (and avoid lowering
|
// Note: we used to clone these bounds directly onto the type parameter (and avoid lowering
|
||||||
// these into hir when we lower thee where clauses), but this makes it quite difficult to
|
// these into hir when we lower thee where clauses), but this makes it quite difficult to
|
||||||
// keep track of the Span info. Now, `add_implicitly_sized` in `AstConv` checks both param bounds and
|
// keep track of the Span info. Now, `<dyn HirTyLowerer>::add_implicit_sized_bound`
|
||||||
// where clauses for `?Sized`.
|
// checks both param bounds and where clauses for `?Sized`.
|
||||||
for pred in &generics.where_clause.predicates {
|
for pred in &generics.where_clause.predicates {
|
||||||
let WherePredicate::BoundPredicate(bound_pred) = pred else {
|
let WherePredicate::BoundPredicate(bound_pred) = pred else {
|
||||||
continue;
|
continue;
|
||||||
|
@ -428,10 +428,6 @@ pub enum TraitBoundModifier {
|
|||||||
MaybeConst,
|
MaybeConst,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The AST represents all type param bounds as types.
|
|
||||||
/// `typeck::collect::compute_bounds` matches these against
|
|
||||||
/// the "special" built-in traits (see `middle::lang_items`) and
|
|
||||||
/// detects `Copy`, `Send` and `Sync`.
|
|
||||||
#[derive(Clone, Copy, Debug, HashStable_Generic)]
|
#[derive(Clone, Copy, Debug, HashStable_Generic)]
|
||||||
pub enum GenericBound<'hir> {
|
pub enum GenericBound<'hir> {
|
||||||
Trait(PolyTraitRef<'hir>, TraitBoundModifier),
|
Trait(PolyTraitRef<'hir>, TraitBoundModifier),
|
||||||
@ -1860,7 +1856,7 @@ pub enum ExprKind<'hir> {
|
|||||||
/// Wraps the expression in a terminating scope.
|
/// Wraps the expression in a terminating scope.
|
||||||
/// This makes it semantically equivalent to `{ let _t = expr; _t }`.
|
/// This makes it semantically equivalent to `{ let _t = expr; _t }`.
|
||||||
///
|
///
|
||||||
/// This construct only exists to tweak the drop order in HIR lowering.
|
/// This construct only exists to tweak the drop order in AST lowering.
|
||||||
/// An example of that is the desugaring of `for` loops.
|
/// An example of that is the desugaring of `for` loops.
|
||||||
DropTemps(&'hir Expr<'hir>),
|
DropTemps(&'hir Expr<'hir>),
|
||||||
/// A `let $pat = $expr` expression.
|
/// A `let $pat = $expr` expression.
|
||||||
@ -2293,7 +2289,7 @@ pub enum ImplItemKind<'hir> {
|
|||||||
/// Bind a type to an associated type (i.e., `A = Foo`).
|
/// Bind a type to an associated type (i.e., `A = Foo`).
|
||||||
///
|
///
|
||||||
/// Bindings like `A: Debug` are represented as a special type `A =
|
/// Bindings like `A: Debug` are represented as a special type `A =
|
||||||
/// $::Debug` that is understood by the astconv code.
|
/// $::Debug` that is understood by the HIR ty lowering code.
|
||||||
///
|
///
|
||||||
/// FIXME(alexreg): why have a separate type for the binding case,
|
/// FIXME(alexreg): why have a separate type for the binding case,
|
||||||
/// wouldn't it be better to make the `ty` field an enum like the
|
/// wouldn't it be better to make the `ty` field an enum like the
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//! Bounds are restrictions applied to some types after they've been converted into the
|
//! Bounds are restrictions applied to some types after they've been lowered from the HIR to the
|
||||||
//! `ty` form from the HIR.
|
//! [`rustc_middle::ty`] form.
|
||||||
|
|
||||||
use rustc_hir::LangItem;
|
use rustc_hir::LangItem;
|
||||||
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
|
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
|
||||||
|
@ -382,8 +382,8 @@ fn check_opaque_meets_bounds<'tcx>(
|
|||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
Err(ty_err) => {
|
Err(ty_err) => {
|
||||||
// Some types may be left "stranded" if they can't be reached
|
// Some types may be left "stranded" if they can't be reached
|
||||||
// from an astconv'd bound but they're mentioned in the HIR. This
|
// from a lowered rustc_middle bound but they're mentioned in the HIR.
|
||||||
// will happen, e.g., when a nested opaque is inside of a non-
|
// This will happen, e.g., when a nested opaque is inside of a non-
|
||||||
// existent associated type, like `impl Trait<Missing = impl Trait>`.
|
// existent associated type, like `impl Trait<Missing = impl Trait>`.
|
||||||
// See <tests/ui/impl-trait/stranded-opaque.rs>.
|
// See <tests/ui/impl-trait/stranded-opaque.rs>.
|
||||||
let ty_err = ty_err.to_string(tcx);
|
let ty_err = ty_err.to_string(tcx);
|
||||||
|
@ -746,7 +746,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
|||||||
|
|
||||||
// We may not collect all RPITITs that we see in the HIR for a trait signature
|
// We may not collect all RPITITs that we see in the HIR for a trait signature
|
||||||
// because an RPITIT was located within a missing item. Like if we have a sig
|
// because an RPITIT was located within a missing item. Like if we have a sig
|
||||||
// returning `-> Missing<impl Sized>`, that gets converted to `-> [type error]`,
|
// returning `-> Missing<impl Sized>`, that gets converted to `-> {type error}`,
|
||||||
// and when walking through the signature we end up never collecting the def id
|
// and when walking through the signature we end up never collecting the def id
|
||||||
// of the `impl Sized`. Insert that here, so we don't ICE later.
|
// of the `impl Sized`. Insert that here, so we don't ICE later.
|
||||||
for assoc_item in tcx.associated_types_for_impl_traits_in_associated_fn(trait_m.def_id) {
|
for assoc_item in tcx.associated_types_for_impl_traits_in_associated_fn(trait_m.def_id) {
|
||||||
|
@ -760,7 +760,7 @@ impl<'tcx> RegionResolutionVisitor<'tcx> {
|
|||||||
|
|
||||||
fn enter_node_scope_with_dtor(&mut self, id: hir::ItemLocalId) {
|
fn enter_node_scope_with_dtor(&mut self, id: hir::ItemLocalId) {
|
||||||
// If node was previously marked as a terminating scope during the
|
// If node was previously marked as a terminating scope during the
|
||||||
// recursive visit of its parent node in the AST, then we need to
|
// recursive visit of its parent node in the HIR, then we need to
|
||||||
// account for the destruction scope representing the scope of
|
// account for the destruction scope representing the scope of
|
||||||
// the destructors that run immediately after it completes.
|
// the destructors that run immediately after it completes.
|
||||||
if self.terminating_scopes.contains(&id) {
|
if self.terminating_scopes.contains(&id) {
|
||||||
|
@ -272,7 +272,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
|
|||||||
}
|
}
|
||||||
Some(ty::ImplPolarity::Negative) => {
|
Some(ty::ImplPolarity::Negative) => {
|
||||||
let ast::ImplPolarity::Negative(span) = impl_.polarity else {
|
let ast::ImplPolarity::Negative(span) = impl_.polarity else {
|
||||||
bug!("impl_polarity query disagrees with impl's polarity in AST");
|
bug!("impl_polarity query disagrees with impl's polarity in HIR");
|
||||||
};
|
};
|
||||||
// FIXME(#27579): what amount of WF checking do we need for neg impls?
|
// FIXME(#27579): what amount of WF checking do we need for neg impls?
|
||||||
if let hir::Defaultness::Default { .. } = impl_.defaultness {
|
if let hir::Defaultness::Default { .. } = impl_.defaultness {
|
||||||
@ -1866,7 +1866,7 @@ fn check_variances_for_type_defn<'tcx>(
|
|||||||
.iter()
|
.iter()
|
||||||
.filter_map(|predicate| match predicate {
|
.filter_map(|predicate| match predicate {
|
||||||
hir::WherePredicate::BoundPredicate(predicate) => {
|
hir::WherePredicate::BoundPredicate(predicate) => {
|
||||||
match icx.to_ty(predicate.bounded_ty).kind() {
|
match icx.lower_ty(predicate.bounded_ty).kind() {
|
||||||
ty::Param(data) => Some(Parameter(data.index)),
|
ty::Param(data) => Some(Parameter(data.index)),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
@ -40,9 +40,9 @@ use std::cell::Cell;
|
|||||||
use std::iter;
|
use std::iter;
|
||||||
use std::ops::Bound;
|
use std::ops::Bound;
|
||||||
|
|
||||||
use crate::astconv::AstConv;
|
|
||||||
use crate::check::intrinsic::intrinsic_operation_unsafety;
|
use crate::check::intrinsic::intrinsic_operation_unsafety;
|
||||||
use crate::errors;
|
use crate::errors;
|
||||||
|
use crate::hir_ty_lowering::HirTyLowerer;
|
||||||
pub use type_of::test_opaque_hidden_types;
|
pub use type_of::test_opaque_hidden_types;
|
||||||
|
|
||||||
mod generics_of;
|
mod generics_of;
|
||||||
@ -88,13 +88,12 @@ pub fn provide(providers: &mut Providers) {
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/// Context specific to some particular item. This is what implements
|
/// Context specific to some particular item. This is what implements [`HirTyLowerer`].
|
||||||
/// [`AstConv`].
|
|
||||||
///
|
///
|
||||||
/// # `ItemCtxt` vs `FnCtxt`
|
/// # `ItemCtxt` vs `FnCtxt`
|
||||||
///
|
///
|
||||||
/// `ItemCtxt` is primarily used to type-check item signatures and lower them
|
/// `ItemCtxt` is primarily used to type-check item signatures and lower them
|
||||||
/// from HIR to their [`ty::Ty`] representation, which is exposed using [`AstConv`].
|
/// from HIR to their [`ty::Ty`] representation, which is exposed using [`HirTyLowerer`].
|
||||||
/// It's also used for the bodies of items like structs where the body (the fields)
|
/// It's also used for the bodies of items like structs where the body (the fields)
|
||||||
/// are just signatures.
|
/// are just signatures.
|
||||||
///
|
///
|
||||||
@ -111,11 +110,11 @@ pub fn provide(providers: &mut Providers) {
|
|||||||
/// `ItemCtxt` has information about the predicates that are defined
|
/// `ItemCtxt` has information about the predicates that are defined
|
||||||
/// on the trait. Unfortunately, this predicate information is
|
/// on the trait. Unfortunately, this predicate information is
|
||||||
/// available in various different forms at various points in the
|
/// available in various different forms at various points in the
|
||||||
/// process. So we can't just store a pointer to e.g., the AST or the
|
/// process. So we can't just store a pointer to e.g., the HIR or the
|
||||||
/// parsed ty form, we have to be more flexible. To this end, the
|
/// parsed ty form, we have to be more flexible. To this end, the
|
||||||
/// `ItemCtxt` is parameterized by a `DefId` that it uses to satisfy
|
/// `ItemCtxt` is parameterized by a `DefId` that it uses to satisfy
|
||||||
/// `get_type_parameter_bounds` requests, drawing the information from
|
/// `probe_ty_param_bounds` requests, drawing the information from
|
||||||
/// the AST (`hir::Generics`), recursively.
|
/// the HIR (`hir::Generics`), recursively.
|
||||||
pub struct ItemCtxt<'tcx> {
|
pub struct ItemCtxt<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
item_def_id: LocalDefId,
|
item_def_id: LocalDefId,
|
||||||
@ -277,7 +276,7 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
|
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
|
||||||
convert_item(self.tcx, item.item_id());
|
lower_item(self.tcx, item.item_id());
|
||||||
reject_placeholder_type_signatures_in_item(self.tcx, item);
|
reject_placeholder_type_signatures_in_item(self.tcx, item);
|
||||||
intravisit::walk_item(self, item);
|
intravisit::walk_item(self, item);
|
||||||
}
|
}
|
||||||
@ -315,12 +314,12 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
|
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
|
||||||
convert_trait_item(self.tcx, trait_item.trait_item_id());
|
lower_trait_item(self.tcx, trait_item.trait_item_id());
|
||||||
intravisit::walk_trait_item(self, trait_item);
|
intravisit::walk_trait_item(self, trait_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
|
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
|
||||||
convert_impl_item(self.tcx, impl_item.impl_item_id());
|
lower_impl_item(self.tcx, impl_item.impl_item_id());
|
||||||
intravisit::walk_impl_item(self, impl_item);
|
intravisit::walk_impl_item(self, impl_item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -344,8 +343,8 @@ impl<'tcx> ItemCtxt<'tcx> {
|
|||||||
ItemCtxt { tcx, item_def_id, tainted_by_errors: Cell::new(None) }
|
ItemCtxt { tcx, item_def_id, tainted_by_errors: Cell::new(None) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_ty(&self, ast_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
|
pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
|
||||||
self.astconv().ast_ty_to_ty(ast_ty)
|
self.lowerer().lower_ty(hir_ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hir_id(&self) -> hir::HirId {
|
pub fn hir_id(&self) -> hir::HirId {
|
||||||
@ -364,7 +363,7 @@ impl<'tcx> ItemCtxt<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
|
impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
|
||||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
@ -373,23 +372,14 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
|
|||||||
self.item_def_id.to_def_id()
|
self.item_def_id.to_def_id()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_type_parameter_bounds(
|
fn allow_infer(&self) -> bool {
|
||||||
&self,
|
false
|
||||||
span: Span,
|
|
||||||
def_id: LocalDefId,
|
|
||||||
assoc_name: Ident,
|
|
||||||
) -> ty::GenericPredicates<'tcx> {
|
|
||||||
self.tcx.at(span).type_param_predicates((self.item_def_id, def_id, assoc_name))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn re_infer(&self, _: Option<&ty::GenericParamDef>, _: Span) -> Option<ty::Region<'tcx>> {
|
fn re_infer(&self, _: Option<&ty::GenericParamDef>, _: Span) -> Option<ty::Region<'tcx>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn allow_ty_infer(&self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ty_infer(&self, _: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
|
fn ty_infer(&self, _: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
|
||||||
Ty::new_error_with_message(self.tcx(), span, "bad placeholder type")
|
Ty::new_error_with_message(self.tcx(), span, "bad placeholder type")
|
||||||
}
|
}
|
||||||
@ -404,7 +394,16 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
|
|||||||
ty::Const::new_error_with_message(self.tcx(), ty, span, "bad placeholder constant")
|
ty::Const::new_error_with_message(self.tcx(), ty, span, "bad placeholder constant")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn projected_ty_from_poly_trait_ref(
|
fn probe_ty_param_bounds(
|
||||||
|
&self,
|
||||||
|
span: Span,
|
||||||
|
def_id: LocalDefId,
|
||||||
|
assoc_name: Ident,
|
||||||
|
) -> ty::GenericPredicates<'tcx> {
|
||||||
|
self.tcx.at(span).type_param_predicates((self.item_def_id, def_id, assoc_name))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lower_assoc_ty(
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
item_def_id: DefId,
|
item_def_id: DefId,
|
||||||
@ -412,7 +411,7 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
|
|||||||
poly_trait_ref: ty::PolyTraitRef<'tcx>,
|
poly_trait_ref: ty::PolyTraitRef<'tcx>,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
if let Some(trait_ref) = poly_trait_ref.no_bound_vars() {
|
if let Some(trait_ref) = poly_trait_ref.no_bound_vars() {
|
||||||
let item_args = self.astconv().create_args_for_associated_item(
|
let item_args = self.lowerer().lower_generic_args_of_assoc_item(
|
||||||
span,
|
span,
|
||||||
item_def_id,
|
item_def_id,
|
||||||
item_segment,
|
item_segment,
|
||||||
@ -497,10 +496,6 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
|
|||||||
ty.ty_adt_def()
|
ty.ty_adt_def()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_tainted_by_errors(&self, err: ErrorGuaranteed) {
|
|
||||||
self.tainted_by_errors.set(Some(err));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn record_ty(&self, _hir_id: hir::HirId, _ty: Ty<'tcx>, _span: Span) {
|
fn record_ty(&self, _hir_id: hir::HirId, _ty: Ty<'tcx>, _span: Span) {
|
||||||
// There's no place to record types from signatures?
|
// There's no place to record types from signatures?
|
||||||
}
|
}
|
||||||
@ -508,6 +503,10 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
|
|||||||
fn infcx(&self) -> Option<&InferCtxt<'tcx>> {
|
fn infcx(&self) -> Option<&InferCtxt<'tcx>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_tainted_by_errors(&self, err: ErrorGuaranteed) {
|
||||||
|
self.tainted_by_errors.set(Some(err));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Synthesize a new lifetime name that doesn't clash with any of the lifetimes already present.
|
/// Synthesize a new lifetime name that doesn't clash with any of the lifetimes already present.
|
||||||
@ -547,9 +546,10 @@ fn get_new_lifetime_name<'tcx>(
|
|||||||
(1..).flat_map(a_to_z_repeat_n).find(|lt| !existing_lifetimes.contains(lt.as_str())).unwrap()
|
(1..).flat_map(a_to_z_repeat_n).find(|lt| !existing_lifetimes.contains(lt.as_str())).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
|
#[instrument(level = "debug", skip_all)]
|
||||||
|
fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
|
||||||
let it = tcx.hir().item(item_id);
|
let it = tcx.hir().item(item_id);
|
||||||
debug!("convert: item {} with id {}", it.ident, it.hir_id());
|
debug!(item = %it.ident, id = %it.hir_id());
|
||||||
let def_id = item_id.owner_id.def_id;
|
let def_id = item_id.owner_id.def_id;
|
||||||
|
|
||||||
match &it.kind {
|
match &it.kind {
|
||||||
@ -591,7 +591,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
|
|||||||
tcx.ensure().generics_of(def_id);
|
tcx.ensure().generics_of(def_id);
|
||||||
tcx.ensure().type_of(def_id);
|
tcx.ensure().type_of(def_id);
|
||||||
tcx.ensure().predicates_of(def_id);
|
tcx.ensure().predicates_of(def_id);
|
||||||
convert_enum_variant_types(tcx, def_id.to_def_id());
|
lower_enum_variant_types(tcx, def_id.to_def_id());
|
||||||
}
|
}
|
||||||
hir::ItemKind::Impl { .. } => {
|
hir::ItemKind::Impl { .. } => {
|
||||||
tcx.ensure().generics_of(def_id);
|
tcx.ensure().generics_of(def_id);
|
||||||
@ -625,7 +625,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ctor_def_id) = struct_def.ctor_def_id() {
|
if let Some(ctor_def_id) = struct_def.ctor_def_id() {
|
||||||
convert_variant_ctor(tcx, ctor_def_id);
|
lower_variant_ctor(tcx, ctor_def_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -668,7 +668,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
|
fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
|
||||||
let trait_item = tcx.hir().trait_item(trait_item_id);
|
let trait_item = tcx.hir().trait_item(trait_item_id);
|
||||||
let def_id = trait_item_id.owner_id;
|
let def_id = trait_item_id.owner_id;
|
||||||
tcx.ensure().generics_of(def_id);
|
tcx.ensure().generics_of(def_id);
|
||||||
@ -717,7 +717,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
|
|||||||
tcx.ensure().predicates_of(def_id);
|
tcx.ensure().predicates_of(def_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
|
fn lower_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
|
||||||
let def_id = impl_item_id.owner_id;
|
let def_id = impl_item_id.owner_id;
|
||||||
tcx.ensure().generics_of(def_id);
|
tcx.ensure().generics_of(def_id);
|
||||||
tcx.ensure().type_of(def_id);
|
tcx.ensure().type_of(def_id);
|
||||||
@ -746,13 +746,13 @@ fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_variant_ctor(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
fn lower_variant_ctor(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||||
tcx.ensure().generics_of(def_id);
|
tcx.ensure().generics_of(def_id);
|
||||||
tcx.ensure().type_of(def_id);
|
tcx.ensure().type_of(def_id);
|
||||||
tcx.ensure().predicates_of(def_id);
|
tcx.ensure().predicates_of(def_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) {
|
fn lower_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) {
|
||||||
let def = tcx.adt_def(def_id);
|
let def = tcx.adt_def(def_id);
|
||||||
let repr_type = def.repr().discr_type();
|
let repr_type = def.repr().discr_type();
|
||||||
let initial = repr_type.initial_discriminant(tcx);
|
let initial = repr_type.initial_discriminant(tcx);
|
||||||
@ -785,10 +785,9 @@ fn convert_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) {
|
|||||||
tcx.ensure().predicates_of(f.did);
|
tcx.ensure().predicates_of(f.did);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert the ctor, if any. This also registers the variant as
|
// Lower the ctor, if any. This also registers the variant as an item.
|
||||||
// an item.
|
|
||||||
if let Some(ctor_def_id) = variant.ctor_def_id() {
|
if let Some(ctor_def_id) = variant.ctor_def_id() {
|
||||||
convert_variant_ctor(tcx, ctor_def_id.expect_local());
|
lower_variant_ctor(tcx, ctor_def_id.expect_local());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -975,7 +974,7 @@ impl<'tcx> FieldUniquenessCheckContext<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_variant(
|
fn lower_variant(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
variant_did: Option<LocalDefId>,
|
variant_did: Option<LocalDefId>,
|
||||||
ident: Ident,
|
ident: Ident,
|
||||||
@ -1060,7 +1059,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
|
|||||||
};
|
};
|
||||||
distance_from_explicit += 1;
|
distance_from_explicit += 1;
|
||||||
|
|
||||||
convert_variant(
|
lower_variant(
|
||||||
tcx,
|
tcx,
|
||||||
Some(v.def_id),
|
Some(v.def_id),
|
||||||
v.ident,
|
v.ident,
|
||||||
@ -1080,7 +1079,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
|
|||||||
ItemKind::Struct(..) => AdtKind::Struct,
|
ItemKind::Struct(..) => AdtKind::Struct,
|
||||||
_ => AdtKind::Union,
|
_ => AdtKind::Union,
|
||||||
};
|
};
|
||||||
let variants = std::iter::once(convert_variant(
|
let variants = std::iter::once(lower_variant(
|
||||||
tcx,
|
tcx,
|
||||||
None,
|
None,
|
||||||
item.ident,
|
item.ident,
|
||||||
@ -1284,7 +1283,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<ty::PolyFnSig<
|
|||||||
if let Item(hir::Item { kind: ItemKind::Impl(i), .. }) = tcx.parent_hir_node(hir_id)
|
if let Item(hir::Item { kind: ItemKind::Impl(i), .. }) = tcx.parent_hir_node(hir_id)
|
||||||
&& i.of_trait.is_some()
|
&& i.of_trait.is_some()
|
||||||
{
|
{
|
||||||
icx.astconv().ty_of_fn(
|
icx.lowerer().lower_fn_ty(
|
||||||
hir_id,
|
hir_id,
|
||||||
sig.header.unsafety,
|
sig.header.unsafety,
|
||||||
sig.header.abi,
|
sig.header.abi,
|
||||||
@ -1301,9 +1300,14 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<ty::PolyFnSig<
|
|||||||
kind: TraitItemKind::Fn(FnSig { header, decl, span: _ }, _),
|
kind: TraitItemKind::Fn(FnSig { header, decl, span: _ }, _),
|
||||||
generics,
|
generics,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => icx.lowerer().lower_fn_ty(
|
||||||
icx.astconv().ty_of_fn(hir_id, header.unsafety, header.abi, decl, Some(generics), None)
|
hir_id,
|
||||||
}
|
header.unsafety,
|
||||||
|
header.abi,
|
||||||
|
decl,
|
||||||
|
Some(generics),
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
|
||||||
ForeignItem(&hir::ForeignItem { kind: ForeignItemKind::Fn(fn_decl, _, _), .. }) => {
|
ForeignItem(&hir::ForeignItem { kind: ForeignItemKind::Fn(fn_decl, _, _), .. }) => {
|
||||||
let abi = tcx.hir().get_foreign_abi(hir_id);
|
let abi = tcx.hir().get_foreign_abi(hir_id);
|
||||||
@ -1411,7 +1415,7 @@ fn infer_return_ty_for_fn_sig<'tcx>(
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => icx.astconv().ty_of_fn(
|
None => icx.lowerer().lower_fn_ty(
|
||||||
hir_id,
|
hir_id,
|
||||||
sig.header.unsafety,
|
sig.header.unsafety,
|
||||||
sig.header.abi,
|
sig.header.abi,
|
||||||
@ -1529,19 +1533,19 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::ImplTrai
|
|||||||
impl_
|
impl_
|
||||||
.of_trait
|
.of_trait
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|ast_trait_ref| {
|
.map(|hir_trait_ref| {
|
||||||
let selfty = tcx.type_of(def_id).instantiate_identity();
|
let self_ty = tcx.type_of(def_id).instantiate_identity();
|
||||||
|
|
||||||
let trait_ref = if let Some(ErrorGuaranteed { .. }) = check_impl_constness(
|
let trait_ref = if let Some(ErrorGuaranteed { .. }) = check_impl_constness(
|
||||||
tcx,
|
tcx,
|
||||||
tcx.is_const_trait_impl_raw(def_id.to_def_id()),
|
tcx.is_const_trait_impl_raw(def_id.to_def_id()),
|
||||||
ast_trait_ref,
|
hir_trait_ref,
|
||||||
) {
|
) {
|
||||||
// we have a const impl, but for a trait without `#[const_trait]`, so
|
// we have a const impl, but for a trait without `#[const_trait]`, so
|
||||||
// without the host param. If we continue with the HIR trait ref, we get
|
// without the host param. If we continue with the HIR trait ref, we get
|
||||||
// ICEs for generic arg count mismatch. We do a little HIR editing to
|
// ICEs for generic arg count mismatch. We do a little HIR editing to
|
||||||
// make astconv happy.
|
// make HIR ty lowering happy.
|
||||||
let mut path_segments = ast_trait_ref.path.segments.to_vec();
|
let mut path_segments = hir_trait_ref.path.segments.to_vec();
|
||||||
let last_segment = path_segments.len() - 1;
|
let last_segment = path_segments.len() - 1;
|
||||||
let mut args = *path_segments[last_segment].args();
|
let mut args = *path_segments[last_segment].args();
|
||||||
let last_arg = args.args.len() - 1;
|
let last_arg = args.args.len() - 1;
|
||||||
@ -1549,19 +1553,19 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::ImplTrai
|
|||||||
args.args = &args.args[..args.args.len() - 1];
|
args.args = &args.args[..args.args.len() - 1];
|
||||||
path_segments[last_segment].args = Some(tcx.hir_arena.alloc(args));
|
path_segments[last_segment].args = Some(tcx.hir_arena.alloc(args));
|
||||||
let path = hir::Path {
|
let path = hir::Path {
|
||||||
span: ast_trait_ref.path.span,
|
span: hir_trait_ref.path.span,
|
||||||
res: ast_trait_ref.path.res,
|
res: hir_trait_ref.path.res,
|
||||||
segments: tcx.hir_arena.alloc_slice(&path_segments),
|
segments: tcx.hir_arena.alloc_slice(&path_segments),
|
||||||
};
|
};
|
||||||
let trait_ref = tcx.hir_arena.alloc(hir::TraitRef { path: tcx.hir_arena.alloc(path), hir_ref_id: ast_trait_ref.hir_ref_id });
|
let trait_ref = tcx.hir_arena.alloc(hir::TraitRef { path: tcx.hir_arena.alloc(path), hir_ref_id: hir_trait_ref.hir_ref_id });
|
||||||
icx.astconv().instantiate_mono_trait_ref(trait_ref, selfty)
|
icx.lowerer().lower_impl_trait_ref(trait_ref, self_ty)
|
||||||
} else {
|
} else {
|
||||||
icx.astconv().instantiate_mono_trait_ref(ast_trait_ref, selfty)
|
icx.lowerer().lower_impl_trait_ref(hir_trait_ref, self_ty)
|
||||||
};
|
};
|
||||||
ty::ImplTraitHeader {
|
ty::ImplTraitHeader {
|
||||||
trait_ref: ty::EarlyBinder::bind(trait_ref),
|
trait_ref: ty::EarlyBinder::bind(trait_ref),
|
||||||
unsafety: impl_.unsafety,
|
unsafety: impl_.unsafety,
|
||||||
polarity: polarity_of_impl(tcx, def_id, impl_, item.span)
|
polarity: polarity_of_impl(tcx, def_id, impl_, item.span)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -1569,20 +1573,20 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::ImplTrai
|
|||||||
fn check_impl_constness(
|
fn check_impl_constness(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
is_const: bool,
|
is_const: bool,
|
||||||
ast_trait_ref: &hir::TraitRef<'_>,
|
hir_trait_ref: &hir::TraitRef<'_>,
|
||||||
) -> Option<ErrorGuaranteed> {
|
) -> Option<ErrorGuaranteed> {
|
||||||
if !is_const {
|
if !is_const {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let trait_def_id = ast_trait_ref.trait_def_id()?;
|
let trait_def_id = hir_trait_ref.trait_def_id()?;
|
||||||
if tcx.has_attr(trait_def_id, sym::const_trait) {
|
if tcx.has_attr(trait_def_id, sym::const_trait) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let trait_name = tcx.item_name(trait_def_id).to_string();
|
let trait_name = tcx.item_name(trait_def_id).to_string();
|
||||||
Some(tcx.dcx().emit_err(errors::ConstImplForNonConstTrait {
|
Some(tcx.dcx().emit_err(errors::ConstImplForNonConstTrait {
|
||||||
trait_ref_span: ast_trait_ref.path.span,
|
trait_ref_span: hir_trait_ref.path.span,
|
||||||
trait_name,
|
trait_name,
|
||||||
local_trait_span:
|
local_trait_span:
|
||||||
trait_def_id.as_local().map(|_| tcx.def_span(trait_def_id).shrink_to_lo()),
|
trait_def_id.as_local().map(|_| tcx.def_span(trait_def_id).shrink_to_lo()),
|
||||||
@ -1678,19 +1682,19 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
|
|||||||
};
|
};
|
||||||
let hir_id = tcx.local_def_id_to_hir_id(def_id);
|
let hir_id = tcx.local_def_id_to_hir_id(def_id);
|
||||||
let fty =
|
let fty =
|
||||||
ItemCtxt::new(tcx, def_id).astconv().ty_of_fn(hir_id, unsafety, abi, decl, None, None);
|
ItemCtxt::new(tcx, def_id).lowerer().lower_fn_ty(hir_id, unsafety, abi, decl, None, None);
|
||||||
|
|
||||||
// Feature gate SIMD types in FFI, since I am not sure that the
|
// Feature gate SIMD types in FFI, since I am not sure that the
|
||||||
// ABIs are handled at all correctly. -huonw
|
// ABIs are handled at all correctly. -huonw
|
||||||
if abi != abi::Abi::RustIntrinsic && !tcx.features().simd_ffi {
|
if abi != abi::Abi::RustIntrinsic && !tcx.features().simd_ffi {
|
||||||
let check = |ast_ty: &hir::Ty<'_>, ty: Ty<'_>| {
|
let check = |hir_ty: &hir::Ty<'_>, ty: Ty<'_>| {
|
||||||
if ty.is_simd() {
|
if ty.is_simd() {
|
||||||
let snip = tcx
|
let snip = tcx
|
||||||
.sess
|
.sess
|
||||||
.source_map()
|
.source_map()
|
||||||
.span_to_snippet(ast_ty.span)
|
.span_to_snippet(hir_ty.span)
|
||||||
.map_or_else(|_| String::new(), |s| format!(" `{s}`"));
|
.map_or_else(|_| String::new(), |s| format!(" `{s}`"));
|
||||||
tcx.dcx().emit_err(errors::SIMDFFIHighlyExperimental { span: ast_ty.span, snip });
|
tcx.dcx().emit_err(errors::SIMDFFIHighlyExperimental { span: hir_ty.span, snip });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
for (input, ty) in iter::zip(decl.inputs, fty.inputs().skip_binder()) {
|
for (input, ty) in iter::zip(decl.inputs, fty.inputs().skip_binder()) {
|
||||||
|
@ -218,8 +218,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
|||||||
Deny,
|
Deny,
|
||||||
}
|
}
|
||||||
|
|
||||||
let no_generics = hir::Generics::empty();
|
let hir_generics = node.generics().unwrap_or(hir::Generics::empty());
|
||||||
let ast_generics = node.generics().unwrap_or(no_generics);
|
|
||||||
let (opt_self, allow_defaults) = match node {
|
let (opt_self, allow_defaults) = match node {
|
||||||
Node::Item(item) => {
|
Node::Item(item) => {
|
||||||
match item.kind {
|
match item.kind {
|
||||||
@ -275,13 +274,13 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
|||||||
generics.parent_count + generics.params.len()
|
generics.parent_count + generics.params.len()
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut params: Vec<_> = Vec::with_capacity(ast_generics.params.len() + has_self as usize);
|
let mut params: Vec<_> = Vec::with_capacity(hir_generics.params.len() + has_self as usize);
|
||||||
|
|
||||||
if let Some(opt_self) = opt_self {
|
if let Some(opt_self) = opt_self {
|
||||||
params.push(opt_self);
|
params.push(opt_self);
|
||||||
}
|
}
|
||||||
|
|
||||||
let early_lifetimes = super::early_bound_lifetimes_from_generics(tcx, ast_generics);
|
let early_lifetimes = super::early_bound_lifetimes_from_generics(tcx, hir_generics);
|
||||||
params.extend(early_lifetimes.enumerate().map(|(i, param)| ty::GenericParamDef {
|
params.extend(early_lifetimes.enumerate().map(|(i, param)| ty::GenericParamDef {
|
||||||
name: param.name.ident().name,
|
name: param.name.ident().name,
|
||||||
index: own_start + i as u32,
|
index: own_start + i as u32,
|
||||||
@ -302,7 +301,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
|||||||
const TYPE_DEFAULT_NOT_ALLOWED: &'static str = "defaults for type parameters are only allowed in \
|
const TYPE_DEFAULT_NOT_ALLOWED: &'static str = "defaults for type parameters are only allowed in \
|
||||||
`struct`, `enum`, `type`, or `trait` definitions";
|
`struct`, `enum`, `type`, or `trait` definitions";
|
||||||
|
|
||||||
params.extend(ast_generics.params.iter().filter_map(|param| match param.kind {
|
params.extend(hir_generics.params.iter().filter_map(|param| match param.kind {
|
||||||
GenericParamKind::Lifetime { .. } => None,
|
GenericParamKind::Lifetime { .. } => None,
|
||||||
GenericParamKind::Type { default, synthetic, .. } => {
|
GenericParamKind::Type { default, synthetic, .. } => {
|
||||||
if default.is_some() {
|
if default.is_some() {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use super::ItemCtxt;
|
use super::ItemCtxt;
|
||||||
use crate::astconv::{AstConv, PredicateFilter};
|
use crate::hir_ty_lowering::{HirTyLowerer, PredicateFilter};
|
||||||
use rustc_data_structures::fx::FxIndexSet;
|
use rustc_data_structures::fx::FxIndexSet;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_infer::traits::util;
|
use rustc_infer::traits::util;
|
||||||
@ -18,7 +18,7 @@ use rustc_span::Span;
|
|||||||
fn associated_type_bounds<'tcx>(
|
fn associated_type_bounds<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
assoc_item_def_id: LocalDefId,
|
assoc_item_def_id: LocalDefId,
|
||||||
ast_bounds: &'tcx [hir::GenericBound<'tcx>],
|
hir_bounds: &'tcx [hir::GenericBound<'tcx>],
|
||||||
span: Span,
|
span: Span,
|
||||||
filter: PredicateFilter,
|
filter: PredicateFilter,
|
||||||
) -> &'tcx [(ty::Clause<'tcx>, Span)] {
|
) -> &'tcx [(ty::Clause<'tcx>, Span)] {
|
||||||
@ -29,9 +29,9 @@ fn associated_type_bounds<'tcx>(
|
|||||||
);
|
);
|
||||||
|
|
||||||
let icx = ItemCtxt::new(tcx, assoc_item_def_id);
|
let icx = ItemCtxt::new(tcx, assoc_item_def_id);
|
||||||
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, filter);
|
let mut bounds = icx.lowerer().lower_mono_bounds(item_ty, hir_bounds, filter);
|
||||||
// Associated types are implicitly sized unless a `?Sized` bound is found
|
// Associated types are implicitly sized unless a `?Sized` bound is found
|
||||||
icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span);
|
icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
|
||||||
|
|
||||||
let trait_def_id = tcx.local_parent(assoc_item_def_id);
|
let trait_def_id = tcx.local_parent(assoc_item_def_id);
|
||||||
let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id);
|
let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id);
|
||||||
@ -62,16 +62,16 @@ fn associated_type_bounds<'tcx>(
|
|||||||
fn opaque_type_bounds<'tcx>(
|
fn opaque_type_bounds<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
opaque_def_id: LocalDefId,
|
opaque_def_id: LocalDefId,
|
||||||
ast_bounds: &'tcx [hir::GenericBound<'tcx>],
|
hir_bounds: &'tcx [hir::GenericBound<'tcx>],
|
||||||
item_ty: Ty<'tcx>,
|
item_ty: Ty<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
filter: PredicateFilter,
|
filter: PredicateFilter,
|
||||||
) -> &'tcx [(ty::Clause<'tcx>, Span)] {
|
) -> &'tcx [(ty::Clause<'tcx>, Span)] {
|
||||||
ty::print::with_reduced_queries!({
|
ty::print::with_reduced_queries!({
|
||||||
let icx = ItemCtxt::new(tcx, opaque_def_id);
|
let icx = ItemCtxt::new(tcx, opaque_def_id);
|
||||||
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, filter);
|
let mut bounds = icx.lowerer().lower_mono_bounds(item_ty, hir_bounds, filter);
|
||||||
// Opaque types are implicitly sized unless a `?Sized` bound is found
|
// Opaque types are implicitly sized unless a `?Sized` bound is found
|
||||||
icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span);
|
icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
|
||||||
debug!(?bounds);
|
debug!(?bounds);
|
||||||
|
|
||||||
tcx.arena.alloc_from_iter(bounds.clauses())
|
tcx.arena.alloc_from_iter(bounds.clauses())
|
||||||
@ -138,8 +138,8 @@ pub(super) fn explicit_item_bounds_with_filter(
|
|||||||
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
|
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
|
||||||
opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter)
|
opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter)
|
||||||
}
|
}
|
||||||
// Since RPITITs are astconv'd as projections in `ast_ty_to_ty`, when we're asking
|
// Since RPITITs are lowered as projections in `<dyn HirTyLowerer>::lower_ty`, when we're
|
||||||
// for the item bounds of the *opaques* in a trait's default method signature, we
|
// asking for the item bounds of the *opaques* in a trait's default method signature, we
|
||||||
// need to map these projections back to opaques.
|
// need to map these projections back to opaques.
|
||||||
hir::Node::Item(hir::Item {
|
hir::Node::Item(hir::Item {
|
||||||
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait: true, origin, .. }),
|
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait: true, origin, .. }),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::astconv::{AstConv, OnlySelfBounds, PredicateFilter};
|
|
||||||
use crate::bounds::Bounds;
|
use crate::bounds::Bounds;
|
||||||
use crate::collect::ItemCtxt;
|
use crate::collect::ItemCtxt;
|
||||||
use crate::constrained_generic_params as cgp;
|
use crate::constrained_generic_params as cgp;
|
||||||
|
use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter};
|
||||||
use hir::{HirId, Node};
|
use hir::{HirId, Node};
|
||||||
use rustc_data_structures::fx::FxIndexSet;
|
use rustc_data_structures::fx::FxIndexSet;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
@ -123,7 +123,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
|||||||
// Preserving the order of insertion is important here so as not to break UI tests.
|
// Preserving the order of insertion is important here so as not to break UI tests.
|
||||||
let mut predicates: FxIndexSet<(ty::Clause<'_>, Span)> = FxIndexSet::default();
|
let mut predicates: FxIndexSet<(ty::Clause<'_>, Span)> = FxIndexSet::default();
|
||||||
|
|
||||||
let ast_generics = node.generics().unwrap_or(NO_GENERICS);
|
let hir_generics = node.generics().unwrap_or(NO_GENERICS);
|
||||||
if let Node::Item(item) = node {
|
if let Node::Item(item) = node {
|
||||||
match item.kind {
|
match item.kind {
|
||||||
ItemKind::Impl(impl_) => {
|
ItemKind::Impl(impl_) => {
|
||||||
@ -149,8 +149,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
|||||||
// like `trait Foo: A + B + C`.
|
// like `trait Foo: A + B + C`.
|
||||||
if let Some(self_bounds) = is_trait {
|
if let Some(self_bounds) = is_trait {
|
||||||
predicates.extend(
|
predicates.extend(
|
||||||
icx.astconv()
|
icx.lowerer()
|
||||||
.compute_bounds(tcx.types.self_param, self_bounds, PredicateFilter::All)
|
.lower_mono_bounds(tcx.types.self_param, self_bounds, PredicateFilter::All)
|
||||||
.clauses(),
|
.clauses(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -170,19 +170,19 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
|||||||
// Collect the predicates that were written inline by the user on each
|
// Collect the predicates that were written inline by the user on each
|
||||||
// type parameter (e.g., `<T: Foo>`). Also add `ConstArgHasType` predicates
|
// type parameter (e.g., `<T: Foo>`). Also add `ConstArgHasType` predicates
|
||||||
// for each const parameter.
|
// for each const parameter.
|
||||||
for param in ast_generics.params {
|
for param in hir_generics.params {
|
||||||
match param.kind {
|
match param.kind {
|
||||||
// We already dealt with early bound lifetimes above.
|
// We already dealt with early bound lifetimes above.
|
||||||
GenericParamKind::Lifetime { .. } => (),
|
GenericParamKind::Lifetime { .. } => (),
|
||||||
GenericParamKind::Type { .. } => {
|
GenericParamKind::Type { .. } => {
|
||||||
let param_ty = icx.astconv().hir_id_to_bound_ty(param.hir_id);
|
let param_ty = icx.lowerer().lower_ty_param(param.hir_id);
|
||||||
let mut bounds = Bounds::default();
|
let mut bounds = Bounds::default();
|
||||||
// Params are implicitly sized unless a `?Sized` bound is found
|
// Params are implicitly sized unless a `?Sized` bound is found
|
||||||
icx.astconv().add_implicitly_sized(
|
icx.lowerer().add_sized_bound(
|
||||||
&mut bounds,
|
&mut bounds,
|
||||||
param_ty,
|
param_ty,
|
||||||
&[],
|
&[],
|
||||||
Some((param.def_id, ast_generics.predicates)),
|
Some((param.def_id, hir_generics.predicates)),
|
||||||
param.span,
|
param.span,
|
||||||
);
|
);
|
||||||
trace!(?bounds);
|
trace!(?bounds);
|
||||||
@ -194,7 +194,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
|||||||
.type_of(param.def_id.to_def_id())
|
.type_of(param.def_id.to_def_id())
|
||||||
.no_bound_vars()
|
.no_bound_vars()
|
||||||
.expect("const parameters cannot be generic");
|
.expect("const parameters cannot be generic");
|
||||||
let ct = icx.astconv().hir_id_to_bound_const(param.hir_id, ct_ty);
|
let ct = icx.lowerer().lower_const_param(param.hir_id, ct_ty);
|
||||||
predicates.insert((
|
predicates.insert((
|
||||||
ty::ClauseKind::ConstArgHasType(ct, ct_ty).to_predicate(tcx),
|
ty::ClauseKind::ConstArgHasType(ct, ct_ty).to_predicate(tcx),
|
||||||
param.span,
|
param.span,
|
||||||
@ -205,10 +205,10 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
|||||||
|
|
||||||
trace!(?predicates);
|
trace!(?predicates);
|
||||||
// Add in the bounds that appear in the where-clause.
|
// Add in the bounds that appear in the where-clause.
|
||||||
for predicate in ast_generics.predicates {
|
for predicate in hir_generics.predicates {
|
||||||
match predicate {
|
match predicate {
|
||||||
hir::WherePredicate::BoundPredicate(bound_pred) => {
|
hir::WherePredicate::BoundPredicate(bound_pred) => {
|
||||||
let ty = icx.to_ty(bound_pred.bounded_ty);
|
let ty = icx.lower_ty(bound_pred.bounded_ty);
|
||||||
let bound_vars = tcx.late_bound_vars(bound_pred.hir_id);
|
let bound_vars = tcx.late_bound_vars(bound_pred.hir_id);
|
||||||
// Keep the type around in a dummy predicate, in case of no bounds.
|
// Keep the type around in a dummy predicate, in case of no bounds.
|
||||||
// That way, `where Ty:` is not a complete noop (see #53696) and `Ty`
|
// That way, `where Ty:` is not a complete noop (see #53696) and `Ty`
|
||||||
@ -232,7 +232,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut bounds = Bounds::default();
|
let mut bounds = Bounds::default();
|
||||||
icx.astconv().add_bounds(
|
icx.lowerer().lower_poly_bounds(
|
||||||
ty,
|
ty,
|
||||||
bound_pred.bounds.iter(),
|
bound_pred.bounds.iter(),
|
||||||
&mut bounds,
|
&mut bounds,
|
||||||
@ -243,11 +243,11 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
|||||||
}
|
}
|
||||||
|
|
||||||
hir::WherePredicate::RegionPredicate(region_pred) => {
|
hir::WherePredicate::RegionPredicate(region_pred) => {
|
||||||
let r1 = icx.astconv().ast_region_to_region(region_pred.lifetime, None);
|
let r1 = icx.lowerer().lower_lifetime(region_pred.lifetime, None);
|
||||||
predicates.extend(region_pred.bounds.iter().map(|bound| {
|
predicates.extend(region_pred.bounds.iter().map(|bound| {
|
||||||
let (r2, span) = match bound {
|
let (r2, span) = match bound {
|
||||||
hir::GenericBound::Outlives(lt) => {
|
hir::GenericBound::Outlives(lt) => {
|
||||||
(icx.astconv().ast_region_to_region(lt, None), lt.ident.span)
|
(icx.lowerer().lower_lifetime(lt, None), lt.ident.span)
|
||||||
}
|
}
|
||||||
bound => {
|
bound => {
|
||||||
span_bug!(
|
span_bug!(
|
||||||
@ -542,8 +542,8 @@ pub(super) fn explicit_predicates_of<'tcx>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Ensures that the super-predicates of the trait with a `DefId`
|
/// Ensures that the super-predicates of the trait with a `DefId`
|
||||||
/// of `trait_def_id` are converted and stored. This also ensures that
|
/// of `trait_def_id` are lowered and stored. This also ensures that
|
||||||
/// the transitive super-predicates are converted.
|
/// the transitive super-predicates are lowered.
|
||||||
pub(super) fn super_predicates_of(
|
pub(super) fn super_predicates_of(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
trait_def_id: LocalDefId,
|
trait_def_id: LocalDefId,
|
||||||
@ -574,8 +574,8 @@ pub(super) fn implied_predicates_of(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Ensures that the super-predicates of the trait with a `DefId`
|
/// Ensures that the super-predicates of the trait with a `DefId`
|
||||||
/// of `trait_def_id` are converted and stored. This also ensures that
|
/// of `trait_def_id` are lowered and stored. This also ensures that
|
||||||
/// the transitive super-predicates are converted.
|
/// the transitive super-predicates are lowered.
|
||||||
pub(super) fn implied_predicates_with_filter(
|
pub(super) fn implied_predicates_with_filter(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
trait_def_id: DefId,
|
trait_def_id: DefId,
|
||||||
@ -601,9 +601,9 @@ pub(super) fn implied_predicates_with_filter(
|
|||||||
let icx = ItemCtxt::new(tcx, trait_def_id);
|
let icx = ItemCtxt::new(tcx, trait_def_id);
|
||||||
|
|
||||||
let self_param_ty = tcx.types.self_param;
|
let self_param_ty = tcx.types.self_param;
|
||||||
let superbounds = icx.astconv().compute_bounds(self_param_ty, bounds, filter);
|
let superbounds = icx.lowerer().lower_mono_bounds(self_param_ty, bounds, filter);
|
||||||
|
|
||||||
let where_bounds_that_match = icx.type_parameter_bounds_in_generics(
|
let where_bounds_that_match = icx.probe_ty_param_bounds_in_generics(
|
||||||
generics,
|
generics,
|
||||||
item.owner_id.def_id,
|
item.owner_id.def_id,
|
||||||
self_param_ty,
|
self_param_ty,
|
||||||
@ -615,7 +615,7 @@ pub(super) fn implied_predicates_with_filter(
|
|||||||
&*tcx.arena.alloc_from_iter(superbounds.clauses().chain(where_bounds_that_match));
|
&*tcx.arena.alloc_from_iter(superbounds.clauses().chain(where_bounds_that_match));
|
||||||
debug!(?implied_bounds);
|
debug!(?implied_bounds);
|
||||||
|
|
||||||
// Now require that immediate supertraits are converted, which will, in
|
// Now require that immediate supertraits are lowered, which will, in
|
||||||
// turn, reach indirect supertraits, so we detect cycles now instead of
|
// turn, reach indirect supertraits, so we detect cycles now instead of
|
||||||
// overflowing during elaboration. Same for implied predicates, which
|
// overflowing during elaboration. Same for implied predicates, which
|
||||||
// make sure we walk into associated type bounds.
|
// make sure we walk into associated type bounds.
|
||||||
@ -656,7 +656,7 @@ pub(super) fn type_param_predicates(
|
|||||||
use rustc_hir::*;
|
use rustc_hir::*;
|
||||||
use rustc_middle::ty::Ty;
|
use rustc_middle::ty::Ty;
|
||||||
|
|
||||||
// In the AST, bounds can derive from two places. Either
|
// In the HIR, bounds can derive from two places. Either
|
||||||
// written inline like `<T: Foo>` or in a where-clause like
|
// written inline like `<T: Foo>` or in a where-clause like
|
||||||
// `where T: Foo`.
|
// `where T: Foo`.
|
||||||
|
|
||||||
@ -676,7 +676,7 @@ pub(super) fn type_param_predicates(
|
|||||||
let mut result = parent
|
let mut result = parent
|
||||||
.map(|parent| {
|
.map(|parent| {
|
||||||
let icx = ItemCtxt::new(tcx, parent);
|
let icx = ItemCtxt::new(tcx, parent);
|
||||||
icx.get_type_parameter_bounds(DUMMY_SP, def_id, assoc_name)
|
icx.probe_ty_param_bounds(DUMMY_SP, def_id, assoc_name)
|
||||||
})
|
})
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let mut extend = None;
|
let mut extend = None;
|
||||||
@ -684,7 +684,7 @@ pub(super) fn type_param_predicates(
|
|||||||
let item_hir_id = tcx.local_def_id_to_hir_id(item_def_id);
|
let item_hir_id = tcx.local_def_id_to_hir_id(item_def_id);
|
||||||
|
|
||||||
let hir_node = tcx.hir_node(item_hir_id);
|
let hir_node = tcx.hir_node(item_hir_id);
|
||||||
let Some(ast_generics) = hir_node.generics() else { return result };
|
let Some(hir_generics) = hir_node.generics() else { return result };
|
||||||
if let Node::Item(item) = hir_node
|
if let Node::Item(item) = hir_node
|
||||||
&& let ItemKind::Trait(..) = item.kind
|
&& let ItemKind::Trait(..) = item.kind
|
||||||
// Implied `Self: Trait` and supertrait bounds.
|
// Implied `Self: Trait` and supertrait bounds.
|
||||||
@ -696,8 +696,8 @@ pub(super) fn type_param_predicates(
|
|||||||
|
|
||||||
let icx = ItemCtxt::new(tcx, item_def_id);
|
let icx = ItemCtxt::new(tcx, item_def_id);
|
||||||
let extra_predicates = extend.into_iter().chain(
|
let extra_predicates = extend.into_iter().chain(
|
||||||
icx.type_parameter_bounds_in_generics(
|
icx.probe_ty_param_bounds_in_generics(
|
||||||
ast_generics,
|
hir_generics,
|
||||||
def_id,
|
def_id,
|
||||||
ty,
|
ty,
|
||||||
PredicateFilter::SelfThatDefines(assoc_name),
|
PredicateFilter::SelfThatDefines(assoc_name),
|
||||||
@ -714,21 +714,22 @@ pub(super) fn type_param_predicates(
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> ItemCtxt<'tcx> {
|
impl<'tcx> ItemCtxt<'tcx> {
|
||||||
/// Finds bounds from `hir::Generics`. This requires scanning through the
|
/// Finds bounds from `hir::Generics`.
|
||||||
/// AST. We do this to avoid having to convert *all* the bounds, which
|
///
|
||||||
/// would create artificial cycles. Instead, we can only convert the
|
/// This requires scanning through the HIR.
|
||||||
/// bounds for a type parameter `X` if `X::Foo` is used.
|
/// We do this to avoid having to lower *all* the bounds, which would create artificial cycles.
|
||||||
#[instrument(level = "trace", skip(self, ast_generics))]
|
/// Instead, we can only lower the bounds for a type parameter `X` if `X::Foo` is used.
|
||||||
fn type_parameter_bounds_in_generics(
|
#[instrument(level = "trace", skip(self, hir_generics))]
|
||||||
|
fn probe_ty_param_bounds_in_generics(
|
||||||
&self,
|
&self,
|
||||||
ast_generics: &'tcx hir::Generics<'tcx>,
|
hir_generics: &'tcx hir::Generics<'tcx>,
|
||||||
param_def_id: LocalDefId,
|
param_def_id: LocalDefId,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
filter: PredicateFilter,
|
filter: PredicateFilter,
|
||||||
) -> Vec<(ty::Clause<'tcx>, Span)> {
|
) -> Vec<(ty::Clause<'tcx>, Span)> {
|
||||||
let mut bounds = Bounds::default();
|
let mut bounds = Bounds::default();
|
||||||
|
|
||||||
for predicate in ast_generics.predicates {
|
for predicate in hir_generics.predicates {
|
||||||
let hir::WherePredicate::BoundPredicate(predicate) = predicate else {
|
let hir::WherePredicate::BoundPredicate(predicate) = predicate else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
@ -750,13 +751,13 @@ impl<'tcx> ItemCtxt<'tcx> {
|
|||||||
let bound_ty = if predicate.is_param_bound(param_def_id.to_def_id()) {
|
let bound_ty = if predicate.is_param_bound(param_def_id.to_def_id()) {
|
||||||
ty
|
ty
|
||||||
} else if matches!(filter, PredicateFilter::All) {
|
} else if matches!(filter, PredicateFilter::All) {
|
||||||
self.to_ty(predicate.bounded_ty)
|
self.lower_ty(predicate.bounded_ty)
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
let bound_vars = self.tcx.late_bound_vars(predicate.hir_id);
|
let bound_vars = self.tcx.late_bound_vars(predicate.hir_id);
|
||||||
self.astconv().add_bounds(
|
self.lowerer().lower_poly_bounds(
|
||||||
bound_ty,
|
bound_ty,
|
||||||
predicate.bounds.iter().filter(|bound| {
|
predicate.bounds.iter().filter(|bound| {
|
||||||
assoc_name
|
assoc_name
|
||||||
|
@ -1917,18 +1917,18 @@ fn is_late_bound_map(
|
|||||||
///
|
///
|
||||||
/// If we conservatively considered `'a` unconstrained then we could break users who had written code before
|
/// If we conservatively considered `'a` unconstrained then we could break users who had written code before
|
||||||
/// we started correctly handling aliases. If we considered `'a` constrained then it would become late bound
|
/// we started correctly handling aliases. If we considered `'a` constrained then it would become late bound
|
||||||
/// causing an error during astconv as the `'a` is not constrained by the input type `<() as Trait<'a>>::Assoc`
|
/// causing an error during HIR ty lowering as the `'a` is not constrained by the input type `<() as Trait<'a>>::Assoc`
|
||||||
/// but appears in the output type `<() as Trait<'a>>::Assoc`.
|
/// but appears in the output type `<() as Trait<'a>>::Assoc`.
|
||||||
///
|
///
|
||||||
/// We must therefore "look into" the `Alias` to see whether we should consider `'a` constrained or not.
|
/// We must therefore "look into" the `Alias` to see whether we should consider `'a` constrained or not.
|
||||||
///
|
///
|
||||||
/// See #100508 #85533 #47511 for additional context
|
/// See #100508 #85533 #47511 for additional context
|
||||||
struct ConstrainedCollectorPostAstConv {
|
struct ConstrainedCollectorPostHirTyLowering {
|
||||||
arg_is_constrained: Box<[bool]>,
|
arg_is_constrained: Box<[bool]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
use ty::Ty;
|
use ty::Ty;
|
||||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ConstrainedCollectorPostAstConv {
|
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ConstrainedCollectorPostHirTyLowering {
|
||||||
fn visit_ty(&mut self, t: Ty<'tcx>) {
|
fn visit_ty(&mut self, t: Ty<'tcx>) {
|
||||||
match t.kind() {
|
match t.kind() {
|
||||||
ty::Param(param_ty) => {
|
ty::Param(param_ty) => {
|
||||||
@ -1970,10 +1970,10 @@ fn is_late_bound_map(
|
|||||||
None,
|
None,
|
||||||
hir::Path { res: Res::Def(DefKind::TyAlias, alias_def), segments, span },
|
hir::Path { res: Res::Def(DefKind::TyAlias, alias_def), segments, span },
|
||||||
)) => {
|
)) => {
|
||||||
// See comments on `ConstrainedCollectorPostAstConv` for why this arm does not just consider
|
// See comments on `ConstrainedCollectorPostHirTyLowering` for why this arm does not
|
||||||
// args to be unconstrained.
|
// just consider args to be unconstrained.
|
||||||
let generics = self.tcx.generics_of(alias_def);
|
let generics = self.tcx.generics_of(alias_def);
|
||||||
let mut walker = ConstrainedCollectorPostAstConv {
|
let mut walker = ConstrainedCollectorPostHirTyLowering {
|
||||||
arg_is_constrained: vec![false; generics.params.len()].into_boxed_slice(),
|
arg_is_constrained: vec![false; generics.params.len()].into_boxed_slice(),
|
||||||
};
|
};
|
||||||
walker.visit_ty(self.tcx.type_of(alias_def).instantiate_identity());
|
walker.visit_ty(self.tcx.type_of(alias_def).instantiate_identity());
|
||||||
|
@ -97,10 +97,10 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
|||||||
// I believe this match arm is only needed for GAT but I am not 100% sure - BoxyUwU
|
// I believe this match arm is only needed for GAT but I am not 100% sure - BoxyUwU
|
||||||
Node::Ty(hir_ty @ hir::Ty { kind: TyKind::Path(QPath::TypeRelative(_, segment)), .. }) => {
|
Node::Ty(hir_ty @ hir::Ty { kind: TyKind::Path(QPath::TypeRelative(_, segment)), .. }) => {
|
||||||
// Find the Item containing the associated type so we can create an ItemCtxt.
|
// Find the Item containing the associated type so we can create an ItemCtxt.
|
||||||
// Using the ItemCtxt convert the HIR for the unresolved assoc type into a
|
// Using the ItemCtxt lower the HIR for the unresolved assoc type into a
|
||||||
// ty which is a fully resolved projection.
|
// ty which is a fully resolved projection.
|
||||||
// For the code example above, this would mean converting Self::Assoc<3>
|
// For the code example above, this would mean lowering `Self::Assoc<3>`
|
||||||
// into a ty::Alias(ty::Projection, <Self as Foo>::Assoc<3>)
|
// to a ty::Alias(ty::Projection, `<Self as Foo>::Assoc<3>`).
|
||||||
let item_def_id = tcx
|
let item_def_id = tcx
|
||||||
.hir()
|
.hir()
|
||||||
.parent_owner_iter(hir_id)
|
.parent_owner_iter(hir_id)
|
||||||
@ -108,7 +108,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.0
|
.0
|
||||||
.def_id;
|
.def_id;
|
||||||
let ty = ItemCtxt::new(tcx, item_def_id).to_ty(hir_ty);
|
let ty = ItemCtxt::new(tcx, item_def_id).lower_ty(hir_ty);
|
||||||
|
|
||||||
// Iterate through the generics of the projection to find the one that corresponds to
|
// Iterate through the generics of the projection to find the one that corresponds to
|
||||||
// the def_id that this query was called with. We filter to only type and const args here
|
// the def_id that this query was called with. We filter to only type and const args here
|
||||||
@ -369,8 +369,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| icx.to_ty(ty)),
|
.unwrap_or_else(|| icx.lower_ty(ty)),
|
||||||
TraitItemKind::Type(_, Some(ty)) => icx.to_ty(ty),
|
TraitItemKind::Type(_, Some(ty)) => icx.lower_ty(ty),
|
||||||
TraitItemKind::Type(_, None) => {
|
TraitItemKind::Type(_, None) => {
|
||||||
span_bug!(item.span, "associated type missing default");
|
span_bug!(item.span, "associated type missing default");
|
||||||
}
|
}
|
||||||
@ -392,7 +392,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
|
|||||||
"associated constant",
|
"associated constant",
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
icx.to_ty(ty)
|
icx.lower_ty(ty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImplItemKind::Type(ty) => {
|
ImplItemKind::Type(ty) => {
|
||||||
@ -400,7 +400,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
|
|||||||
check_feature_inherent_assoc_ty(tcx, item.span);
|
check_feature_inherent_assoc_ty(tcx, item.span);
|
||||||
}
|
}
|
||||||
|
|
||||||
icx.to_ty(ty)
|
icx.lower_ty(ty)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -416,17 +416,17 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
|
|||||||
"static variable",
|
"static variable",
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
icx.to_ty(ty)
|
icx.lower_ty(ty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ItemKind::Const(ty, _, body_id) => {
|
ItemKind::Const(ty, _, body_id) => {
|
||||||
if ty.is_suggestable_infer_ty() {
|
if ty.is_suggestable_infer_ty() {
|
||||||
infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident, "constant")
|
infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident, "constant")
|
||||||
} else {
|
} else {
|
||||||
icx.to_ty(ty)
|
icx.lower_ty(ty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ItemKind::TyAlias(self_ty, _) => icx.to_ty(self_ty),
|
ItemKind::TyAlias(self_ty, _) => icx.lower_ty(self_ty),
|
||||||
ItemKind::Impl(hir::Impl { self_ty, .. }) => match self_ty.find_self_aliases() {
|
ItemKind::Impl(hir::Impl { self_ty, .. }) => match self_ty.find_self_aliases() {
|
||||||
spans if spans.len() > 0 => {
|
spans if spans.len() > 0 => {
|
||||||
let guar = tcx
|
let guar = tcx
|
||||||
@ -434,7 +434,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
|
|||||||
.emit_err(crate::errors::SelfInImplSelf { span: spans.into(), note: () });
|
.emit_err(crate::errors::SelfInImplSelf { span: spans.into(), note: () });
|
||||||
Ty::new_error(tcx, guar)
|
Ty::new_error(tcx, guar)
|
||||||
}
|
}
|
||||||
_ => icx.to_ty(*self_ty),
|
_ => icx.lower_ty(*self_ty),
|
||||||
},
|
},
|
||||||
ItemKind::Fn(..) => {
|
ItemKind::Fn(..) => {
|
||||||
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
||||||
@ -466,7 +466,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
|
|||||||
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
||||||
Ty::new_fn_def(tcx, def_id.to_def_id(), args)
|
Ty::new_fn_def(tcx, def_id.to_def_id(), args)
|
||||||
}
|
}
|
||||||
ForeignItemKind::Static(t, _) => icx.to_ty(t),
|
ForeignItemKind::Static(t, _) => icx.lower_ty(t),
|
||||||
ForeignItemKind::Type => Ty::new_foreign(tcx, def_id.to_def_id()),
|
ForeignItemKind::Type => Ty::new_foreign(tcx, def_id.to_def_id()),
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -480,7 +480,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
Node::Field(field) => icx.to_ty(field.ty),
|
Node::Field(field) => icx.lower_ty(field.ty),
|
||||||
|
|
||||||
Node::Expr(&Expr { kind: ExprKind::Closure { .. }, .. }) => {
|
Node::Expr(&Expr { kind: ExprKind::Closure { .. }, .. }) => {
|
||||||
tcx.typeck(def_id).node_type(hir_id)
|
tcx.typeck(def_id).node_type(hir_id)
|
||||||
@ -495,7 +495,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
|
|||||||
|
|
||||||
Node::GenericParam(param) => match ¶m.kind {
|
Node::GenericParam(param) => match ¶m.kind {
|
||||||
GenericParamKind::Type { default: Some(ty), .. }
|
GenericParamKind::Type { default: Some(ty), .. }
|
||||||
| GenericParamKind::Const { ty, .. } => icx.to_ty(ty),
|
| GenericParamKind::Const { ty, .. } => icx.lower_ty(ty),
|
||||||
x => bug!("unexpected non-type Node::GenericParam: {:?}", x),
|
x => bug!("unexpected non-type Node::GenericParam: {:?}", x),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -12,17 +12,19 @@ use rustc_trait_selection::traits;
|
|||||||
use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
|
use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
use crate::astconv::{AstConv, OnlySelfBounds, PredicateFilter};
|
|
||||||
use crate::bounds::Bounds;
|
use crate::bounds::Bounds;
|
||||||
use crate::errors;
|
use crate::errors;
|
||||||
|
use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter};
|
||||||
|
|
||||||
impl<'tcx> dyn AstConv<'tcx> + '_ {
|
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
/// Sets `implicitly_sized` to true on `Bounds` if necessary
|
/// Add a `Sized` bound to the `bounds` if appropriate.
|
||||||
pub(crate) fn add_implicitly_sized(
|
///
|
||||||
|
/// Doesn't add the bound if the HIR bounds contain any of `Sized`, `?Sized` or `!Sized`.
|
||||||
|
pub(crate) fn add_sized_bound(
|
||||||
&self,
|
&self,
|
||||||
bounds: &mut Bounds<'tcx>,
|
bounds: &mut Bounds<'tcx>,
|
||||||
self_ty: Ty<'tcx>,
|
self_ty: Ty<'tcx>,
|
||||||
ast_bounds: &'tcx [hir::GenericBound<'tcx>],
|
hir_bounds: &'tcx [hir::GenericBound<'tcx>],
|
||||||
self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
|
self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) {
|
) {
|
||||||
@ -33,9 +35,9 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
|
|
||||||
// Try to find an unbound in bounds.
|
// Try to find an unbound in bounds.
|
||||||
let mut unbounds: SmallVec<[_; 1]> = SmallVec::new();
|
let mut unbounds: SmallVec<[_; 1]> = SmallVec::new();
|
||||||
let mut search_bounds = |ast_bounds: &'tcx [hir::GenericBound<'tcx>]| {
|
let mut search_bounds = |hir_bounds: &'tcx [hir::GenericBound<'tcx>]| {
|
||||||
for ab in ast_bounds {
|
for hir_bound in hir_bounds {
|
||||||
let hir::GenericBound::Trait(ptr, modifier) = ab else {
|
let hir::GenericBound::Trait(ptr, modifier) = hir_bound else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
match modifier {
|
match modifier {
|
||||||
@ -58,7 +60,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
search_bounds(ast_bounds);
|
search_bounds(hir_bounds);
|
||||||
if let Some((self_ty, where_clause)) = self_ty_where_predicates {
|
if let Some((self_ty, where_clause)) = self_ty_where_predicates {
|
||||||
for clause in where_clause {
|
for clause in where_clause {
|
||||||
if let hir::WherePredicate::BoundPredicate(pred) = clause
|
if let hir::WherePredicate::BoundPredicate(pred) = clause
|
||||||
@ -101,34 +103,40 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This helper takes a *converted* parameter type (`param_ty`)
|
/// Lower HIR bounds into `bounds` given the self type `param_ty` and the overarching late-bound vars if any.
|
||||||
/// and an *unconverted* list of bounds:
|
|
||||||
///
|
///
|
||||||
/// ```text
|
/// ### Examples
|
||||||
/// fn foo<T: Debug>
|
///
|
||||||
/// ^ ^^^^^ `ast_bounds` parameter, in HIR form
|
/// ```ignore (illustrative)
|
||||||
/// |
|
/// fn foo<T>() where for<'a> T: Trait<'a> + Copy {}
|
||||||
/// `param_ty`, in ty form
|
/// // ^^^^^^^ ^ ^^^^^^^^^^^^^^^^ `hir_bounds`, in HIR form
|
||||||
|
/// // | |
|
||||||
|
/// // | `param_ty`, in ty form
|
||||||
|
/// // `bound_vars`, in ty form
|
||||||
|
///
|
||||||
|
/// fn bar<T>() where T: for<'a> Trait<'a> + Copy {} // no overarching `bound_vars` here!
|
||||||
|
/// // ^ ^^^^^^^^^^^^^^^^^^^^^^^^ `hir_bounds`, in HIR form
|
||||||
|
/// // |
|
||||||
|
/// // `param_ty`, in ty form
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// It adds these `ast_bounds` into the `bounds` structure.
|
/// ### A Note on Binders
|
||||||
///
|
///
|
||||||
/// **A note on binders:** there is an implied binder around
|
/// There is an implied binder around `param_ty` and `hir_bounds`.
|
||||||
/// `param_ty` and `ast_bounds`. See `instantiate_poly_trait_ref`
|
/// See `lower_poly_trait_ref` for more details.
|
||||||
/// for more details.
|
#[instrument(level = "debug", skip(self, hir_bounds, bounds))]
|
||||||
#[instrument(level = "debug", skip(self, ast_bounds, bounds))]
|
pub(crate) fn lower_poly_bounds<'hir, I: Iterator<Item = &'hir hir::GenericBound<'tcx>>>(
|
||||||
pub(crate) fn add_bounds<'hir, I: Iterator<Item = &'hir hir::GenericBound<'tcx>>>(
|
|
||||||
&self,
|
&self,
|
||||||
param_ty: Ty<'tcx>,
|
param_ty: Ty<'tcx>,
|
||||||
ast_bounds: I,
|
hir_bounds: I,
|
||||||
bounds: &mut Bounds<'tcx>,
|
bounds: &mut Bounds<'tcx>,
|
||||||
bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
|
bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
|
||||||
only_self_bounds: OnlySelfBounds,
|
only_self_bounds: OnlySelfBounds,
|
||||||
) where
|
) where
|
||||||
'tcx: 'hir,
|
'tcx: 'hir,
|
||||||
{
|
{
|
||||||
for ast_bound in ast_bounds {
|
for hir_bound in hir_bounds {
|
||||||
match ast_bound {
|
match hir_bound {
|
||||||
hir::GenericBound::Trait(poly_trait_ref, modifier) => {
|
hir::GenericBound::Trait(poly_trait_ref, modifier) => {
|
||||||
let (constness, polarity) = match modifier {
|
let (constness, polarity) = match modifier {
|
||||||
hir::TraitBoundModifier::Const => {
|
hir::TraitBoundModifier::Const => {
|
||||||
@ -145,7 +153,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
}
|
}
|
||||||
hir::TraitBoundModifier::Maybe => continue,
|
hir::TraitBoundModifier::Maybe => continue,
|
||||||
};
|
};
|
||||||
let _ = self.instantiate_poly_trait_ref(
|
let _ = self.lower_poly_trait_ref(
|
||||||
&poly_trait_ref.trait_ref,
|
&poly_trait_ref.trait_ref,
|
||||||
poly_trait_ref.span,
|
poly_trait_ref.span,
|
||||||
constness,
|
constness,
|
||||||
@ -156,7 +164,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
hir::GenericBound::Outlives(lifetime) => {
|
hir::GenericBound::Outlives(lifetime) => {
|
||||||
let region = self.ast_region_to_region(lifetime, None);
|
let region = self.lower_lifetime(lifetime, None);
|
||||||
bounds.push_region_bound(
|
bounds.push_region_bound(
|
||||||
self.tcx(),
|
self.tcx(),
|
||||||
ty::Binder::bind_with_vars(
|
ty::Binder::bind_with_vars(
|
||||||
@ -170,26 +178,19 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Translates a list of bounds from the HIR into the `Bounds` data structure.
|
/// Lower HIR bounds into `bounds` given the self type `param_ty` and *no* overarching late-bound vars.
|
||||||
/// The self-type for the bounds is given by `param_ty`.
|
|
||||||
///
|
///
|
||||||
/// Example:
|
/// ### Example
|
||||||
///
|
///
|
||||||
/// ```ignore (illustrative)
|
/// ```ignore (illustrative)
|
||||||
/// fn foo<T: Bar + Baz>() { }
|
/// fn foo<T: Bar + Baz>() { }
|
||||||
/// // ^ ^^^^^^^^^ ast_bounds
|
/// // ^ ^^^^^^^^^ hir_bounds
|
||||||
/// // param_ty
|
/// // param_ty
|
||||||
/// ```
|
/// ```
|
||||||
///
|
pub(crate) fn lower_mono_bounds(
|
||||||
/// The `sized_by_default` parameter indicates if, in this context, the `param_ty` should be
|
|
||||||
/// considered `Sized` unless there is an explicit `?Sized` bound. This would be true in the
|
|
||||||
/// example above, but is not true in supertrait listings like `trait Foo: Bar + Baz`.
|
|
||||||
///
|
|
||||||
/// `span` should be the declaration size of the parameter.
|
|
||||||
pub(crate) fn compute_bounds(
|
|
||||||
&self,
|
&self,
|
||||||
param_ty: Ty<'tcx>,
|
param_ty: Ty<'tcx>,
|
||||||
ast_bounds: &[hir::GenericBound<'tcx>],
|
hir_bounds: &[hir::GenericBound<'tcx>],
|
||||||
filter: PredicateFilter,
|
filter: PredicateFilter,
|
||||||
) -> Bounds<'tcx> {
|
) -> Bounds<'tcx> {
|
||||||
let mut bounds = Bounds::default();
|
let mut bounds = Bounds::default();
|
||||||
@ -201,9 +202,9 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => OnlySelfBounds(true),
|
PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => OnlySelfBounds(true),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.add_bounds(
|
self.lower_poly_bounds(
|
||||||
param_ty,
|
param_ty,
|
||||||
ast_bounds.iter().filter(|bound| match filter {
|
hir_bounds.iter().filter(|bound| match filter {
|
||||||
PredicateFilter::All
|
PredicateFilter::All
|
||||||
| PredicateFilter::SelfOnly
|
| PredicateFilter::SelfOnly
|
||||||
| PredicateFilter::SelfAndAssociatedTypeBounds => true,
|
| PredicateFilter::SelfAndAssociatedTypeBounds => true,
|
||||||
@ -227,14 +228,16 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
bounds
|
bounds
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given an HIR binding like `Item = Foo` or `Item: Foo`, pushes the corresponding predicates
|
/// Lower an associated item binding from HIR into `bounds`.
|
||||||
/// onto `bounds`.
|
|
||||||
///
|
///
|
||||||
/// **A note on binders:** given something like `T: for<'a> Iterator<Item = &'a u32>`, the
|
/// ### A Note on Binders
|
||||||
/// `trait_ref` here will be `for<'a> T: Iterator`. The `binding` data however is from *inside*
|
///
|
||||||
/// the binder (e.g., `&'a u32`) and hence may reference bound regions.
|
/// Given something like `T: for<'a> Iterator<Item = &'a u32>`,
|
||||||
|
/// the `trait_ref` here will be `for<'a> T: Iterator`.
|
||||||
|
/// The `binding` data however is from *inside* the binder
|
||||||
|
/// (e.g., `&'a u32`) and hence may reference bound regions.
|
||||||
#[instrument(level = "debug", skip(self, bounds, dup_bindings, path_span))]
|
#[instrument(level = "debug", skip(self, bounds, dup_bindings, path_span))]
|
||||||
pub(super) fn add_predicates_for_ast_type_binding(
|
pub(super) fn lower_assoc_item_binding(
|
||||||
&self,
|
&self,
|
||||||
hir_ref_id: hir::HirId,
|
hir_ref_id: hir::HirId,
|
||||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||||
@ -244,22 +247,6 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
path_span: Span,
|
path_span: Span,
|
||||||
only_self_bounds: OnlySelfBounds,
|
only_self_bounds: OnlySelfBounds,
|
||||||
) -> Result<(), ErrorGuaranteed> {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
// Given something like `U: SomeTrait<T = X>`, we want to produce a
|
|
||||||
// predicate like `<U as SomeTrait>::T = X`. This is somewhat
|
|
||||||
// subtle in the event that `T` is defined in a supertrait of
|
|
||||||
// `SomeTrait`, because in that case we need to upcast.
|
|
||||||
//
|
|
||||||
// That is, consider this case:
|
|
||||||
//
|
|
||||||
// ```
|
|
||||||
// trait SubTrait: SuperTrait<i32> { }
|
|
||||||
// trait SuperTrait<A> { type T; }
|
|
||||||
//
|
|
||||||
// ... B: SubTrait<T = foo> ...
|
|
||||||
// ```
|
|
||||||
//
|
|
||||||
// We want to produce `<B as SuperTrait<i32>>::T == foo`.
|
|
||||||
|
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
|
||||||
let assoc_kind = if binding.gen_args.parenthesized
|
let assoc_kind = if binding.gen_args.parenthesized
|
||||||
@ -272,7 +259,15 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
ty::AssocKind::Type
|
ty::AssocKind::Type
|
||||||
};
|
};
|
||||||
|
|
||||||
let candidate = if self.trait_defines_associated_item_named(
|
// Given something like `U: Trait<T = X>`, we want to produce a predicate like
|
||||||
|
// `<U as Trait>::T = X`.
|
||||||
|
// This is somewhat subtle in the event that `T` is defined in a supertrait of `Trait`,
|
||||||
|
// because in that case we need to upcast. I.e., we want to produce
|
||||||
|
// `<B as SuperTrait<i32>>::T == X` for `B: SubTrait<T = X>` where
|
||||||
|
//
|
||||||
|
// trait SubTrait: SuperTrait<i32> {}
|
||||||
|
// trait SuperTrait<A> { type T; }
|
||||||
|
let candidate = if self.probe_trait_that_defines_assoc_item(
|
||||||
trait_ref.def_id(),
|
trait_ref.def_id(),
|
||||||
assoc_kind,
|
assoc_kind,
|
||||||
binding.ident,
|
binding.ident,
|
||||||
@ -282,7 +277,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
} else {
|
} else {
|
||||||
// Otherwise, we have to walk through the supertraits to find
|
// Otherwise, we have to walk through the supertraits to find
|
||||||
// one that does define it.
|
// one that does define it.
|
||||||
self.one_bound_for_assoc_item(
|
self.probe_single_bound_for_assoc_item(
|
||||||
|| traits::supertraits(tcx, trait_ref),
|
|| traits::supertraits(tcx, trait_ref),
|
||||||
trait_ref.skip_binder().print_only_trait_name(),
|
trait_ref.skip_binder().print_only_trait_name(),
|
||||||
None,
|
None,
|
||||||
@ -417,7 +412,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
infer_args: false,
|
infer_args: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let alias_args = self.create_args_for_associated_item(
|
let alias_args = self.lower_generic_args_of_assoc_item(
|
||||||
path_span,
|
path_span,
|
||||||
assoc_item.def_id,
|
assoc_item.def_id,
|
||||||
&item_segment,
|
&item_segment,
|
||||||
@ -449,9 +444,11 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
span: binding.span,
|
span: binding.span,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
// Lower an equality constraint like `Item = u32` as found in HIR bound `T: Iterator<Item = u32>`
|
||||||
|
// to a projection predicate: `<T as Iterator>::Item = u32`.
|
||||||
hir::TypeBindingKind::Equality { term } => {
|
hir::TypeBindingKind::Equality { term } => {
|
||||||
let term = match term {
|
let term = match term {
|
||||||
hir::Term::Ty(ty) => self.ast_ty_to_ty(ty).into(),
|
hir::Term::Ty(ty) => self.lower_ty(ty).into(),
|
||||||
hir::Term::Const(ct) => ty::Const::from_anon_const(tcx, ct.def_id).into(),
|
hir::Term::Const(ct) => ty::Const::from_anon_const(tcx, ct.def_id).into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -490,10 +487,6 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// "Desugar" a constraint like `T: Iterator<Item = u32>` this to
|
|
||||||
// the "projection predicate" for:
|
|
||||||
//
|
|
||||||
// `<T as Iterator>::Item = u32`
|
|
||||||
bounds.push_projection_bound(
|
bounds.push_projection_bound(
|
||||||
tcx,
|
tcx,
|
||||||
projection_ty
|
projection_ty
|
||||||
@ -501,22 +494,18 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
binding.span,
|
binding.span,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
hir::TypeBindingKind::Constraint { bounds: ast_bounds } => {
|
// Lower a constraint like `Item: Debug` as found in HIR bound `T: Iterator<Item: Debug>`
|
||||||
// "Desugar" a constraint like `T: Iterator<Item: Debug>` to
|
// to a bound involving a projection: `<T as Iterator>::Item: Debug`.
|
||||||
//
|
hir::TypeBindingKind::Constraint { bounds: hir_bounds } => {
|
||||||
// `<T as Iterator>::Item: Debug`
|
// NOTE: If `only_self_bounds` is true, do NOT expand this associated type bound into
|
||||||
//
|
// a trait predicate, since we only want to add predicates for the `Self` type.
|
||||||
// Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty`
|
|
||||||
// parameter to have a skipped binder.
|
|
||||||
//
|
|
||||||
// NOTE: If `only_self_bounds` is true, do NOT expand this associated
|
|
||||||
// type bound into a trait predicate, since we only want to add predicates
|
|
||||||
// for the `Self` type.
|
|
||||||
if !only_self_bounds.0 {
|
if !only_self_bounds.0 {
|
||||||
|
// Calling `skip_binder` is okay, because `lower_bounds` expects the `param_ty`
|
||||||
|
// parameter to have a skipped binder.
|
||||||
let param_ty = Ty::new_alias(tcx, ty::Projection, projection_ty.skip_binder());
|
let param_ty = Ty::new_alias(tcx, ty::Projection, projection_ty.skip_binder());
|
||||||
self.add_bounds(
|
self.lower_poly_bounds(
|
||||||
param_ty,
|
param_ty,
|
||||||
ast_bounds.iter(),
|
hir_bounds.iter(),
|
||||||
bounds,
|
bounds,
|
||||||
projection_ty.bound_vars(),
|
projection_ty.bound_vars(),
|
||||||
only_self_bounds,
|
only_self_bounds,
|
@ -1,9 +1,9 @@
|
|||||||
use crate::astconv::AstConv;
|
|
||||||
use crate::errors::{
|
use crate::errors::{
|
||||||
self, AssocTypeBindingNotAllowed, ManualImplementation, MissingTypeParams,
|
self, AssocTypeBindingNotAllowed, ManualImplementation, MissingTypeParams,
|
||||||
ParenthesizedFnTraitExpansion,
|
ParenthesizedFnTraitExpansion,
|
||||||
};
|
};
|
||||||
use crate::fluent_generated as fluent;
|
use crate::fluent_generated as fluent;
|
||||||
|
use crate::hir_ty_lowering::HirTyLowerer;
|
||||||
use crate::traits::error_reporting::report_object_safety_error;
|
use crate::traits::error_reporting::report_object_safety_error;
|
||||||
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
|
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
|
||||||
use rustc_data_structures::sorted_map::SortedMap;
|
use rustc_data_structures::sorted_map::SortedMap;
|
||||||
@ -22,7 +22,7 @@ use rustc_span::symbol::{sym, Ident};
|
|||||||
use rustc_span::{Span, Symbol, DUMMY_SP};
|
use rustc_span::{Span, Symbol, DUMMY_SP};
|
||||||
use rustc_trait_selection::traits::object_safety_violations_for_assoc_item;
|
use rustc_trait_selection::traits::object_safety_violations_for_assoc_item;
|
||||||
|
|
||||||
impl<'tcx> dyn AstConv<'tcx> + '_ {
|
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
/// On missing type parameters, emit an E0393 error and provide a structured suggestion using
|
/// On missing type parameters, emit an E0393 error and provide a structured suggestion using
|
||||||
/// the type parameter's name as a placeholder.
|
/// the type parameter's name as a placeholder.
|
||||||
pub(crate) fn complain_about_missing_type_params(
|
pub(crate) fn complain_about_missing_type_params(
|
||||||
@ -311,7 +311,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
// FIXME(associated_const_equality): This has quite a few false positives and negatives.
|
// FIXME(associated_const_equality): This has quite a few false positives and negatives.
|
||||||
let wrap_in_braces_sugg = if let Some(binding) = binding
|
let wrap_in_braces_sugg = if let Some(binding) = binding
|
||||||
&& let hir::TypeBindingKind::Equality { term: hir::Term::Ty(hir_ty) } = binding.kind
|
&& let hir::TypeBindingKind::Equality { term: hir::Term::Ty(hir_ty) } = binding.kind
|
||||||
&& let ty = self.ast_ty_to_ty(hir_ty)
|
&& let ty = self.lower_ty(hir_ty)
|
||||||
&& (ty.is_enum() || ty.references_error())
|
&& (ty.is_enum() || ty.references_error())
|
||||||
&& tcx.features().associated_const_equality
|
&& tcx.features().associated_const_equality
|
||||||
{
|
{
|
||||||
@ -349,7 +349,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn report_ambiguous_associated_type(
|
pub(super) fn report_ambiguous_assoc_ty(
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
types: &[String],
|
types: &[String],
|
||||||
@ -458,7 +458,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
reported
|
reported
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn complain_about_ambiguous_inherent_assoc_type(
|
pub(crate) fn complain_about_ambiguous_inherent_assoc_ty(
|
||||||
&self,
|
&self,
|
||||||
name: Ident,
|
name: Ident,
|
||||||
candidates: Vec<DefId>,
|
candidates: Vec<DefId>,
|
||||||
@ -471,14 +471,14 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
"multiple applicable items in scope"
|
"multiple applicable items in scope"
|
||||||
);
|
);
|
||||||
err.span_label(name.span, format!("multiple `{name}` found"));
|
err.span_label(name.span, format!("multiple `{name}` found"));
|
||||||
self.note_ambiguous_inherent_assoc_type(&mut err, candidates, span);
|
self.note_ambiguous_inherent_assoc_ty(&mut err, candidates, span);
|
||||||
let reported = err.emit();
|
let reported = err.emit();
|
||||||
self.set_tainted_by_errors(reported);
|
self.set_tainted_by_errors(reported);
|
||||||
reported
|
reported
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(fmease): Heavily adapted from `rustc_hir_typeck::method::suggest`. Deduplicate.
|
// FIXME(fmease): Heavily adapted from `rustc_hir_typeck::method::suggest`. Deduplicate.
|
||||||
fn note_ambiguous_inherent_assoc_type(
|
fn note_ambiguous_inherent_assoc_ty(
|
||||||
&self,
|
&self,
|
||||||
err: &mut Diag<'_>,
|
err: &mut Diag<'_>,
|
||||||
candidates: Vec<DefId>,
|
candidates: Vec<DefId>,
|
||||||
@ -521,7 +521,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(inherent_associated_types): Find similarly named associated types and suggest them.
|
// FIXME(inherent_associated_types): Find similarly named associated types and suggest them.
|
||||||
pub(crate) fn complain_about_inherent_assoc_type_not_found(
|
pub(crate) fn complain_about_inherent_assoc_ty_not_found(
|
||||||
&self,
|
&self,
|
||||||
name: Ident,
|
name: Ident,
|
||||||
self_ty: Ty<'tcx>,
|
self_ty: Ty<'tcx>,
|
||||||
@ -697,7 +697,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
/// reasonable suggestion on how to write it. For the case of multiple associated types in the
|
/// reasonable suggestion on how to write it. For the case of multiple associated types in the
|
||||||
/// same trait bound have the same name (as they come from different supertraits), we instead
|
/// same trait bound have the same name (as they come from different supertraits), we instead
|
||||||
/// emit a generic note suggesting using a `where` clause to constraint instead.
|
/// emit a generic note suggesting using a `where` clause to constraint instead.
|
||||||
pub(crate) fn complain_about_missing_associated_types(
|
pub(crate) fn complain_about_missing_assoc_tys(
|
||||||
&self,
|
&self,
|
||||||
associated_types: FxIndexMap<Span, FxIndexSet<DefId>>,
|
associated_types: FxIndexMap<Span, FxIndexSet<DefId>>,
|
||||||
potential_assoc_types: Vec<Span>,
|
potential_assoc_types: Vec<Span>,
|
||||||
@ -1027,7 +1027,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Emits an error regarding forbidden type binding associations
|
/// Emits an error regarding forbidden type binding associations
|
||||||
pub fn prohibit_assoc_ty_binding(
|
pub fn prohibit_assoc_item_binding(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
span: Span,
|
span: Span,
|
||||||
segment: Option<(&hir::PathSegment<'_>, Span)>,
|
segment: Option<(&hir::PathSegment<'_>, Span)>,
|
@ -1,7 +1,7 @@
|
|||||||
use super::IsMethodCall;
|
use super::IsMethodCall;
|
||||||
use crate::astconv::{
|
use crate::hir_ty_lowering::{
|
||||||
errors::prohibit_assoc_ty_binding, CreateInstantiationsForGenericArgsCtxt, ExplicitLateBound,
|
errors::prohibit_assoc_item_binding, ExplicitLateBound, GenericArgCountMismatch,
|
||||||
GenericArgCountMismatch, GenericArgCountResult, GenericArgPosition,
|
GenericArgCountResult, GenericArgPosition, GenericArgsLowerer,
|
||||||
};
|
};
|
||||||
use crate::structured_errors::{GenericArgsInfo, StructuredDiag, WrongNumberOfGenericArgs};
|
use crate::structured_errors::{GenericArgsInfo, StructuredDiag, WrongNumberOfGenericArgs};
|
||||||
use rustc_ast::ast::ParamKindOrd;
|
use rustc_ast::ast::ParamKindOrd;
|
||||||
@ -143,24 +143,22 @@ fn generic_arg_mismatch_err(
|
|||||||
err.emit()
|
err.emit()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates the relevant generic arguments
|
/// Lower generic arguments from the HIR to the [`rustc_middle::ty`] representation.
|
||||||
/// corresponding to a set of generic parameters. This is a
|
///
|
||||||
/// rather complex function. Let us try to explain the role
|
/// This is a rather complex function. Let us try to explain the role
|
||||||
/// of each of its parameters:
|
/// of each of its parameters:
|
||||||
///
|
///
|
||||||
/// To start, we are given the `def_id` of the thing whose generic
|
/// To start, we are given the `def_id` of the thing whose generic parameters we
|
||||||
/// parameters we are instantiating, and a partial set of
|
/// are creating, and a partial set of arguments `parent_args`. In general,
|
||||||
/// arguments `parent_args`. In general, the generic arguments
|
/// the generic arguments for an item begin with arguments for all the "parents"
|
||||||
/// for an item begin with arguments for all the "parents" of
|
/// of that item -- e.g., for a method it might include the parameters from the impl.
|
||||||
/// that item -- e.g., for a method it might include the
|
|
||||||
/// parameters from the impl.
|
|
||||||
///
|
///
|
||||||
/// Therefore, the method begins by walking down these parents,
|
/// Therefore, the method begins by walking down these parents,
|
||||||
/// starting with the outermost parent and proceed inwards until
|
/// starting with the outermost parent and proceed inwards until
|
||||||
/// it reaches `def_id`. For each parent `P`, it will check `parent_args`
|
/// it reaches `def_id`. For each parent `P`, it will check `parent_args`
|
||||||
/// first to see if the parent's arguments are listed in there. If so,
|
/// first to see if the parent's arguments are listed in there. If so,
|
||||||
/// we can append those and move on. Otherwise, it invokes the
|
/// we can append those and move on. Otherwise, it uses the provided
|
||||||
/// three callback functions:
|
/// [`GenericArgsLowerer`] `ctx` which has the following methods:
|
||||||
///
|
///
|
||||||
/// - `args_for_def_id`: given the `DefId` `P`, supplies back the
|
/// - `args_for_def_id`: given the `DefId` `P`, supplies back the
|
||||||
/// generic arguments that were given to that parent from within
|
/// generic arguments that were given to that parent from within
|
||||||
@ -168,18 +166,18 @@ fn generic_arg_mismatch_err(
|
|||||||
/// might refer to the trait `Foo`, and the arguments might be
|
/// might refer to the trait `Foo`, and the arguments might be
|
||||||
/// `[T]`. The boolean value indicates whether to infer values
|
/// `[T]`. The boolean value indicates whether to infer values
|
||||||
/// for arguments whose values were not explicitly provided.
|
/// for arguments whose values were not explicitly provided.
|
||||||
/// - `provided_kind`: given the generic parameter and the value from `args_for_def_id`,
|
/// - `provided_kind`: given the generic parameter and the value
|
||||||
/// instantiate a `GenericArg`.
|
/// from `args_for_def_id`, creating a `GenericArg`.
|
||||||
/// - `inferred_kind`: if no parameter was provided, and inference is enabled, then
|
/// - `inferred_kind`: if no parameter was provided, and inference
|
||||||
/// creates a suitable inference variable.
|
/// is enabled, then creates a suitable inference variable.
|
||||||
pub fn create_args_for_parent_generic_args<'tcx: 'a, 'a>(
|
pub fn lower_generic_args<'tcx: 'a, 'a>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
parent_args: &[ty::GenericArg<'tcx>],
|
parent_args: &[ty::GenericArg<'tcx>],
|
||||||
has_self: bool,
|
has_self: bool,
|
||||||
self_ty: Option<Ty<'tcx>>,
|
self_ty: Option<Ty<'tcx>>,
|
||||||
arg_count: &GenericArgCountResult,
|
arg_count: &GenericArgCountResult,
|
||||||
ctx: &mut impl CreateInstantiationsForGenericArgsCtxt<'a, 'tcx>,
|
ctx: &mut impl GenericArgsLowerer<'a, 'tcx>,
|
||||||
) -> GenericArgsRef<'tcx> {
|
) -> GenericArgsRef<'tcx> {
|
||||||
// Collect the segments of the path; we need to instantiate arguments
|
// Collect the segments of the path; we need to instantiate arguments
|
||||||
// for parameters throughout the entire path (wherever there are
|
// for parameters throughout the entire path (wherever there are
|
||||||
@ -456,7 +454,7 @@ pub(crate) fn check_generic_arg_count(
|
|||||||
if gen_pos != GenericArgPosition::Type
|
if gen_pos != GenericArgPosition::Type
|
||||||
&& let Some(b) = gen_args.bindings.first()
|
&& let Some(b) = gen_args.bindings.first()
|
||||||
{
|
{
|
||||||
prohibit_assoc_ty_binding(tcx, b.span, None);
|
prohibit_assoc_item_binding(tcx, b.span, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let explicit_late_bound =
|
let explicit_late_bound =
|
@ -6,9 +6,9 @@ use rustc_lint_defs::{builtin::BARE_TRAIT_OBJECTS, Applicability};
|
|||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName;
|
use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName;
|
||||||
|
|
||||||
use super::AstConv;
|
use super::HirTyLowerer;
|
||||||
|
|
||||||
impl<'tcx> dyn AstConv<'tcx> + '_ {
|
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
/// Make sure that we are in the condition to suggest the blanket implementation.
|
/// Make sure that we are in the condition to suggest the blanket implementation.
|
||||||
pub(super) fn maybe_lint_blanket_trait_impl<G: EmissionGuarantee>(
|
pub(super) fn maybe_lint_blanket_trait_impl<G: EmissionGuarantee>(
|
||||||
&self,
|
&self,
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
use crate::astconv::{GenericArgCountMismatch, GenericArgCountResult, OnlySelfBounds};
|
|
||||||
use crate::bounds::Bounds;
|
use crate::bounds::Bounds;
|
||||||
use crate::errors::TraitObjectDeclaredWithNoTraits;
|
use crate::errors::TraitObjectDeclaredWithNoTraits;
|
||||||
|
use crate::hir_ty_lowering::{GenericArgCountMismatch, GenericArgCountResult, OnlySelfBounds};
|
||||||
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
|
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
|
||||||
use rustc_errors::{codes::*, struct_span_code_err};
|
use rustc_errors::{codes::*, struct_span_code_err};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
@ -11,14 +11,16 @@ use rustc_middle::ty::{self, Ty};
|
|||||||
use rustc_middle::ty::{DynKind, ToPredicate};
|
use rustc_middle::ty::{DynKind, ToPredicate};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::traits::error_reporting::report_object_safety_error;
|
use rustc_trait_selection::traits::error_reporting::report_object_safety_error;
|
||||||
use rustc_trait_selection::traits::{self, astconv_object_safety_violations};
|
use rustc_trait_selection::traits::{self, hir_ty_lowering_object_safety_violations};
|
||||||
|
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
|
|
||||||
use super::AstConv;
|
use super::HirTyLowerer;
|
||||||
|
|
||||||
impl<'tcx> dyn AstConv<'tcx> + '_ {
|
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
pub(super) fn conv_object_ty_poly_trait_ref(
|
/// Lower a trait object type from the HIR to our internal notion of a type.
|
||||||
|
#[instrument(level = "debug", skip_all, ret)]
|
||||||
|
pub(super) fn lower_trait_object_ty(
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
hir_id: hir::HirId,
|
hir_id: hir::HirId,
|
||||||
@ -37,7 +39,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
correct:
|
correct:
|
||||||
Err(GenericArgCountMismatch { invalid_args: cur_potential_assoc_types, .. }),
|
Err(GenericArgCountMismatch { invalid_args: cur_potential_assoc_types, .. }),
|
||||||
..
|
..
|
||||||
} = self.instantiate_poly_trait_ref(
|
} = self.lower_poly_trait_ref(
|
||||||
&trait_bound.trait_ref,
|
&trait_bound.trait_ref,
|
||||||
trait_bound.span,
|
trait_bound.span,
|
||||||
ty::BoundConstness::NotConst,
|
ty::BoundConstness::NotConst,
|
||||||
@ -133,7 +135,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
// to avoid ICEs.
|
// to avoid ICEs.
|
||||||
for item in ®ular_traits {
|
for item in ®ular_traits {
|
||||||
let object_safety_violations =
|
let object_safety_violations =
|
||||||
astconv_object_safety_violations(tcx, item.trait_ref().def_id());
|
hir_ty_lowering_object_safety_violations(tcx, item.trait_ref().def_id());
|
||||||
if !object_safety_violations.is_empty() {
|
if !object_safety_violations.is_empty() {
|
||||||
let reported = report_object_safety_error(
|
let reported = report_object_safety_error(
|
||||||
tcx,
|
tcx,
|
||||||
@ -156,7 +158,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
for (base_trait_ref, span) in regular_traits_refs_spans {
|
for (base_trait_ref, span) in regular_traits_refs_spans {
|
||||||
let base_pred: ty::Predicate<'tcx> = base_trait_ref.to_predicate(tcx);
|
let base_pred: ty::Predicate<'tcx> = base_trait_ref.to_predicate(tcx);
|
||||||
for pred in traits::elaborate(tcx, [base_pred]).filter_only_self() {
|
for pred in traits::elaborate(tcx, [base_pred]).filter_only_self() {
|
||||||
debug!("conv_object_ty_poly_trait_ref: observing object predicate `{:?}`", pred);
|
debug!("observing object predicate `{pred:?}`");
|
||||||
|
|
||||||
let bound_predicate = pred.kind();
|
let bound_predicate = pred.kind();
|
||||||
match bound_predicate.skip_binder() {
|
match bound_predicate.skip_binder() {
|
||||||
@ -231,7 +233,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
def_ids.retain(|def_id| !tcx.generics_require_sized_self(def_id));
|
def_ids.retain(|def_id| !tcx.generics_require_sized_self(def_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.complain_about_missing_associated_types(
|
self.complain_about_missing_assoc_tys(
|
||||||
associated_types,
|
associated_types,
|
||||||
potential_assoc_types,
|
potential_assoc_types,
|
||||||
hir_trait_bounds,
|
hir_trait_bounds,
|
||||||
@ -243,8 +245,8 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
// the bounds
|
// the bounds
|
||||||
let mut duplicates = FxHashSet::default();
|
let mut duplicates = FxHashSet::default();
|
||||||
auto_traits.retain(|i| duplicates.insert(i.trait_ref().def_id()));
|
auto_traits.retain(|i| duplicates.insert(i.trait_ref().def_id()));
|
||||||
debug!("regular_traits: {:?}", regular_traits);
|
debug!(?regular_traits);
|
||||||
debug!("auto_traits: {:?}", auto_traits);
|
debug!(?auto_traits);
|
||||||
|
|
||||||
// Erase the `dummy_self` (`trait_object_dummy_self`) used above.
|
// Erase the `dummy_self` (`trait_object_dummy_self`) used above.
|
||||||
let existential_trait_refs = regular_traits.iter().map(|i| {
|
let existential_trait_refs = regular_traits.iter().map(|i| {
|
||||||
@ -362,11 +364,11 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
|
|
||||||
// Use explicitly-specified region bound.
|
// Use explicitly-specified region bound.
|
||||||
let region_bound = if !lifetime.is_elided() {
|
let region_bound = if !lifetime.is_elided() {
|
||||||
self.ast_region_to_region(lifetime, None)
|
self.lower_lifetime(lifetime, None)
|
||||||
} else {
|
} else {
|
||||||
self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| {
|
self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| {
|
||||||
if tcx.named_bound_var(lifetime.hir_id).is_some() {
|
if tcx.named_bound_var(lifetime.hir_id).is_some() {
|
||||||
self.ast_region_to_region(lifetime, None)
|
self.lower_lifetime(lifetime, None)
|
||||||
} else {
|
} else {
|
||||||
self.re_infer(None, span).unwrap_or_else(|| {
|
self.re_infer(None, span).unwrap_or_else(|| {
|
||||||
let err = struct_span_code_err!(
|
let err = struct_span_code_err!(
|
||||||
@ -389,10 +391,8 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
debug!("region_bound: {:?}", region_bound);
|
debug!(?region_bound);
|
||||||
|
|
||||||
let ty = Ty::new_dynamic(tcx, existential_predicates, region_bound, representation);
|
Ty::new_dynamic(tcx, existential_predicates, region_bound, representation)
|
||||||
debug!("trait_object_type: {:?}", ty);
|
|
||||||
ty
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -68,7 +68,7 @@ fn diagnostic_hir_wf_check<'tcx>(
|
|||||||
let infcx = self.tcx.infer_ctxt().build();
|
let infcx = self.tcx.infer_ctxt().build();
|
||||||
let ocx = ObligationCtxt::new(&infcx);
|
let ocx = ObligationCtxt::new(&infcx);
|
||||||
|
|
||||||
let tcx_ty = self.icx.to_ty(ty);
|
let tcx_ty = self.icx.lower_ty(ty);
|
||||||
// This visitor can walk into binders, resulting in the `tcx_ty` to
|
// This visitor can walk into binders, resulting in the `tcx_ty` to
|
||||||
// potentially reference escaping bound variables. We simply erase
|
// potentially reference escaping bound variables. We simply erase
|
||||||
// those here.
|
// those here.
|
||||||
|
@ -30,8 +30,8 @@ several major phases:
|
|||||||
The type checker is defined into various submodules which are documented
|
The type checker is defined into various submodules which are documented
|
||||||
independently:
|
independently:
|
||||||
|
|
||||||
- astconv: converts the AST representation of types
|
- hir_ty_lowering: lowers type-system entities from the [HIR][hir] to the
|
||||||
into the `ty` representation.
|
[`rustc_middle::ty`] representation.
|
||||||
|
|
||||||
- collect: computes the types of each top-level item and enters them into
|
- collect: computes the types of each top-level item and enters them into
|
||||||
the `tcx.types` table for later use.
|
the `tcx.types` table for later use.
|
||||||
@ -82,11 +82,11 @@ extern crate rustc_middle;
|
|||||||
// These are used by Clippy.
|
// These are used by Clippy.
|
||||||
pub mod check;
|
pub mod check;
|
||||||
|
|
||||||
pub mod astconv;
|
|
||||||
pub mod autoderef;
|
pub mod autoderef;
|
||||||
mod bounds;
|
mod bounds;
|
||||||
mod check_unused;
|
mod check_unused;
|
||||||
mod coherence;
|
mod coherence;
|
||||||
|
pub mod hir_ty_lowering;
|
||||||
// FIXME: This module shouldn't be public.
|
// FIXME: This module shouldn't be public.
|
||||||
pub mod collect;
|
pub mod collect;
|
||||||
mod constrained_generic_params;
|
mod constrained_generic_params;
|
||||||
@ -211,12 +211,20 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A quasi-deprecated helper used in rustdoc and clippy to get
|
/// Lower a [`hir::Ty`] to a [`Ty`].
|
||||||
/// the type from a HIR node.
|
///
|
||||||
pub fn hir_ty_to_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
|
/// <div class="warning">
|
||||||
|
///
|
||||||
|
/// This function is **quasi-deprecated**. It can cause ICEs if called inside of a body
|
||||||
|
/// (of a function or constant) and especially if it contains inferred types (`_`).
|
||||||
|
///
|
||||||
|
/// It's used in rustdoc and Clippy.
|
||||||
|
///
|
||||||
|
/// </div>
|
||||||
|
pub fn lower_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
|
||||||
// In case there are any projections, etc., find the "environment"
|
// In case there are any projections, etc., find the "environment"
|
||||||
// def-ID that will be used to determine the traits/predicates in
|
// def-ID that will be used to determine the traits/predicates in
|
||||||
// scope. This is derived from the enclosing item-like thing.
|
// scope. This is derived from the enclosing item-like thing.
|
||||||
let env_def_id = tcx.hir().get_parent_item(hir_ty.hir_id);
|
let env_def_id = tcx.hir().get_parent_item(hir_ty.hir_id);
|
||||||
collect::ItemCtxt::new(tcx, env_def_id.def_id).to_ty(hir_ty)
|
collect::ItemCtxt::new(tcx, env_def_id.def_id).lower_ty(hir_ty)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//! Constraint construction and representation
|
//! Constraint construction and representation
|
||||||
//!
|
//!
|
||||||
//! The second pass over the AST determines the set of constraints.
|
//! The second pass over the HIR determines the set of constraints.
|
||||||
//! We walk the set of items and, for each member, generate new constraints.
|
//! We walk the set of items and, for each member, generate new constraints.
|
||||||
|
|
||||||
use hir::def_id::{DefId, LocalDefId};
|
use hir::def_id::{DefId, LocalDefId};
|
||||||
|
@ -5,7 +5,7 @@ use super::{check_fn, CoroutineTypes, Expectation, FnCtxt};
|
|||||||
use rustc_errors::ErrorGuaranteed;
|
use rustc_errors::ErrorGuaranteed;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::lang_items::LangItem;
|
use rustc_hir::lang_items::LangItem;
|
||||||
use rustc_hir_analysis::astconv::AstConv;
|
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
|
||||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||||
use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes};
|
use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes};
|
||||||
use rustc_infer::infer::{InferOk, InferResult};
|
use rustc_infer::infer::{InferOk, InferResult};
|
||||||
@ -784,7 +784,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
decl: &hir::FnDecl<'tcx>,
|
decl: &hir::FnDecl<'tcx>,
|
||||||
closure_kind: hir::ClosureKind,
|
closure_kind: hir::ClosureKind,
|
||||||
) -> ty::PolyFnSig<'tcx> {
|
) -> ty::PolyFnSig<'tcx> {
|
||||||
let astconv = self.astconv();
|
let lowerer = self.lowerer();
|
||||||
|
|
||||||
trace!("decl = {:#?}", decl);
|
trace!("decl = {:#?}", decl);
|
||||||
debug!(?closure_kind);
|
debug!(?closure_kind);
|
||||||
@ -793,9 +793,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
let bound_vars = self.tcx.late_bound_vars(hir_id);
|
let bound_vars = self.tcx.late_bound_vars(hir_id);
|
||||||
|
|
||||||
// First, convert the types that the user supplied (if any).
|
// First, convert the types that the user supplied (if any).
|
||||||
let supplied_arguments = decl.inputs.iter().map(|a| astconv.ast_ty_to_ty(a));
|
let supplied_arguments = decl.inputs.iter().map(|a| lowerer.lower_ty(a));
|
||||||
let supplied_return = match decl.output {
|
let supplied_return = match decl.output {
|
||||||
hir::FnRetTy::Return(ref output) => astconv.ast_ty_to_ty(output),
|
hir::FnRetTy::Return(ref output) => lowerer.lower_ty(output),
|
||||||
hir::FnRetTy::DefaultReturn(_) => match closure_kind {
|
hir::FnRetTy::DefaultReturn(_) => match closure_kind {
|
||||||
// In the case of the async block that we create for a function body,
|
// In the case of the async block that we create for a function body,
|
||||||
// we expect the return type of the block to match that of the enclosing
|
// we expect the return type of the block to match that of the enclosing
|
||||||
@ -813,7 +813,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
// easily (and locally) prove that we
|
// easily (and locally) prove that we
|
||||||
// *have* reported an
|
// *have* reported an
|
||||||
// error. --nikomatsakis
|
// error. --nikomatsakis
|
||||||
astconv.ty_infer(None, decl.output.span())
|
lowerer.ty_infer(None, decl.output.span())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// All `gen {}` and `async gen {}` must return unit.
|
// All `gen {}` and `async gen {}` must return unit.
|
||||||
@ -832,7 +832,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
| hir::ClosureKind::Coroutine(hir::CoroutineKind::Coroutine(_))
|
| hir::ClosureKind::Coroutine(hir::CoroutineKind::Coroutine(_))
|
||||||
| hir::ClosureKind::Closure
|
| hir::ClosureKind::Closure
|
||||||
| hir::ClosureKind::CoroutineClosure(_) => {
|
| hir::ClosureKind::CoroutineClosure(_) => {
|
||||||
astconv.ty_infer(None, decl.output.span())
|
lowerer.ty_infer(None, decl.output.span())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -989,17 +989,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
decl: &hir::FnDecl<'tcx>,
|
decl: &hir::FnDecl<'tcx>,
|
||||||
guar: ErrorGuaranteed,
|
guar: ErrorGuaranteed,
|
||||||
) -> ty::PolyFnSig<'tcx> {
|
) -> ty::PolyFnSig<'tcx> {
|
||||||
let astconv = self.astconv();
|
let lowerer = self.lowerer();
|
||||||
let err_ty = Ty::new_error(self.tcx, guar);
|
let err_ty = Ty::new_error(self.tcx, guar);
|
||||||
|
|
||||||
let supplied_arguments = decl.inputs.iter().map(|a| {
|
let supplied_arguments = decl.inputs.iter().map(|a| {
|
||||||
// Convert the types that the user supplied (if any), but ignore them.
|
// Convert the types that the user supplied (if any), but ignore them.
|
||||||
astconv.ast_ty_to_ty(a);
|
lowerer.lower_ty(a);
|
||||||
err_ty
|
err_ty
|
||||||
});
|
});
|
||||||
|
|
||||||
if let hir::FnRetTy::Return(ref output) = decl.output {
|
if let hir::FnRetTy::Return(ref output) = decl.output {
|
||||||
astconv.ast_ty_to_ty(output);
|
lowerer.lower_ty(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = ty::Binder::dummy(self.tcx.mk_fn_sig(
|
let result = ty::Binder::dummy(self.tcx.mk_fn_sig(
|
||||||
|
@ -41,7 +41,7 @@ use rustc_hir as hir;
|
|||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::intravisit::{self, Visitor};
|
use rustc_hir::intravisit::{self, Visitor};
|
||||||
use rustc_hir::Expr;
|
use rustc_hir::Expr;
|
||||||
use rustc_hir_analysis::astconv::AstConv;
|
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
|
||||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||||
use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult};
|
use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult};
|
||||||
use rustc_infer::traits::TraitEngine;
|
use rustc_infer::traits::TraitEngine;
|
||||||
|
@ -35,8 +35,8 @@ use rustc_hir::def_id::DefId;
|
|||||||
use rustc_hir::intravisit::Visitor;
|
use rustc_hir::intravisit::Visitor;
|
||||||
use rustc_hir::lang_items::LangItem;
|
use rustc_hir::lang_items::LangItem;
|
||||||
use rustc_hir::{ExprKind, HirId, QPath};
|
use rustc_hir::{ExprKind, HirId, QPath};
|
||||||
use rustc_hir_analysis::astconv::AstConv as _;
|
|
||||||
use rustc_hir_analysis::check::ty_kind_suggestion;
|
use rustc_hir_analysis::check::ty_kind_suggestion;
|
||||||
|
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer as _;
|
||||||
use rustc_infer::infer;
|
use rustc_infer::infer;
|
||||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||||
use rustc_infer::infer::DefineOpaqueTypes;
|
use rustc_infer::infer::DefineOpaqueTypes;
|
||||||
@ -333,7 +333,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
ExprKind::Cast(e, t) => self.check_expr_cast(e, t, expr),
|
ExprKind::Cast(e, t) => self.check_expr_cast(e, t, expr),
|
||||||
ExprKind::Type(e, t) => {
|
ExprKind::Type(e, t) => {
|
||||||
let ascribed_ty = self.to_ty_saving_user_provided_ty(t);
|
let ascribed_ty = self.lower_ty_saving_user_provided_ty(t);
|
||||||
let ty = self.check_expr_with_hint(e, ascribed_ty);
|
let ty = self.check_expr_with_hint(e, ascribed_ty);
|
||||||
self.demand_eqtype(e.span, ascribed_ty, ty);
|
self.demand_eqtype(e.span, ascribed_ty, ty);
|
||||||
ascribed_ty
|
ascribed_ty
|
||||||
@ -1375,7 +1375,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
// Find the type of `e`. Supply hints based on the type we are casting to,
|
// Find the type of `e`. Supply hints based on the type we are casting to,
|
||||||
// if appropriate.
|
// if appropriate.
|
||||||
let t_cast = self.to_ty_saving_user_provided_ty(t);
|
let t_cast = self.lower_ty_saving_user_provided_ty(t);
|
||||||
let t_cast = self.resolve_vars_if_possible(t_cast);
|
let t_cast = self.resolve_vars_if_possible(t_cast);
|
||||||
let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
|
let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
|
||||||
let t_expr = self.resolve_vars_if_possible(t_expr);
|
let t_expr = self.resolve_vars_if_possible(t_expr);
|
||||||
@ -1503,7 +1503,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
expr: &'tcx hir::Expr<'tcx>,
|
expr: &'tcx hir::Expr<'tcx>,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let count = self.array_length_to_const(count);
|
let count = self.lower_array_length(count);
|
||||||
if let Some(count) = count.try_eval_target_usize(tcx, self.param_env) {
|
if let Some(count) = count.try_eval_target_usize(tcx, self.param_env) {
|
||||||
self.suggest_array_len(expr, count);
|
self.suggest_array_len(expr, count);
|
||||||
}
|
}
|
||||||
@ -1679,7 +1679,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
expr: &hir::Expr<'_>,
|
expr: &hir::Expr<'_>,
|
||||||
span: Span,
|
span: Span,
|
||||||
variant: &'tcx ty::VariantDef,
|
variant: &'tcx ty::VariantDef,
|
||||||
ast_fields: &'tcx [hir::ExprField<'tcx>],
|
hir_fields: &'tcx [hir::ExprField<'tcx>],
|
||||||
base_expr: &'tcx Option<&'tcx hir::Expr<'tcx>>,
|
base_expr: &'tcx Option<&'tcx hir::Expr<'tcx>>,
|
||||||
) {
|
) {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
@ -1710,7 +1710,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
let mut error_happened = false;
|
let mut error_happened = false;
|
||||||
|
|
||||||
// Type-check each field.
|
// Type-check each field.
|
||||||
for (idx, field) in ast_fields.iter().enumerate() {
|
for (idx, field) in hir_fields.iter().enumerate() {
|
||||||
let ident = tcx.adjust_ident(field.ident, variant.def_id);
|
let ident = tcx.adjust_ident(field.ident, variant.def_id);
|
||||||
let field_type = if let Some((i, v_field)) = remaining_fields.remove(&ident) {
|
let field_type = if let Some((i, v_field)) = remaining_fields.remove(&ident) {
|
||||||
seen_fields.insert(ident, field.span);
|
seen_fields.insert(ident, field.span);
|
||||||
@ -1739,7 +1739,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
variant,
|
variant,
|
||||||
expr,
|
expr,
|
||||||
field,
|
field,
|
||||||
ast_fields,
|
hir_fields,
|
||||||
adt.variant_descr(),
|
adt.variant_descr(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
@ -1754,7 +1754,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
self.demand_coerce_diag(field.expr, ty, field_type, None, AllowTwoPhase::No);
|
self.demand_coerce_diag(field.expr, ty, field_type, None, AllowTwoPhase::No);
|
||||||
|
|
||||||
if let Some(diag) = diag {
|
if let Some(diag) = diag {
|
||||||
if idx == ast_fields.len() - 1 {
|
if idx == hir_fields.len() - 1 {
|
||||||
if remaining_fields.is_empty() {
|
if remaining_fields.is_empty() {
|
||||||
self.suggest_fru_from_range_and_emit(field, variant, args, diag);
|
self.suggest_fru_from_range_and_emit(field, variant, args, diag);
|
||||||
} else {
|
} else {
|
||||||
@ -1768,7 +1768,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
// Make sure the programmer specified correct number of fields.
|
// Make sure the programmer specified correct number of fields.
|
||||||
if adt_kind == AdtKind::Union {
|
if adt_kind == AdtKind::Union {
|
||||||
if ast_fields.len() != 1 {
|
if hir_fields.len() != 1 {
|
||||||
struct_span_code_err!(
|
struct_span_code_err!(
|
||||||
tcx.dcx(),
|
tcx.dcx(),
|
||||||
span,
|
span,
|
||||||
@ -1905,14 +1905,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if !private_fields.is_empty() {
|
if !private_fields.is_empty() {
|
||||||
self.report_private_fields(adt_ty, span, expr.span, private_fields, ast_fields);
|
self.report_private_fields(adt_ty, span, expr.span, private_fields, hir_fields);
|
||||||
} else {
|
} else {
|
||||||
self.report_missing_fields(
|
self.report_missing_fields(
|
||||||
adt_ty,
|
adt_ty,
|
||||||
span,
|
span,
|
||||||
remaining_fields,
|
remaining_fields,
|
||||||
variant,
|
variant,
|
||||||
ast_fields,
|
hir_fields,
|
||||||
args,
|
args,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1949,7 +1949,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
span: Span,
|
span: Span,
|
||||||
remaining_fields: UnordMap<Ident, (FieldIdx, &ty::FieldDef)>,
|
remaining_fields: UnordMap<Ident, (FieldIdx, &ty::FieldDef)>,
|
||||||
variant: &'tcx ty::VariantDef,
|
variant: &'tcx ty::VariantDef,
|
||||||
ast_fields: &'tcx [hir::ExprField<'tcx>],
|
hir_fields: &'tcx [hir::ExprField<'tcx>],
|
||||||
args: GenericArgsRef<'tcx>,
|
args: GenericArgsRef<'tcx>,
|
||||||
) {
|
) {
|
||||||
let len = remaining_fields.len();
|
let len = remaining_fields.len();
|
||||||
@ -1986,8 +1986,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
);
|
);
|
||||||
err.span_label(span, format!("missing {remaining_fields_names}{truncated_fields_error}"));
|
err.span_label(span, format!("missing {remaining_fields_names}{truncated_fields_error}"));
|
||||||
|
|
||||||
if let Some(last) = ast_fields.last() {
|
if let Some(hir_field) = hir_fields.last() {
|
||||||
self.suggest_fru_from_range_and_emit(last, variant, args, err);
|
self.suggest_fru_from_range_and_emit(hir_field, variant, args, err);
|
||||||
} else {
|
} else {
|
||||||
err.emit();
|
err.emit();
|
||||||
}
|
}
|
||||||
@ -3283,7 +3283,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
fields: &[Ident],
|
fields: &[Ident],
|
||||||
expr: &'tcx hir::Expr<'tcx>,
|
expr: &'tcx hir::Expr<'tcx>,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
let container = self.to_ty(container).normalized;
|
let container = self.lower_ty(container).normalized;
|
||||||
|
|
||||||
if let Some(ident_2) = fields.get(1)
|
if let Some(ident_2) = fields.get(1)
|
||||||
&& !self.tcx.features().offset_of_nested
|
&& !self.tcx.features().offset_of_nested
|
||||||
|
@ -11,12 +11,12 @@ use rustc_hir::def::{CtorOf, DefKind, Res};
|
|||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::lang_items::LangItem;
|
use rustc_hir::lang_items::LangItem;
|
||||||
use rustc_hir::{ExprKind, GenericArg, Node, QPath};
|
use rustc_hir::{ExprKind, GenericArg, Node, QPath};
|
||||||
use rustc_hir_analysis::astconv::generics::{
|
use rustc_hir_analysis::hir_ty_lowering::generics::{
|
||||||
check_generic_arg_count_for_call, create_args_for_parent_generic_args,
|
check_generic_arg_count_for_call, lower_generic_args,
|
||||||
};
|
};
|
||||||
use rustc_hir_analysis::astconv::{
|
use rustc_hir_analysis::hir_ty_lowering::{
|
||||||
AstConv, CreateInstantiationsForGenericArgsCtxt, ExplicitLateBound, GenericArgCountMismatch,
|
ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, GenericArgsLowerer,
|
||||||
GenericArgCountResult, IsMethodCall, PathSeg,
|
GenericPathSegment, HirTyLowerer, IsMethodCall,
|
||||||
};
|
};
|
||||||
use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
|
use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
|
||||||
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
|
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
|
||||||
@ -394,20 +394,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_ty(&self, ast_t: &hir::Ty<'tcx>) -> LoweredTy<'tcx> {
|
pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> LoweredTy<'tcx> {
|
||||||
let t = self.astconv().ast_ty_to_ty(ast_t);
|
let ty = self.lowerer().lower_ty(hir_ty);
|
||||||
self.register_wf_obligation(t.into(), ast_t.span, traits::WellFormed(None));
|
self.register_wf_obligation(ty.into(), hir_ty.span, traits::WellFormed(None));
|
||||||
LoweredTy::from_raw(self, ast_t.span, t)
|
LoweredTy::from_raw(self, hir_ty.span, ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
|
#[instrument(level = "debug", skip_all)]
|
||||||
let ty = self.to_ty(ast_ty);
|
pub fn lower_ty_saving_user_provided_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
|
||||||
debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
|
let ty = self.lower_ty(hir_ty);
|
||||||
|
debug!(?ty);
|
||||||
|
|
||||||
if Self::can_contain_user_lifetime_bounds(ty.raw) {
|
if Self::can_contain_user_lifetime_bounds(ty.raw) {
|
||||||
let c_ty = self.canonicalize_response(UserType::Ty(ty.raw));
|
let c_ty = self.canonicalize_response(UserType::Ty(ty.raw));
|
||||||
debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
|
debug!(?c_ty);
|
||||||
self.typeck_results.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
|
self.typeck_results.borrow_mut().user_provided_types_mut().insert(hir_ty.hir_id, c_ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
ty.normalized
|
ty.normalized
|
||||||
@ -424,7 +425,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn array_length_to_const(&self, length: &hir::ArrayLen) -> ty::Const<'tcx> {
|
pub fn lower_array_length(&self, length: &hir::ArrayLen) -> ty::Const<'tcx> {
|
||||||
match length {
|
match length {
|
||||||
hir::ArrayLen::Infer(inf) => self.ct_infer(self.tcx.types.usize, None, inf.span),
|
hir::ArrayLen::Infer(inf) => self.ct_infer(self.tcx.types.usize, None, inf.span),
|
||||||
hir::ArrayLen::Body(anon_const) => {
|
hir::ArrayLen::Body(anon_const) => {
|
||||||
@ -436,20 +437,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn const_arg_to_const(
|
pub fn lower_const_arg(&self, hir_ct: &hir::AnonConst, param_def_id: DefId) -> ty::Const<'tcx> {
|
||||||
&self,
|
let did = hir_ct.def_id;
|
||||||
ast_c: &hir::AnonConst,
|
|
||||||
param_def_id: DefId,
|
|
||||||
) -> ty::Const<'tcx> {
|
|
||||||
let did = ast_c.def_id;
|
|
||||||
self.tcx.feed_anon_const_type(did, self.tcx.type_of(param_def_id));
|
self.tcx.feed_anon_const_type(did, self.tcx.type_of(param_def_id));
|
||||||
let c = ty::Const::from_anon_const(self.tcx, did);
|
let ct = ty::Const::from_anon_const(self.tcx, did);
|
||||||
self.register_wf_obligation(
|
self.register_wf_obligation(
|
||||||
c.into(),
|
ct.into(),
|
||||||
self.tcx.hir().span(ast_c.hir_id),
|
self.tcx.hir().span(hir_ct.hir_id),
|
||||||
ObligationCauseCode::WellFormed(None),
|
ObligationCauseCode::WellFormed(None),
|
||||||
);
|
);
|
||||||
c
|
ct
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the type given by the user has free regions, save it for later, since
|
// If the type given by the user has free regions, save it for later, since
|
||||||
@ -827,12 +824,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
QPath::Resolved(ref opt_qself, path) => {
|
QPath::Resolved(ref opt_qself, path) => {
|
||||||
return (
|
return (
|
||||||
path.res,
|
path.res,
|
||||||
opt_qself.as_ref().map(|qself| self.to_ty(qself)),
|
opt_qself.as_ref().map(|qself| self.lower_ty(qself)),
|
||||||
path.segments,
|
path.segments,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
QPath::TypeRelative(ref qself, ref segment) => {
|
QPath::TypeRelative(ref qself, ref segment) => {
|
||||||
// Don't use `self.to_ty`, since this will register a WF obligation.
|
// Don't use `self.lower_ty`, since this will register a WF obligation.
|
||||||
// If we're trying to call a nonexistent method on a trait
|
// If we're trying to call a nonexistent method on a trait
|
||||||
// (e.g. `MyTrait::missing_method`), then resolution will
|
// (e.g. `MyTrait::missing_method`), then resolution will
|
||||||
// give us a `QPath::TypeRelative` with a trait object as
|
// give us a `QPath::TypeRelative` with a trait object as
|
||||||
@ -841,7 +838,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
// to be object-safe.
|
// to be object-safe.
|
||||||
// We manually call `register_wf_obligation` in the success path
|
// We manually call `register_wf_obligation` in the success path
|
||||||
// below.
|
// below.
|
||||||
let ty = self.astconv().ast_ty_to_ty_in_path(qself);
|
let ty = self.lowerer().lower_ty_in_path(qself);
|
||||||
(LoweredTy::from_raw(self, span, ty), qself, segment)
|
(LoweredTy::from_raw(self, span, ty), qself, segment)
|
||||||
}
|
}
|
||||||
QPath::LangItem(..) => {
|
QPath::LangItem(..) => {
|
||||||
@ -1119,9 +1116,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
) -> (Ty<'tcx>, Res) {
|
) -> (Ty<'tcx>, Res) {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
|
|
||||||
let path_segs = match res {
|
let generic_segments = match res {
|
||||||
Res::Local(_) | Res::SelfCtor(_) => vec![],
|
Res::Local(_) | Res::SelfCtor(_) => vec![],
|
||||||
Res::Def(kind, def_id) => self.astconv().def_ids_for_value_path_segments(
|
Res::Def(kind, def_id) => self.lowerer().probe_generic_path_segments(
|
||||||
segments,
|
segments,
|
||||||
self_ty.map(|ty| ty.raw),
|
self_ty.map(|ty| ty.raw),
|
||||||
kind,
|
kind,
|
||||||
@ -1178,14 +1175,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
// provided (if any) into their appropriate spaces. We'll also report
|
// provided (if any) into their appropriate spaces. We'll also report
|
||||||
// errors if type parameters are provided in an inappropriate place.
|
// errors if type parameters are provided in an inappropriate place.
|
||||||
|
|
||||||
let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
|
let indices: FxHashSet<_> =
|
||||||
let generics_has_err = self.astconv().prohibit_generics(
|
generic_segments.iter().map(|GenericPathSegment(_, index)| index).collect();
|
||||||
|
let generics_has_err = self.lowerer().prohibit_generic_args(
|
||||||
segments.iter().enumerate().filter_map(|(index, seg)| {
|
segments.iter().enumerate().filter_map(|(index, seg)| {
|
||||||
if !generic_segs.contains(&index) || is_alias_variant_ctor {
|
if !indices.contains(&index) || is_alias_variant_ctor { Some(seg) } else { None }
|
||||||
Some(seg)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}),
|
}),
|
||||||
|_| {},
|
|_| {},
|
||||||
);
|
);
|
||||||
@ -1212,7 +1206,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
let mut infer_args_for_err = FxHashSet::default();
|
let mut infer_args_for_err = FxHashSet::default();
|
||||||
|
|
||||||
let mut explicit_late_bound = ExplicitLateBound::No;
|
let mut explicit_late_bound = ExplicitLateBound::No;
|
||||||
for &PathSeg(def_id, index) in &path_segs {
|
for &GenericPathSegment(def_id, index) in &generic_segments {
|
||||||
let seg = &segments[index];
|
let seg = &segments[index];
|
||||||
let generics = tcx.generics_of(def_id);
|
let generics = tcx.generics_of(def_id);
|
||||||
|
|
||||||
@ -1233,8 +1227,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let has_self =
|
let has_self = generic_segments
|
||||||
path_segs.last().is_some_and(|PathSeg(def_id, _)| tcx.generics_of(*def_id).has_self);
|
.last()
|
||||||
|
.is_some_and(|GenericPathSegment(def_id, _)| tcx.generics_of(*def_id).has_self);
|
||||||
|
|
||||||
let (res, self_ctor_args) = if let Res::SelfCtor(impl_def_id) = res {
|
let (res, self_ctor_args) = if let Res::SelfCtor(impl_def_id) = res {
|
||||||
let ty = LoweredTy::from_raw(
|
let ty = LoweredTy::from_raw(
|
||||||
@ -1294,22 +1289,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CreateCtorInstantiationsContext<'a, 'tcx> {
|
struct CtorGenericArgsCtxt<'a, 'tcx> {
|
||||||
fcx: &'a FnCtxt<'a, 'tcx>,
|
fcx: &'a FnCtxt<'a, 'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
path_segs: &'a [PathSeg],
|
generic_segments: &'a [GenericPathSegment],
|
||||||
infer_args_for_err: &'a FxHashSet<usize>,
|
infer_args_for_err: &'a FxHashSet<usize>,
|
||||||
segments: &'tcx [hir::PathSegment<'tcx>],
|
segments: &'tcx [hir::PathSegment<'tcx>],
|
||||||
}
|
}
|
||||||
impl<'tcx, 'a> CreateInstantiationsForGenericArgsCtxt<'a, 'tcx>
|
impl<'tcx, 'a> GenericArgsLowerer<'a, 'tcx> for CtorGenericArgsCtxt<'a, 'tcx> {
|
||||||
for CreateCtorInstantiationsContext<'a, 'tcx>
|
|
||||||
{
|
|
||||||
fn args_for_def_id(
|
fn args_for_def_id(
|
||||||
&mut self,
|
&mut self,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
) -> (Option<&'a hir::GenericArgs<'tcx>>, bool) {
|
) -> (Option<&'a hir::GenericArgs<'tcx>>, bool) {
|
||||||
if let Some(&PathSeg(_, index)) =
|
if let Some(&GenericPathSegment(_, index)) =
|
||||||
self.path_segs.iter().find(|&PathSeg(did, _)| *did == def_id)
|
self.generic_segments.iter().find(|&GenericPathSegment(did, _)| *did == def_id)
|
||||||
{
|
{
|
||||||
// If we've encountered an `impl Trait`-related error, we're just
|
// If we've encountered an `impl Trait`-related error, we're just
|
||||||
// going to infer the arguments for better error messages.
|
// going to infer the arguments for better error messages.
|
||||||
@ -1332,13 +1325,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
) -> ty::GenericArg<'tcx> {
|
) -> ty::GenericArg<'tcx> {
|
||||||
match (¶m.kind, arg) {
|
match (¶m.kind, arg) {
|
||||||
(GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
|
(GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
|
||||||
self.fcx.astconv().ast_region_to_region(lt, Some(param)).into()
|
self.fcx.lowerer().lower_lifetime(lt, Some(param)).into()
|
||||||
}
|
}
|
||||||
(GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
|
(GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
|
||||||
self.fcx.to_ty(ty).raw.into()
|
self.fcx.lower_ty(ty).raw.into()
|
||||||
}
|
}
|
||||||
(GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => {
|
(GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => {
|
||||||
self.fcx.const_arg_to_const(&ct.value, param.def_id).into()
|
self.fcx.lower_const_arg(&ct.value, param.def_id).into()
|
||||||
}
|
}
|
||||||
(GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => {
|
(GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => {
|
||||||
self.fcx.ty_infer(Some(param), inf.span).into()
|
self.fcx.ty_infer(Some(param), inf.span).into()
|
||||||
@ -1420,17 +1413,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let args_raw = self_ctor_args.unwrap_or_else(|| {
|
let args_raw = self_ctor_args.unwrap_or_else(|| {
|
||||||
create_args_for_parent_generic_args(
|
lower_generic_args(
|
||||||
tcx,
|
tcx,
|
||||||
def_id,
|
def_id,
|
||||||
&[],
|
&[],
|
||||||
has_self,
|
has_self,
|
||||||
self_ty.map(|s| s.raw),
|
self_ty.map(|s| s.raw),
|
||||||
&arg_count,
|
&arg_count,
|
||||||
&mut CreateCtorInstantiationsContext {
|
&mut CtorGenericArgsCtxt {
|
||||||
fcx: self,
|
fcx: self,
|
||||||
span,
|
span,
|
||||||
path_segs: &path_segs,
|
generic_segments: &generic_segments,
|
||||||
infer_args_for_err: &infer_args_for_err,
|
infer_args_for_err: &infer_args_for_err,
|
||||||
segments,
|
segments,
|
||||||
},
|
},
|
||||||
|
@ -24,9 +24,9 @@ use rustc_hir::def::{CtorOf, DefKind, Res};
|
|||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::intravisit::Visitor;
|
use rustc_hir::intravisit::Visitor;
|
||||||
use rustc_hir::{ExprKind, Node, QPath};
|
use rustc_hir::{ExprKind, Node, QPath};
|
||||||
use rustc_hir_analysis::astconv::AstConv;
|
|
||||||
use rustc_hir_analysis::check::intrinsicck::InlineAsmCtxt;
|
use rustc_hir_analysis::check::intrinsicck::InlineAsmCtxt;
|
||||||
use rustc_hir_analysis::check::potentially_plural_count;
|
use rustc_hir_analysis::check::potentially_plural_count;
|
||||||
|
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
|
||||||
use rustc_hir_analysis::structured_errors::StructuredDiag;
|
use rustc_hir_analysis::structured_errors::StructuredDiag;
|
||||||
use rustc_index::IndexVec;
|
use rustc_index::IndexVec;
|
||||||
use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt};
|
use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt};
|
||||||
@ -1961,16 +1961,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
) -> (Res, LoweredTy<'tcx>) {
|
) -> (Res, LoweredTy<'tcx>) {
|
||||||
match *qpath {
|
match *qpath {
|
||||||
QPath::Resolved(ref maybe_qself, path) => {
|
QPath::Resolved(ref maybe_qself, path) => {
|
||||||
let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself).raw);
|
let self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself).raw);
|
||||||
let ty = self.astconv().res_to_ty(self_ty, path, hir_id, true);
|
let ty = self.lowerer().lower_path(self_ty, path, hir_id, true);
|
||||||
(path.res, LoweredTy::from_raw(self, path_span, ty))
|
(path.res, LoweredTy::from_raw(self, path_span, ty))
|
||||||
}
|
}
|
||||||
QPath::TypeRelative(qself, segment) => {
|
QPath::TypeRelative(qself, segment) => {
|
||||||
let ty = self.to_ty(qself);
|
let ty = self.lower_ty(qself);
|
||||||
|
|
||||||
let result = self
|
let result = self
|
||||||
.astconv()
|
.lowerer()
|
||||||
.associated_path_to_ty(hir_id, path_span, ty.raw, qself, segment, true);
|
.lower_assoc_path(hir_id, path_span, ty.raw, qself, segment, true);
|
||||||
let ty = result
|
let ty = result
|
||||||
.map(|(ty, _, _)| ty)
|
.map(|(ty, _, _)| ty)
|
||||||
.unwrap_or_else(|guar| Ty::new_error(self.tcx(), guar));
|
.unwrap_or_else(|guar| Ty::new_error(self.tcx(), guar));
|
||||||
|
@ -12,7 +12,7 @@ use hir::def_id::CRATE_DEF_ID;
|
|||||||
use rustc_errors::{DiagCtxt, ErrorGuaranteed};
|
use rustc_errors::{DiagCtxt, ErrorGuaranteed};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_hir_analysis::astconv::AstConv;
|
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
|
||||||
use rustc_infer::infer;
|
use rustc_infer::infer;
|
||||||
use rustc_infer::infer::error_reporting::sub_relations::SubRelations;
|
use rustc_infer::infer::error_reporting::sub_relations::SubRelations;
|
||||||
use rustc_infer::infer::error_reporting::TypeErrCtxt;
|
use rustc_infer::infer::error_reporting::TypeErrCtxt;
|
||||||
@ -212,7 +212,7 @@ impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
|
impl<'a, 'tcx> HirTyLowerer<'tcx> for FnCtxt<'a, 'tcx> {
|
||||||
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
|
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
@ -221,31 +221,8 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
|
|||||||
self.body_id.to_def_id()
|
self.body_id.to_def_id()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_type_parameter_bounds(
|
fn allow_infer(&self) -> bool {
|
||||||
&self,
|
true
|
||||||
_: Span,
|
|
||||||
def_id: LocalDefId,
|
|
||||||
_: Ident,
|
|
||||||
) -> ty::GenericPredicates<'tcx> {
|
|
||||||
let tcx = self.tcx;
|
|
||||||
let item_def_id = tcx.hir().ty_param_owner(def_id);
|
|
||||||
let generics = tcx.generics_of(item_def_id);
|
|
||||||
let index = generics.param_def_id_to_index[&def_id.to_def_id()];
|
|
||||||
// HACK(eddyb) should get the original `Span`.
|
|
||||||
let span = tcx.def_span(def_id);
|
|
||||||
ty::GenericPredicates {
|
|
||||||
parent: None,
|
|
||||||
predicates: tcx.arena.alloc_from_iter(
|
|
||||||
self.param_env.caller_bounds().iter().filter_map(|predicate| {
|
|
||||||
match predicate.kind().skip_binder() {
|
|
||||||
ty::ClauseKind::Trait(data) if data.self_ty().is_param(index) => {
|
|
||||||
Some((predicate, span))
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn re_infer(&self, def: Option<&ty::GenericParamDef>, span: Span) -> Option<ty::Region<'tcx>> {
|
fn re_infer(&self, def: Option<&ty::GenericParamDef>, span: Span) -> Option<ty::Region<'tcx>> {
|
||||||
@ -256,10 +233,6 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
|
|||||||
Some(self.next_region_var(v))
|
Some(self.next_region_var(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn allow_ty_infer(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
|
fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
|
||||||
match param {
|
match param {
|
||||||
Some(param) => self.var_for_def(span, param).as_type().unwrap(),
|
Some(param) => self.var_for_def(span, param).as_type().unwrap(),
|
||||||
@ -292,7 +265,34 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn projected_ty_from_poly_trait_ref(
|
fn probe_ty_param_bounds(
|
||||||
|
&self,
|
||||||
|
_: Span,
|
||||||
|
def_id: LocalDefId,
|
||||||
|
_: Ident,
|
||||||
|
) -> ty::GenericPredicates<'tcx> {
|
||||||
|
let tcx = self.tcx;
|
||||||
|
let item_def_id = tcx.hir().ty_param_owner(def_id);
|
||||||
|
let generics = tcx.generics_of(item_def_id);
|
||||||
|
let index = generics.param_def_id_to_index[&def_id.to_def_id()];
|
||||||
|
// HACK(eddyb) should get the original `Span`.
|
||||||
|
let span = tcx.def_span(def_id);
|
||||||
|
ty::GenericPredicates {
|
||||||
|
parent: None,
|
||||||
|
predicates: tcx.arena.alloc_from_iter(
|
||||||
|
self.param_env.caller_bounds().iter().filter_map(|predicate| {
|
||||||
|
match predicate.kind().skip_binder() {
|
||||||
|
ty::ClauseKind::Trait(data) if data.self_ty().is_param(index) => {
|
||||||
|
Some((predicate, span))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lower_assoc_ty(
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
item_def_id: DefId,
|
item_def_id: DefId,
|
||||||
@ -305,7 +305,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
|
|||||||
poly_trait_ref,
|
poly_trait_ref,
|
||||||
);
|
);
|
||||||
|
|
||||||
let item_args = self.astconv().create_args_for_associated_item(
|
let item_args = self.lowerer().lower_generic_args_of_assoc_item(
|
||||||
span,
|
span,
|
||||||
item_def_id,
|
item_def_id,
|
||||||
item_segment,
|
item_segment,
|
||||||
@ -328,10 +328,6 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_tainted_by_errors(&self, e: ErrorGuaranteed) {
|
|
||||||
self.infcx.set_tainted_by_errors(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span) {
|
fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span) {
|
||||||
// FIXME: normalization and escaping regions
|
// FIXME: normalization and escaping regions
|
||||||
let ty = if !ty.has_escaping_bound_vars() {
|
let ty = if !ty.has_escaping_bound_vars() {
|
||||||
@ -355,13 +351,17 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
|
|||||||
fn infcx(&self) -> Option<&infer::InferCtxt<'tcx>> {
|
fn infcx(&self) -> Option<&infer::InferCtxt<'tcx>> {
|
||||||
Some(&self.infcx)
|
Some(&self.infcx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_tainted_by_errors(&self, e: ErrorGuaranteed) {
|
||||||
|
self.infcx.set_tainted_by_errors(e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The `ty` representation of a user-provided type. Depending on the use-site
|
/// The `ty` representation of a user-provided type. Depending on the use-site
|
||||||
/// we want to either use the unnormalized or the normalized form of this type.
|
/// we want to either use the unnormalized or the normalized form of this type.
|
||||||
///
|
///
|
||||||
/// This is a bridge between the interface of `AstConv`, which outputs a raw `Ty`,
|
/// This is a bridge between the interface of HIR ty lowering, which outputs a raw
|
||||||
/// and the API in this module, which expect `Ty` to be fully normalized.
|
/// `Ty`, and the API in this module, which expect `Ty` to be fully normalized.
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct LoweredTy<'tcx> {
|
pub struct LoweredTy<'tcx> {
|
||||||
/// The unnormalized type provided by the user.
|
/// The unnormalized type provided by the user.
|
||||||
|
@ -21,7 +21,7 @@ use rustc_hir::{
|
|||||||
CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, GenericBound, HirId, Node,
|
CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, GenericBound, HirId, Node,
|
||||||
Path, QPath, Stmt, StmtKind, TyKind, WherePredicate,
|
Path, QPath, Stmt, StmtKind, TyKind, WherePredicate,
|
||||||
};
|
};
|
||||||
use rustc_hir_analysis::astconv::AstConv;
|
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
|
||||||
use rustc_infer::traits::{self};
|
use rustc_infer::traits::{self};
|
||||||
use rustc_middle::lint::in_external_macro;
|
use rustc_middle::lint::in_external_macro;
|
||||||
use rustc_middle::middle::stability::EvalResult;
|
use rustc_middle::middle::stability::EvalResult;
|
||||||
@ -877,7 +877,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
// Only point to return type if the expected type is the return type, as if they
|
// Only point to return type if the expected type is the return type, as if they
|
||||||
// are not, the expectation must have been caused by something else.
|
// are not, the expectation must have been caused by something else.
|
||||||
debug!("return type {:?}", hir_ty);
|
debug!("return type {:?}", hir_ty);
|
||||||
let ty = self.astconv().ast_ty_to_ty(hir_ty);
|
let ty = self.lowerer().lower_ty(hir_ty);
|
||||||
debug!("return type {:?}", ty);
|
debug!("return type {:?}", ty);
|
||||||
debug!("expected type {:?}", expected);
|
debug!("expected type {:?}", expected);
|
||||||
let bound_vars = self.tcx.late_bound_vars(hir_ty.hir_id.owner.into());
|
let bound_vars = self.tcx.late_bound_vars(hir_ty.hir_id.owner.into());
|
||||||
@ -957,8 +957,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
bounded_ty,
|
bounded_ty,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
// FIXME: Maybe these calls to `ast_ty_to_ty` can be removed (and the ones below)
|
// FIXME: Maybe these calls to `lower_ty` can be removed (and the ones below)
|
||||||
let ty = self.astconv().ast_ty_to_ty(bounded_ty);
|
let ty = self.lowerer().lower_ty(bounded_ty);
|
||||||
Some((ty, bounds))
|
Some((ty, bounds))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
@ -996,7 +996,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
let all_bounds_str = all_matching_bounds_strs.join(" + ");
|
let all_bounds_str = all_matching_bounds_strs.join(" + ");
|
||||||
|
|
||||||
let ty_param_used_in_fn_params = fn_parameters.iter().any(|param| {
|
let ty_param_used_in_fn_params = fn_parameters.iter().any(|param| {
|
||||||
let ty = self.astconv().ast_ty_to_ty( param);
|
let ty = self.lowerer().lower_ty( param);
|
||||||
matches!(ty.kind(), ty::Param(fn_param_ty_param) if expected_ty_as_param == fn_param_ty_param)
|
matches!(ty.kind(), ty::Param(fn_param_ty_param) if expected_ty_as_param == fn_param_ty_param)
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1071,7 +1071,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
let can_return = match fn_decl.output {
|
let can_return = match fn_decl.output {
|
||||||
hir::FnRetTy::Return(ty) => {
|
hir::FnRetTy::Return(ty) => {
|
||||||
let ty = self.astconv().ast_ty_to_ty(ty);
|
let ty = self.lowerer().lower_ty(ty);
|
||||||
let bound_vars = self.tcx.late_bound_vars(fn_id);
|
let bound_vars = self.tcx.late_bound_vars(fn_id);
|
||||||
let ty = self
|
let ty = self
|
||||||
.tcx
|
.tcx
|
||||||
|
@ -93,7 +93,7 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
|
|||||||
fn declare(&mut self, decl: Declaration<'tcx>) {
|
fn declare(&mut self, decl: Declaration<'tcx>) {
|
||||||
let local_ty = match decl.ty {
|
let local_ty = match decl.ty {
|
||||||
Some(ref ty) => {
|
Some(ref ty) => {
|
||||||
let o_ty = self.fcx.to_ty(ty);
|
let o_ty = self.fcx.lower_ty(ty);
|
||||||
|
|
||||||
let c_ty =
|
let c_ty =
|
||||||
self.fcx.inh.infcx.canonicalize_user_type_annotation(UserType::Ty(o_ty.raw));
|
self.fcx.inh.infcx.canonicalize_user_type_annotation(UserType::Ty(o_ty.raw));
|
||||||
|
@ -57,8 +57,8 @@ use rustc_hir as hir;
|
|||||||
use rustc_hir::def::{DefKind, Res};
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::intravisit::Visitor;
|
use rustc_hir::intravisit::Visitor;
|
||||||
use rustc_hir::{HirIdMap, Node};
|
use rustc_hir::{HirIdMap, Node};
|
||||||
use rustc_hir_analysis::astconv::AstConv;
|
|
||||||
use rustc_hir_analysis::check::check_abi;
|
use rustc_hir_analysis::check::check_abi;
|
||||||
|
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
|
||||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||||
use rustc_infer::traits::{ObligationCauseCode, ObligationInspector, WellFormedLoc};
|
use rustc_infer::traits::{ObligationCauseCode, ObligationInspector, WellFormedLoc};
|
||||||
use rustc_middle::query::Providers;
|
use rustc_middle::query::Providers;
|
||||||
@ -178,7 +178,7 @@ fn typeck_with_fallback<'tcx>(
|
|||||||
|
|
||||||
if let Some(hir::FnSig { header, decl, .. }) = fn_sig {
|
if let Some(hir::FnSig { header, decl, .. }) = fn_sig {
|
||||||
let fn_sig = if decl.output.get_infer_ret_ty().is_some() {
|
let fn_sig = if decl.output.get_infer_ret_ty().is_some() {
|
||||||
fcx.astconv().ty_of_fn(id, header.unsafety, header.abi, decl, None, None)
|
fcx.lowerer().lower_fn_ty(id, header.unsafety, header.abi, decl, None, None)
|
||||||
} else {
|
} else {
|
||||||
tcx.fn_sig(def_id).instantiate_identity()
|
tcx.fn_sig(def_id).instantiate_identity()
|
||||||
};
|
};
|
||||||
|
@ -4,10 +4,10 @@ use crate::{callee, FnCtxt};
|
|||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::GenericArg;
|
use rustc_hir::GenericArg;
|
||||||
use rustc_hir_analysis::astconv::generics::{
|
use rustc_hir_analysis::hir_ty_lowering::generics::{
|
||||||
check_generic_arg_count_for_call, create_args_for_parent_generic_args,
|
check_generic_arg_count_for_call, lower_generic_args,
|
||||||
};
|
};
|
||||||
use rustc_hir_analysis::astconv::{AstConv, CreateInstantiationsForGenericArgsCtxt, IsMethodCall};
|
use rustc_hir_analysis::hir_ty_lowering::{GenericArgsLowerer, HirTyLowerer, IsMethodCall};
|
||||||
use rustc_infer::infer::{self, DefineOpaqueTypes, InferOk};
|
use rustc_infer::infer::{self, DefineOpaqueTypes, InferOk};
|
||||||
use rustc_middle::traits::{ObligationCauseCode, UnifyReceiverContext};
|
use rustc_middle::traits::{ObligationCauseCode, UnifyReceiverContext};
|
||||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
|
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
|
||||||
@ -366,14 +366,12 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
|||||||
// combining parameters from the type and those from the method.
|
// combining parameters from the type and those from the method.
|
||||||
assert_eq!(generics.parent_count, parent_args.len());
|
assert_eq!(generics.parent_count, parent_args.len());
|
||||||
|
|
||||||
struct MethodInstantiationsCtxt<'a, 'tcx> {
|
struct GenericArgsCtxt<'a, 'tcx> {
|
||||||
cfcx: &'a ConfirmContext<'a, 'tcx>,
|
cfcx: &'a ConfirmContext<'a, 'tcx>,
|
||||||
pick: &'a probe::Pick<'tcx>,
|
pick: &'a probe::Pick<'tcx>,
|
||||||
seg: &'a hir::PathSegment<'tcx>,
|
seg: &'a hir::PathSegment<'tcx>,
|
||||||
}
|
}
|
||||||
impl<'a, 'tcx> CreateInstantiationsForGenericArgsCtxt<'a, 'tcx>
|
impl<'a, 'tcx> GenericArgsLowerer<'a, 'tcx> for GenericArgsCtxt<'a, 'tcx> {
|
||||||
for MethodInstantiationsCtxt<'a, 'tcx>
|
|
||||||
{
|
|
||||||
fn args_for_def_id(
|
fn args_for_def_id(
|
||||||
&mut self,
|
&mut self,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
@ -393,13 +391,13 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
|||||||
) -> ty::GenericArg<'tcx> {
|
) -> ty::GenericArg<'tcx> {
|
||||||
match (¶m.kind, arg) {
|
match (¶m.kind, arg) {
|
||||||
(GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
|
(GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
|
||||||
self.cfcx.fcx.astconv().ast_region_to_region(lt, Some(param)).into()
|
self.cfcx.fcx.lowerer().lower_lifetime(lt, Some(param)).into()
|
||||||
}
|
}
|
||||||
(GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
|
(GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
|
||||||
self.cfcx.to_ty(ty).raw.into()
|
self.cfcx.lower_ty(ty).raw.into()
|
||||||
}
|
}
|
||||||
(GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => {
|
(GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => {
|
||||||
self.cfcx.const_arg_to_const(&ct.value, param.def_id).into()
|
self.cfcx.lower_const_arg(&ct.value, param.def_id).into()
|
||||||
}
|
}
|
||||||
(GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => {
|
(GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => {
|
||||||
self.cfcx.ty_infer(Some(param), inf.span).into()
|
self.cfcx.ty_infer(Some(param), inf.span).into()
|
||||||
@ -432,14 +430,14 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let args = create_args_for_parent_generic_args(
|
let args = lower_generic_args(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
pick.item.def_id,
|
pick.item.def_id,
|
||||||
parent_args,
|
parent_args,
|
||||||
false,
|
false,
|
||||||
None,
|
None,
|
||||||
&arg_count_correct,
|
&arg_count_correct,
|
||||||
&mut MethodInstantiationsCtxt { cfcx: self, pick, seg },
|
&mut GenericArgsCtxt { cfcx: self, pick, seg },
|
||||||
);
|
);
|
||||||
|
|
||||||
// When the method is confirmed, the `args` includes
|
// When the method is confirmed, the `args` includes
|
||||||
|
@ -3264,8 +3264,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
Colon,
|
Colon,
|
||||||
Nothing,
|
Nothing,
|
||||||
}
|
}
|
||||||
let ast_generics = hir.get_generics(id.owner.def_id).unwrap();
|
let hir_generics = hir.get_generics(id.owner.def_id).unwrap();
|
||||||
let trait_def_ids: DefIdSet = ast_generics
|
let trait_def_ids: DefIdSet = hir_generics
|
||||||
.bounds_for_param(def_id)
|
.bounds_for_param(def_id)
|
||||||
.flat_map(|bp| bp.bounds.iter())
|
.flat_map(|bp| bp.bounds.iter())
|
||||||
.filter_map(|bound| bound.trait_ref()?.trait_def_id())
|
.filter_map(|bound| bound.trait_ref()?.trait_def_id())
|
||||||
@ -3277,7 +3277,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
"restrict type parameter `{}` with",
|
"restrict type parameter `{}` with",
|
||||||
param.name.ident(),
|
param.name.ident(),
|
||||||
));
|
));
|
||||||
let bounds_span = ast_generics.bounds_span_for_suggestions(def_id);
|
let bounds_span = hir_generics.bounds_span_for_suggestions(def_id);
|
||||||
if rcvr_ty.is_ref() && param.is_impl_trait() && bounds_span.is_some() {
|
if rcvr_ty.is_ref() && param.is_impl_trait() && bounds_span.is_some() {
|
||||||
err.multipart_suggestions(
|
err.multipart_suggestions(
|
||||||
msg,
|
msg,
|
||||||
|
@ -1062,7 +1062,7 @@ pub enum ExpnKind {
|
|||||||
Macro(MacroKind, Symbol),
|
Macro(MacroKind, Symbol),
|
||||||
/// Transform done by the compiler on the AST.
|
/// Transform done by the compiler on the AST.
|
||||||
AstPass(AstPass),
|
AstPass(AstPass),
|
||||||
/// Desugaring done by the compiler during HIR lowering.
|
/// Desugaring done by the compiler during AST lowering.
|
||||||
Desugaring(DesugaringKind),
|
Desugaring(DesugaringKind),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//! Computes a normalizes-to (projection) goal for inherent associated types,
|
//! Computes a normalizes-to (projection) goal for inherent associated types,
|
||||||
//! `#![feature(inherent_associated_type)]`. Since astconv already determines
|
//! `#![feature(inherent_associated_type)]`. Since HIR ty lowering already determines
|
||||||
//! which impl the IAT is being projected from, we just:
|
//! which impl the IAT is being projected from, we just:
|
||||||
//! 1. instantiate generic parameters,
|
//! 1. instantiate generic parameters,
|
||||||
//! 2. equate the self type, and
|
//! 2. equate the self type, and
|
||||||
|
@ -46,7 +46,7 @@ pub use self::coherence::{IsFirstInputType, OrphanCheckErr, OverlapResult};
|
|||||||
pub use self::engine::{ObligationCtxt, TraitEngineExt};
|
pub use self::engine::{ObligationCtxt, TraitEngineExt};
|
||||||
pub use self::fulfill::{FulfillmentContext, PendingPredicateObligation};
|
pub use self::fulfill::{FulfillmentContext, PendingPredicateObligation};
|
||||||
pub use self::normalize::NormalizeExt;
|
pub use self::normalize::NormalizeExt;
|
||||||
pub use self::object_safety::astconv_object_safety_violations;
|
pub use self::object_safety::hir_ty_lowering_object_safety_violations;
|
||||||
pub use self::object_safety::is_vtable_safe_method;
|
pub use self::object_safety::is_vtable_safe_method;
|
||||||
pub use self::object_safety::object_safety_violations_for_assoc_item;
|
pub use self::object_safety::object_safety_violations_for_assoc_item;
|
||||||
pub use self::object_safety::ObjectSafetyViolation;
|
pub use self::object_safety::ObjectSafetyViolation;
|
||||||
|
@ -32,11 +32,13 @@ use std::ops::ControlFlow;
|
|||||||
|
|
||||||
pub use crate::traits::{MethodViolationCode, ObjectSafetyViolation};
|
pub use crate::traits::{MethodViolationCode, ObjectSafetyViolation};
|
||||||
|
|
||||||
/// Returns the object safety violations that affect
|
/// Returns the object safety violations that affect HIR ty lowering.
|
||||||
/// astconv -- currently, `Self` in supertraits. This is needed
|
///
|
||||||
|
/// Currently that is `Self` in supertraits. This is needed
|
||||||
/// because `object_safety_violations` can't be used during
|
/// because `object_safety_violations` can't be used during
|
||||||
/// type collection.
|
/// type collection.
|
||||||
pub fn astconv_object_safety_violations(
|
#[instrument(level = "debug", skip(tcx))]
|
||||||
|
pub fn hir_ty_lowering_object_safety_violations(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
trait_def_id: DefId,
|
trait_def_id: DefId,
|
||||||
) -> Vec<ObjectSafetyViolation> {
|
) -> Vec<ObjectSafetyViolation> {
|
||||||
@ -46,9 +48,7 @@ pub fn astconv_object_safety_violations(
|
|||||||
.filter(|spans| !spans.is_empty())
|
.filter(|spans| !spans.is_empty())
|
||||||
.map(ObjectSafetyViolation::SupertraitSelf)
|
.map(ObjectSafetyViolation::SupertraitSelf)
|
||||||
.collect();
|
.collect();
|
||||||
|
debug!(?violations);
|
||||||
debug!("astconv_object_safety_violations(trait_def_id={:?}) = {:?}", trait_def_id, violations);
|
|
||||||
|
|
||||||
violations
|
violations
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1264,7 +1264,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
|
|
||||||
// Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`,
|
// Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`,
|
||||||
// normalizing in the process, since `type_of` returns something directly from
|
// normalizing in the process, since `type_of` returns something directly from
|
||||||
// astconv (which means it's un-normalized).
|
// HIR ty lowering (which means it's un-normalized).
|
||||||
let source_tail = normalize_with_depth_to(
|
let source_tail = normalize_with_depth_to(
|
||||||
self,
|
self,
|
||||||
obligation.param_env,
|
obligation.param_env,
|
||||||
|
@ -396,7 +396,7 @@ pub(crate) fn assoc_def(
|
|||||||
// associated type. Normally this situation
|
// associated type. Normally this situation
|
||||||
// could only arise through a compiler bug --
|
// could only arise through a compiler bug --
|
||||||
// if the user wrote a bad item name, it
|
// if the user wrote a bad item name, it
|
||||||
// should have failed in astconv.
|
// should have failed during HIR ty lowering.
|
||||||
bug!(
|
bug!(
|
||||||
"No associated type `{}` for {}",
|
"No associated type `{}` for {}",
|
||||||
tcx.item_name(assoc_def_id),
|
tcx.item_name(assoc_def_id),
|
||||||
|
@ -60,7 +60,7 @@ impl AliasKind {
|
|||||||
/// Defines the kinds of types used by the type system.
|
/// Defines the kinds of types used by the type system.
|
||||||
///
|
///
|
||||||
/// Types written by the user start out as `hir::TyKind` and get
|
/// Types written by the user start out as `hir::TyKind` and get
|
||||||
/// converted to this representation using `AstConv::ast_ty_to_ty`.
|
/// converted to this representation using `<dyn HirTyLowerer>::lower_ty`.
|
||||||
#[cfg_attr(feature = "nightly", rustc_diagnostic_item = "IrTyKind")]
|
#[cfg_attr(feature = "nightly", rustc_diagnostic_item = "IrTyKind")]
|
||||||
#[derive(derivative::Derivative)]
|
#[derive(derivative::Derivative)]
|
||||||
#[derivative(
|
#[derivative(
|
||||||
|
@ -20,7 +20,7 @@ use rustc_hir as hir;
|
|||||||
use rustc_hir::def::{CtorKind, DefKind, Res};
|
use rustc_hir::def::{CtorKind, DefKind, Res};
|
||||||
use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LocalDefId, LOCAL_CRATE};
|
use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LocalDefId, LOCAL_CRATE};
|
||||||
use rustc_hir::PredicateOrigin;
|
use rustc_hir::PredicateOrigin;
|
||||||
use rustc_hir_analysis::hir_ty_to_ty;
|
use rustc_hir_analysis::lower_ty;
|
||||||
use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData};
|
use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData};
|
||||||
use rustc_middle::metadata::Reexport;
|
use rustc_middle::metadata::Reexport;
|
||||||
use rustc_middle::middle::resolve_bound_vars as rbv;
|
use rustc_middle::middle::resolve_bound_vars as rbv;
|
||||||
@ -1260,12 +1260,8 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext
|
|||||||
hir::TraitItemKind::Type(bounds, Some(default)) => {
|
hir::TraitItemKind::Type(bounds, Some(default)) => {
|
||||||
let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx));
|
let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx));
|
||||||
let bounds = bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect();
|
let bounds = bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect();
|
||||||
let item_type = clean_middle_ty(
|
let item_type =
|
||||||
ty::Binder::dummy(hir_ty_to_ty(cx.tcx, default)),
|
clean_middle_ty(ty::Binder::dummy(lower_ty(cx.tcx, default)), cx, None, None);
|
||||||
cx,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
AssocTypeItem(
|
AssocTypeItem(
|
||||||
Box::new(TypeAlias {
|
Box::new(TypeAlias {
|
||||||
type_: clean_ty(default, cx),
|
type_: clean_ty(default, cx),
|
||||||
@ -1306,12 +1302,8 @@ pub(crate) fn clean_impl_item<'tcx>(
|
|||||||
hir::ImplItemKind::Type(hir_ty) => {
|
hir::ImplItemKind::Type(hir_ty) => {
|
||||||
let type_ = clean_ty(hir_ty, cx);
|
let type_ = clean_ty(hir_ty, cx);
|
||||||
let generics = clean_generics(impl_.generics, cx);
|
let generics = clean_generics(impl_.generics, cx);
|
||||||
let item_type = clean_middle_ty(
|
let item_type =
|
||||||
ty::Binder::dummy(hir_ty_to_ty(cx.tcx, hir_ty)),
|
clean_middle_ty(ty::Binder::dummy(lower_ty(cx.tcx, hir_ty)), cx, None, None);
|
||||||
cx,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
AssocTypeItem(
|
AssocTypeItem(
|
||||||
Box::new(TypeAlias {
|
Box::new(TypeAlias {
|
||||||
type_,
|
type_,
|
||||||
@ -1690,7 +1682,7 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type
|
|||||||
}
|
}
|
||||||
hir::QPath::Resolved(Some(qself), p) => {
|
hir::QPath::Resolved(Some(qself), p) => {
|
||||||
// Try to normalize `<X as Y>::T` to a type
|
// Try to normalize `<X as Y>::T` to a type
|
||||||
let ty = hir_ty_to_ty(cx.tcx, hir_ty);
|
let ty = lower_ty(cx.tcx, hir_ty);
|
||||||
// `hir_to_ty` can return projection types with escaping vars for GATs, e.g. `<() as Trait>::Gat<'_>`
|
// `hir_to_ty` can return projection types with escaping vars for GATs, e.g. `<() as Trait>::Gat<'_>`
|
||||||
if !ty.has_escaping_bound_vars()
|
if !ty.has_escaping_bound_vars()
|
||||||
&& let Some(normalized_value) = normalize(cx, ty::Binder::dummy(ty))
|
&& let Some(normalized_value) = normalize(cx, ty::Binder::dummy(ty))
|
||||||
@ -1716,7 +1708,7 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
hir::QPath::TypeRelative(qself, segment) => {
|
hir::QPath::TypeRelative(qself, segment) => {
|
||||||
let ty = hir_ty_to_ty(cx.tcx, hir_ty);
|
let ty = lower_ty(cx.tcx, hir_ty);
|
||||||
let self_type = clean_ty(qself, cx);
|
let self_type = clean_ty(qself, cx);
|
||||||
|
|
||||||
let (trait_, should_show_cast) = match ty.kind() {
|
let (trait_, should_show_cast) = match ty.kind() {
|
||||||
@ -2742,12 +2734,8 @@ fn clean_maybe_renamed_item<'tcx>(
|
|||||||
ItemKind::TyAlias(hir_ty, generics) => {
|
ItemKind::TyAlias(hir_ty, generics) => {
|
||||||
*cx.current_type_aliases.entry(def_id).or_insert(0) += 1;
|
*cx.current_type_aliases.entry(def_id).or_insert(0) += 1;
|
||||||
let rustdoc_ty = clean_ty(hir_ty, cx);
|
let rustdoc_ty = clean_ty(hir_ty, cx);
|
||||||
let type_ = clean_middle_ty(
|
let type_ =
|
||||||
ty::Binder::dummy(hir_ty_to_ty(cx.tcx, hir_ty)),
|
clean_middle_ty(ty::Binder::dummy(lower_ty(cx.tcx, hir_ty)), cx, None, None);
|
||||||
cx,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
let generics = clean_generics(generics, cx);
|
let generics = clean_generics(generics, cx);
|
||||||
if let Some(count) = cx.current_type_aliases.get_mut(&def_id) {
|
if let Some(count) = cx.current_type_aliases.get_mut(&def_id) {
|
||||||
*count -= 1;
|
*count -= 1;
|
||||||
|
@ -118,10 +118,10 @@ Here the HIR sees the types without "thinking" about them, it knows that the fun
|
|||||||
an `u32`. As far as `hir::Ty` is concerned those might be different types. But at the `ty::Ty` level the compiler
|
an `u32`. As far as `hir::Ty` is concerned those might be different types. But at the `ty::Ty` level the compiler
|
||||||
understands that they're the same type, in-depth lifetimes, etc...
|
understands that they're the same type, in-depth lifetimes, etc...
|
||||||
|
|
||||||
To get from a `hir::Ty` to a `ty::Ty`, you can use the [`hir_ty_to_ty`][hir_ty_to_ty] function outside of bodies or
|
To get from a `hir::Ty` to a `ty::Ty`, you can use the [`lower_ty`][lower_ty] function outside of bodies or
|
||||||
the [`TypeckResults::node_type()`][node_type] method inside of bodies.
|
the [`TypeckResults::node_type()`][node_type] method inside of bodies.
|
||||||
|
|
||||||
> **Warning**: Don't use `hir_ty_to_ty` inside of bodies, because this can cause ICEs.
|
> **Warning**: Don't use `lower_ty` inside of bodies, because this can cause ICEs.
|
||||||
|
|
||||||
## Creating Types programmatically
|
## Creating Types programmatically
|
||||||
|
|
||||||
@ -162,6 +162,6 @@ in this chapter:
|
|||||||
[Ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html
|
[Ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html
|
||||||
[TyKind]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/ty_kind/enum.TyKind.html
|
[TyKind]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/ty_kind/enum.TyKind.html
|
||||||
[TypeckResults]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html
|
[TypeckResults]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html
|
||||||
[middle_ty]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_middle/ty/struct.Ty.html
|
[middle_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html
|
||||||
[hir_ty]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_hir/struct.Ty.html
|
[hir_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/struct.Ty.html
|
||||||
[hir_ty_to_ty]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_hir_analysis/fn.hir_ty_to_ty.html
|
[lower_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/fn.lower_ty.html
|
||||||
|
@ -5,7 +5,7 @@ use rustc_errors::Diag;
|
|||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::intravisit::{walk_body, walk_expr, walk_inf, walk_ty, Visitor};
|
use rustc_hir::intravisit::{walk_body, walk_expr, walk_inf, walk_ty, Visitor};
|
||||||
use rustc_hir::{Body, Expr, ExprKind, GenericArg, Item, ItemKind, QPath, TyKind};
|
use rustc_hir::{Body, Expr, ExprKind, GenericArg, Item, ItemKind, QPath, TyKind};
|
||||||
use rustc_hir_analysis::hir_ty_to_ty;
|
use rustc_hir_analysis::lower_ty;
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::hir::nested_filter;
|
use rustc_middle::hir::nested_filter;
|
||||||
use rustc_middle::ty::{Ty, TypeckResults};
|
use rustc_middle::ty::{Ty, TypeckResults};
|
||||||
@ -227,7 +227,7 @@ impl<'tcx> ImplicitHasherType<'tcx> {
|
|||||||
.collect();
|
.collect();
|
||||||
let params_len = params.len();
|
let params_len = params.len();
|
||||||
|
|
||||||
let ty = hir_ty_to_ty(cx.tcx, hir_ty);
|
let ty = lower_ty(cx.tcx, hir_ty);
|
||||||
|
|
||||||
if is_type_diagnostic_item(cx, ty, sym::HashMap) && params_len == 2 {
|
if is_type_diagnostic_item(cx, ty, sym::HashMap) && params_len == 2 {
|
||||||
Some(ImplicitHasherType::HashMap(
|
Some(ImplicitHasherType::HashMap(
|
||||||
|
@ -6,7 +6,7 @@ use rustc_hir::{
|
|||||||
GenericArg, GenericBound, GenericBounds, ItemKind, PredicateOrigin, TraitBoundModifier, TyKind, TypeBinding,
|
GenericArg, GenericBound, GenericBounds, ItemKind, PredicateOrigin, TraitBoundModifier, TyKind, TypeBinding,
|
||||||
WherePredicate,
|
WherePredicate,
|
||||||
};
|
};
|
||||||
use rustc_hir_analysis::hir_ty_to_ty;
|
use rustc_hir_analysis::lower_ty;
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::ty::{self, ClauseKind, Generics, Ty, TyCtxt};
|
use rustc_middle::ty::{self, ClauseKind, Generics, Ty, TyCtxt};
|
||||||
use rustc_session::declare_lint_pass;
|
use rustc_session::declare_lint_pass;
|
||||||
@ -146,7 +146,7 @@ fn try_resolve_type<'tcx>(
|
|||||||
index: usize,
|
index: usize,
|
||||||
) -> Option<Ty<'tcx>> {
|
) -> Option<Ty<'tcx>> {
|
||||||
match args.get(index - 1) {
|
match args.get(index - 1) {
|
||||||
Some(GenericArg::Type(ty)) => Some(hir_ty_to_ty(tcx, ty)),
|
Some(GenericArg::Type(ty)) => Some(lower_ty(tcx, ty)),
|
||||||
Some(_) => None,
|
Some(_) => None,
|
||||||
None => Some(tcx.type_of(generics.params[index].def_id).skip_binder()),
|
None => Some(tcx.type_of(generics.params[index].def_id).skip_binder()),
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ use clippy_utils::{path_def_id, qpath_generic_tys};
|
|||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::{self as hir, QPath, TyKind};
|
use rustc_hir::{self as hir, QPath, TyKind};
|
||||||
use rustc_hir_analysis::hir_ty_to_ty;
|
use rustc_hir_analysis::lower_ty;
|
||||||
use rustc_lint::LateContext;
|
use rustc_lint::LateContext;
|
||||||
use rustc_middle::ty::TypeVisitableExt;
|
use rustc_middle::ty::TypeVisitableExt;
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
@ -56,10 +56,10 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>, qpath:
|
|||||||
};
|
};
|
||||||
let inner_span = match qpath_generic_tys(inner_qpath).next() {
|
let inner_span = match qpath_generic_tys(inner_qpath).next() {
|
||||||
Some(hir_ty) => {
|
Some(hir_ty) => {
|
||||||
// Reallocation of a fat pointer causes it to become thin. `hir_ty_to_ty` is safe to use
|
// Reallocation of a fat pointer causes it to become thin. `lower_ty` is safe to use
|
||||||
// here because `mod.rs` guarantees this lint is only run on types outside of bodies and
|
// here because `mod.rs` guarantees this lint is only run on types outside of bodies and
|
||||||
// is not run on locals.
|
// is not run on locals.
|
||||||
let ty = hir_ty_to_ty(cx.tcx, hir_ty);
|
let ty = lower_ty(cx.tcx, hir_ty);
|
||||||
if ty.has_escaping_bound_vars() || !ty.is_sized(cx.tcx, cx.param_env) {
|
if ty.has_escaping_bound_vars() || !ty.is_sized(cx.tcx, cx.param_env) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ use clippy_utils::source::snippet;
|
|||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::{self as hir, GenericArg, LangItem, QPath, TyKind};
|
use rustc_hir::{self as hir, GenericArg, LangItem, QPath, TyKind};
|
||||||
use rustc_hir_analysis::hir_ty_to_ty;
|
use rustc_hir_analysis::lower_ty;
|
||||||
use rustc_lint::LateContext;
|
use rustc_lint::LateContext;
|
||||||
use rustc_middle::ty::layout::LayoutOf;
|
use rustc_middle::ty::layout::LayoutOf;
|
||||||
use rustc_middle::ty::TypeVisitableExt;
|
use rustc_middle::ty::TypeVisitableExt;
|
||||||
@ -35,7 +35,7 @@ pub(super) fn check<'tcx>(
|
|||||||
&& let Some(GenericArg::Type(boxed_ty)) = last.args.first()
|
&& let Some(GenericArg::Type(boxed_ty)) = last.args.first()
|
||||||
// extract allocator from the Box for later
|
// extract allocator from the Box for later
|
||||||
&& let boxed_alloc_ty = last.args.get(1)
|
&& let boxed_alloc_ty = last.args.get(1)
|
||||||
&& let ty_ty = hir_ty_to_ty(cx.tcx, boxed_ty)
|
&& let ty_ty = lower_ty(cx.tcx, boxed_ty)
|
||||||
&& !ty_ty.has_escaping_bound_vars()
|
&& !ty_ty.has_escaping_bound_vars()
|
||||||
&& ty_ty.is_sized(cx.tcx, cx.param_env)
|
&& ty_ty.is_sized(cx.tcx, cx.param_env)
|
||||||
&& let Ok(ty_ty_size) = cx.layout_of(ty_ty).map(|l| l.size.bytes())
|
&& let Ok(ty_ty_size) = cx.layout_of(ty_ty).map(|l| l.size.bytes())
|
||||||
@ -55,7 +55,7 @@ pub(super) fn check<'tcx>(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
(Some(GenericArg::Type(l)), Some(GenericArg::Type(r))) =>
|
(Some(GenericArg::Type(l)), Some(GenericArg::Type(r))) =>
|
||||||
hir_ty_to_ty(cx.tcx, l) == hir_ty_to_ty(cx.tcx, r),
|
lower_ty(cx.tcx, l) == lower_ty(cx.tcx, r),
|
||||||
_ => false
|
_ => false
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@ use rustc_hir::def::{DefKind, Res};
|
|||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_hir::intravisit::{walk_body, walk_expr, FnKind, Visitor};
|
use rustc_hir::intravisit::{walk_body, walk_expr, FnKind, Visitor};
|
||||||
use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId, Item, ItemKind, Node, QPath, TyKind};
|
use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId, Item, ItemKind, Node, QPath, TyKind};
|
||||||
use rustc_hir_analysis::hir_ty_to_ty;
|
use rustc_hir_analysis::lower_ty;
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::hir::map::Map;
|
use rustc_middle::hir::map::Map;
|
||||||
use rustc_middle::hir::nested_filter;
|
use rustc_middle::hir::nested_filter;
|
||||||
@ -74,7 +74,7 @@ fn get_hir_ty_def_id<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: rustc_hir::Ty<'tcx>) -> Op
|
|||||||
match qpath {
|
match qpath {
|
||||||
QPath::Resolved(_, path) => path.res.opt_def_id(),
|
QPath::Resolved(_, path) => path.res.opt_def_id(),
|
||||||
QPath::TypeRelative(_, _) => {
|
QPath::TypeRelative(_, _) => {
|
||||||
let ty = hir_ty_to_ty(tcx, &hir_ty);
|
let ty = lower_ty(tcx, &hir_ty);
|
||||||
|
|
||||||
match ty.kind() {
|
match ty.kind() {
|
||||||
ty::Alias(ty::Projection, proj) => {
|
ty::Alias(ty::Projection, proj) => {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use clippy_utils::diagnostics::span_lint;
|
use clippy_utils::diagnostics::span_lint;
|
||||||
use rustc_hir::intravisit::FnKind;
|
use rustc_hir::intravisit::FnKind;
|
||||||
use rustc_hir::{Body, Expr, ExprKind, FnDecl, FnRetTy, TyKind, UnOp};
|
use rustc_hir::{Body, Expr, ExprKind, FnDecl, FnRetTy, TyKind, UnOp};
|
||||||
use rustc_hir_analysis::hir_ty_to_ty;
|
use rustc_hir_analysis::lower_ty;
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::lint::in_external_macro;
|
use rustc_middle::lint::in_external_macro;
|
||||||
use rustc_session::declare_lint_pass;
|
use rustc_session::declare_lint_pass;
|
||||||
@ -71,7 +71,7 @@ impl LateLintPass<'_> for UninhabitedReferences {
|
|||||||
}
|
}
|
||||||
if let FnRetTy::Return(hir_ty) = fndecl.output
|
if let FnRetTy::Return(hir_ty) = fndecl.output
|
||||||
&& let TyKind::Ref(_, mut_ty) = hir_ty.kind
|
&& let TyKind::Ref(_, mut_ty) = hir_ty.kind
|
||||||
&& hir_ty_to_ty(cx.tcx, mut_ty.ty).is_privately_uninhabited(cx.tcx, cx.param_env)
|
&& lower_ty(cx.tcx, mut_ty.ty).is_privately_uninhabited(cx.tcx, cx.param_env)
|
||||||
{
|
{
|
||||||
span_lint(
|
span_lint(
|
||||||
cx,
|
cx,
|
||||||
|
@ -11,7 +11,7 @@ use rustc_hir::{
|
|||||||
self as hir, Expr, ExprKind, FnRetTy, FnSig, GenericArgsParentheses, GenericParam, GenericParamKind, HirId, Impl,
|
self as hir, Expr, ExprKind, FnRetTy, FnSig, GenericArgsParentheses, GenericParam, GenericParamKind, HirId, Impl,
|
||||||
ImplItemKind, Item, ItemKind, Pat, PatKind, Path, QPath, Ty, TyKind,
|
ImplItemKind, Item, ItemKind, Pat, PatKind, Path, QPath, Ty, TyKind,
|
||||||
};
|
};
|
||||||
use rustc_hir_analysis::hir_ty_to_ty;
|
use rustc_hir_analysis::lower_ty;
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::ty::Ty as MiddleTy;
|
use rustc_middle::ty::Ty as MiddleTy;
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
@ -193,7 +193,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn check_body(&mut self, _: &LateContext<'_>, _: &hir::Body<'_>) {
|
fn check_body(&mut self, _: &LateContext<'_>, _: &hir::Body<'_>) {
|
||||||
// `hir_ty_to_ty` cannot be called in `Body`s or it will panic (sometimes). But in bodies
|
// `lower_ty` cannot be called in `Body`s or it will panic (sometimes). But in bodies
|
||||||
// we can use `cx.typeck_results.node_type(..)` to get the `ty::Ty` from a `hir::Ty`.
|
// we can use `cx.typeck_results.node_type(..)` to get the `ty::Ty` from a `hir::Ty`.
|
||||||
// However the `node_type()` method can *only* be called in bodies.
|
// However the `node_type()` method can *only* be called in bodies.
|
||||||
if let Some(&mut StackItem::Check { ref mut in_body, .. }) = self.stack.last_mut() {
|
if let Some(&mut StackItem::Check { ref mut in_body, .. }) = self.stack.last_mut() {
|
||||||
@ -224,7 +224,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
|
|||||||
&& let ty = if in_body > 0 {
|
&& let ty = if in_body > 0 {
|
||||||
cx.typeck_results().node_type(hir_ty.hir_id)
|
cx.typeck_results().node_type(hir_ty.hir_id)
|
||||||
} else {
|
} else {
|
||||||
hir_ty_to_ty(cx.tcx, hir_ty)
|
lower_ty(cx.tcx, hir_ty)
|
||||||
}
|
}
|
||||||
&& let impl_ty = cx.tcx.type_of(impl_id).instantiate_identity()
|
&& let impl_ty = cx.tcx.type_of(impl_id).instantiate_identity()
|
||||||
&& same_type_and_consts(ty, impl_ty)
|
&& same_type_and_consts(ty, impl_ty)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use clippy_utils::diagnostics::span_lint_and_help;
|
use clippy_utils::diagnostics::span_lint_and_help;
|
||||||
use clippy_utils::ty::{is_normalizable, is_type_diagnostic_item};
|
use clippy_utils::ty::{is_normalizable, is_type_diagnostic_item};
|
||||||
use rustc_hir::{self as hir, HirId, ItemKind, Node};
|
use rustc_hir::{self as hir, HirId, ItemKind, Node};
|
||||||
use rustc_hir_analysis::hir_ty_to_ty;
|
use rustc_hir_analysis::lower_ty;
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::ty::layout::LayoutOf as _;
|
use rustc_middle::ty::layout::LayoutOf as _;
|
||||||
use rustc_middle::ty::{Adt, Ty, TypeVisitableExt};
|
use rustc_middle::ty::{Adt, Ty, TypeVisitableExt};
|
||||||
@ -91,5 +91,5 @@ fn ty_from_hir_ty<'tcx>(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'t
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| hir_ty_to_ty(cx.tcx, hir_ty))
|
.unwrap_or_else(|| lower_ty(cx.tcx, hir_ty))
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//! This is a minimal reproducer for the ICE in https://github.com/rust-lang/rust-clippy/pull/6179.
|
//! This is a minimal reproducer for the ICE in https://github.com/rust-lang/rust-clippy/pull/6179.
|
||||||
//! The ICE is mainly caused by using `hir_ty_to_ty`. See the discussion in the PR for details.
|
//! The ICE is mainly caused by using `lower_ty`. See the discussion in the PR for details.
|
||||||
|
|
||||||
#![warn(clippy::use_self)]
|
#![warn(clippy::use_self)]
|
||||||
#![allow(dead_code, clippy::let_with_type_underscore)]
|
#![allow(dead_code, clippy::let_with_type_underscore)]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//@ run-pass
|
//@ run-pass
|
||||||
// Test that astconv doesn't forget about mutability of &mut str
|
// Test that HIR ty lowering doesn't forget about mutability of `&mut str`.
|
||||||
|
|
||||||
//@ pretty-expanded FIXME #23616
|
//@ pretty-expanded FIXME #23616
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// astconv uses `FreshTy(0)` as a dummy `Self` type when instanciating trait objects.
|
// HIR ty lowering uses `FreshTy(0)` as a dummy `Self` type when instanciating trait objects.
|
||||||
// This `FreshTy(0)` can leak into substs, causing ICEs in several places.
|
// This `FreshTy(0)` can leak into substs, causing ICEs in several places.
|
||||||
|
|
||||||
#![feature(trait_alias)]
|
#![feature(trait_alias)]
|
||||||
|
@ -499,6 +499,10 @@ of `ObligationCtxt`.
|
|||||||
"""
|
"""
|
||||||
cc = ["@lcnr", "@compiler-errors"]
|
cc = ["@lcnr", "@compiler-errors"]
|
||||||
|
|
||||||
|
[mentions."compiler/rustc_hir_analysis/src/hir_ty_lowering"]
|
||||||
|
message = "HIR ty lowering was modified"
|
||||||
|
cc = ["@fmease"]
|
||||||
|
|
||||||
[mentions."compiler/rustc_error_codes/src/lib.rs"]
|
[mentions."compiler/rustc_error_codes/src/lib.rs"]
|
||||||
message = "Some changes occurred in diagnostic error codes"
|
message = "Some changes occurred in diagnostic error codes"
|
||||||
cc = ["@GuillaumeGomez"]
|
cc = ["@GuillaumeGomez"]
|
||||||
|
Loading…
Reference in New Issue
Block a user