Auto merge of #116163 - compiler-errors:lazyness, r=oli-obk
Don't store lazyness in `DefKind::TyAlias` 1. Don't store lazyness of a type alias in its `DefKind`, but instead via a query. 2. This allows us to treat type aliases as lazy if `#[feature(lazy_type_alias)]` *OR* if the alias contains a TAIT, rather than having checks for both in separate parts of the codebase. r? `@oli-obk` cc `@fmease`
This commit is contained in:
commit
6b99cf1d35
51 changed files with 128 additions and 189 deletions
|
@ -909,23 +909,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
let tcx = self.tcx();
|
||||
let args = self.ast_path_args_for_ty(span, did, item_segment);
|
||||
|
||||
if let DefKind::TyAlias { lazy: true } = tcx.def_kind(did) {
|
||||
if let DefKind::TyAlias = tcx.def_kind(did)
|
||||
&& tcx.type_alias_is_lazy(did)
|
||||
{
|
||||
// Type aliases defined in crates that have the
|
||||
// feature `lazy_type_alias` enabled get encoded as a type alias that normalization will
|
||||
// then actually instantiate the where bounds of.
|
||||
let alias_ty = tcx.mk_alias_ty(did, args);
|
||||
Ty::new_alias(tcx, ty::Weak, alias_ty)
|
||||
} else {
|
||||
let ty = tcx.at(span).type_of(did);
|
||||
if ty.skip_binder().has_opaque_types() {
|
||||
// Type aliases referring to types that contain opaque types (but aren't just directly
|
||||
// referencing a single opaque type) get encoded as a type alias that normalization will
|
||||
// then actually instantiate the where bounds of.
|
||||
let alias_ty = tcx.mk_alias_ty(did, args);
|
||||
Ty::new_alias(tcx, ty::Weak, alias_ty)
|
||||
} else {
|
||||
ty.instantiate(tcx, args)
|
||||
}
|
||||
tcx.at(span).type_of(did).instantiate(tcx, args)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2164,7 +2157,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
}
|
||||
Res::Def(
|
||||
DefKind::Enum
|
||||
| DefKind::TyAlias { .. }
|
||||
| DefKind::TyAlias
|
||||
| DefKind::Struct
|
||||
| DefKind::Union
|
||||
| DefKind::ForeignTy,
|
||||
|
|
|
@ -640,7 +640,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
|
|||
check_opaque(tcx, id);
|
||||
}
|
||||
}
|
||||
DefKind::TyAlias { .. } => {
|
||||
DefKind::TyAlias => {
|
||||
let pty_ty = tcx.type_of(id.owner_id).instantiate_identity();
|
||||
let generics = tcx.generics_of(id.owner_id);
|
||||
check_type_params_are_used(tcx, &generics, pty_ty);
|
||||
|
|
|
@ -246,9 +246,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
|
|||
// `ForeignItem`s are handled separately.
|
||||
hir::ItemKind::ForeignMod { .. } => {}
|
||||
hir::ItemKind::TyAlias(hir_ty, ast_generics) => {
|
||||
if tcx.features().lazy_type_alias
|
||||
|| tcx.type_of(item.owner_id).skip_binder().has_opaque_types()
|
||||
{
|
||||
if tcx.type_alias_is_lazy(item.owner_id) {
|
||||
// Bounds of lazy type aliases and of eager ones that contain opaque types are respected.
|
||||
// E.g: `type X = impl Trait;`, `type X = (impl Trait, Y);`.
|
||||
check_item_type(tcx, def_id, hir_ty.span, UnsizedHandling::Allow);
|
||||
|
@ -1711,10 +1709,8 @@ fn check_variances_for_type_defn<'tcx>(
|
|||
}
|
||||
}
|
||||
ItemKind::TyAlias(..) => {
|
||||
let ty = tcx.type_of(item.owner_id).instantiate_identity();
|
||||
|
||||
if tcx.features().lazy_type_alias || ty.has_opaque_types() {
|
||||
if ty.references_error() {
|
||||
if tcx.type_alias_is_lazy(item.owner_id) {
|
||||
if tcx.type_of(item.owner_id).skip_binder().references_error() {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -58,6 +58,7 @@ pub fn provide(providers: &mut Providers) {
|
|||
*providers = Providers {
|
||||
type_of: type_of::type_of,
|
||||
type_of_opaque: type_of::type_of_opaque,
|
||||
type_alias_is_lazy: type_of::type_alias_is_lazy,
|
||||
item_bounds: item_bounds::item_bounds,
|
||||
explicit_item_bounds: item_bounds::explicit_item_bounds,
|
||||
generics_of: generics_of::generics_of,
|
||||
|
|
|
@ -1519,7 +1519,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||
DefKind::Struct
|
||||
| DefKind::Union
|
||||
| DefKind::Enum
|
||||
| DefKind::TyAlias { .. }
|
||||
| DefKind::TyAlias
|
||||
| DefKind::Trait,
|
||||
def_id,
|
||||
) if depth == 0 => Some(def_id),
|
||||
|
@ -2029,7 +2029,7 @@ fn is_late_bound_map(
|
|||
|
||||
hir::TyKind::Path(hir::QPath::Resolved(
|
||||
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
|
||||
// args to be unconstrained.
|
||||
|
|
|
@ -623,3 +623,25 @@ fn check_feature_inherent_assoc_ty(tcx: TyCtxt<'_>, span: Span) {
|
|||
.emit();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_alias_is_lazy<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool {
|
||||
use hir::intravisit::Visitor;
|
||||
if tcx.features().lazy_type_alias {
|
||||
return true;
|
||||
}
|
||||
struct HasTait {
|
||||
has_type_alias_impl_trait: bool,
|
||||
}
|
||||
impl<'tcx> Visitor<'tcx> for HasTait {
|
||||
fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) {
|
||||
if let hir::TyKind::OpaqueDef(..) = t.kind {
|
||||
self.has_type_alias_impl_trait = true;
|
||||
} else {
|
||||
hir::intravisit::walk_ty(self, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut has_tait = HasTait { has_type_alias_impl_trait: false };
|
||||
has_tait.visit_ty(tcx.hir().expect_item(def_id).expect_ty_alias().0);
|
||||
has_tait.has_type_alias_impl_trait
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
use hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
|
||||
|
||||
use super::terms::VarianceTerm::*;
|
||||
|
@ -78,9 +78,7 @@ pub fn add_constraints_from_crate<'a, 'tcx>(
|
|||
}
|
||||
}
|
||||
DefKind::Fn | DefKind::AssocFn => constraint_cx.build_constraints_for_item(def_id),
|
||||
DefKind::TyAlias { lazy }
|
||||
if lazy || tcx.type_of(def_id).instantiate_identity().has_opaque_types() =>
|
||||
{
|
||||
DefKind::TyAlias if tcx.type_alias_is_lazy(def_id) => {
|
||||
constraint_cx.build_constraints_for_item(def_id)
|
||||
}
|
||||
_ => {}
|
||||
|
@ -110,8 +108,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
|
||||
// The type as returned by `type_of` is the underlying type and generally not a weak projection.
|
||||
// Therefore we need to check the `DefKind` first.
|
||||
if let DefKind::TyAlias { lazy } = tcx.def_kind(def_id)
|
||||
&& (lazy || ty.has_opaque_types())
|
||||
if let DefKind::TyAlias = tcx.def_kind(def_id)
|
||||
&& tcx.type_alias_is_lazy(def_id)
|
||||
{
|
||||
self.add_constraints_from_ty(current_item, ty, self.covariant);
|
||||
return;
|
||||
|
|
|
@ -8,7 +8,7 @@ use rustc_hir::def::DefKind;
|
|||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::{self, CrateVariancesMap, GenericArgsRef, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt};
|
||||
use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable};
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
/// Defines the `TermsContext` basically houses an arena where we can
|
||||
|
@ -56,9 +56,7 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
|
|||
let crate_map = tcx.crate_variances(());
|
||||
return crate_map.variances.get(&item_def_id.to_def_id()).copied().unwrap_or(&[]);
|
||||
}
|
||||
DefKind::TyAlias { lazy }
|
||||
if lazy || tcx.type_of(item_def_id).instantiate_identity().has_opaque_types() =>
|
||||
{
|
||||
DefKind::TyAlias if tcx.type_alias_is_lazy(item_def_id) => {
|
||||
// These are inferred.
|
||||
let crate_map = tcx.crate_variances(());
|
||||
return crate_map.variances.get(&item_def_id.to_def_id()).copied().unwrap_or(&[]);
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
use rustc_arena::DroplessArena;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{LocalDefId, LocalDefIdMap};
|
||||
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use std::fmt;
|
||||
|
||||
use self::VarianceTerm::*;
|
||||
|
@ -97,9 +97,7 @@ pub fn determine_parameters_to_be_inferred<'a, 'tcx>(
|
|||
}
|
||||
}
|
||||
DefKind::Fn | DefKind::AssocFn => terms_cx.add_inferreds_for_item(def_id),
|
||||
DefKind::TyAlias { lazy }
|
||||
if lazy || tcx.type_of(def_id).instantiate_identity().has_opaque_types() =>
|
||||
{
|
||||
DefKind::TyAlias if tcx.type_alias_is_lazy(def_id) => {
|
||||
terms_cx.add_inferreds_for_item(def_id)
|
||||
}
|
||||
_ => {}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue