Skip to content

Commit

Permalink
Auto merge of #116163 - compiler-errors:lazyness, r=<try>
Browse files Browse the repository at this point in the history
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`
  • Loading branch information
bors committed Sep 26, 2023
2 parents c614c17 + d6ce9ce commit b3abcff
Show file tree
Hide file tree
Showing 51 changed files with 128 additions and 189 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/diagnostics/region_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
// be the same as those of the ADT.
// FIXME: We should be able to do something similar to
// match_adt_and_segment in this case.
Res::Def(DefKind::TyAlias { .. }, _) => (),
Res::Def(DefKind::TyAlias, _) => (),
_ => {
if let Some(last_segment) = path.segments.last() {
if let Some(highlight) = self.match_adt_and_segment(
Expand Down
10 changes: 4 additions & 6 deletions compiler/rustc_hir/src/def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,7 @@ pub enum DefKind {
Variant,
Trait,
/// Type alias: `type Foo = Bar;`
TyAlias {
lazy: bool,
},
TyAlias,
/// Type from an `extern` block.
ForeignTy,
/// Trait alias: `trait IntIterator = Iterator<Item = i32>;`
Expand Down Expand Up @@ -143,7 +141,7 @@ impl DefKind {
DefKind::Ctor(CtorOf::Struct, CtorKind::Fn) => "tuple struct",
DefKind::Ctor(CtorOf::Struct, CtorKind::Const) => "unit struct",
DefKind::OpaqueTy => "opaque type",
DefKind::TyAlias { .. } => "type alias",
DefKind::TyAlias => "type alias",
DefKind::TraitAlias => "trait alias",
DefKind::AssocTy => "associated type",
DefKind::Union => "union",
Expand Down Expand Up @@ -199,7 +197,7 @@ impl DefKind {
| DefKind::Variant
| DefKind::Trait
| DefKind::OpaqueTy
| DefKind::TyAlias { .. }
| DefKind::TyAlias
| DefKind::ForeignTy
| DefKind::TraitAlias
| DefKind::AssocTy
Expand Down Expand Up @@ -250,7 +248,7 @@ impl DefKind {
| DefKind::Enum
| DefKind::Variant
| DefKind::Trait
| DefKind::TyAlias { .. }
| DefKind::TyAlias
| DefKind::ForeignTy
| DefKind::TraitAlias
| DefKind::AssocTy
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ impl Target {
DefKind::Mod => Target::Mod,
DefKind::ForeignMod => Target::ForeignMod,
DefKind::GlobalAsm => Target::GlobalAsm,
DefKind::TyAlias { .. } => Target::TyAlias,
DefKind::TyAlias => Target::TyAlias,
DefKind::OpaqueTy => Target::OpaqueTy,
DefKind::Enum => Target::Enum,
DefKind::Struct => Target::Struct,
Expand Down
17 changes: 5 additions & 12 deletions compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}

Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
10 changes: 3 additions & 7 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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.
Expand Down
22 changes: 22 additions & 0 deletions compiler/rustc_hir_analysis/src/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
10 changes: 4 additions & 6 deletions compiler/rustc_hir_analysis/src/variance/constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down Expand Up @@ -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)
}
_ => {}
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_hir_analysis/src/variance/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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(&[]);
Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_hir_analysis/src/variance/terms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down Expand Up @@ -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)
}
_ => {}
Expand Down
5 changes: 1 addition & 4 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1370,10 +1370,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
_ => bug!("unexpected type: {:?}", ty.normalized),
},
Res::Def(
DefKind::Struct | DefKind::Union | DefKind::TyAlias { .. } | DefKind::AssocTy,
_,
)
Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
| Res::SelfTyParam { .. }
| Res::SelfTyAlias { .. } => match ty.normalized.ty_adt_def() {
Some(adt) if !adt.is_enum() => {
Expand Down
5 changes: 1 addition & 4 deletions compiler/rustc_hir_typeck/src/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -557,10 +557,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
Ok(adt_def.variant_index_with_ctor_id(variant_ctor_id))
}
Res::Def(DefKind::Ctor(CtorOf::Struct, ..), _)
| Res::Def(
DefKind::Struct | DefKind::Union | DefKind::TyAlias { .. } | DefKind::AssocTy,
_,
)
| Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
| Res::SelfCtor(..)
| Res::SelfTyParam { .. }
| Res::SelfTyAlias { .. } => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -918,7 +918,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
//
// See the `need_type_info/issue-103053.rs` test for
// a example.
if !matches!(path.res, Res::Def(DefKind::TyAlias { .. }, _)) => {
if !matches!(path.res, Res::Def(DefKind::TyAlias, _)) => {
if let Some(ty) = self.opt_node_type(expr.hir_id)
&& let ty::Adt(_, args) = ty.kind()
{
Expand Down Expand Up @@ -1047,7 +1047,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
) => {
if tcx.res_generics_def_id(path.res) != Some(def.did()) {
match path.res {
Res::Def(DefKind::TyAlias { .. }, _) => {
Res::Def(DefKind::TyAlias, _) => {
// FIXME: Ideally we should support this. For that
// we have to map back from the self type to the
// type alias though. That's difficult.
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1454,13 +1454,13 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
let hir::ItemKind::TyAlias(hir_ty, type_alias_generics) = &item.kind else { return };

if cx.tcx.features().lazy_type_alias {
// Bounds of lazy type aliases are respected.
// Bounds of lazy type aliases and TAITs are respected.
if cx.tcx.type_alias_is_lazy(item.owner_id) {
return;
}

let ty = cx.tcx.type_of(item.owner_id).skip_binder();
if ty.has_opaque_types() || ty.has_inherent_projections() {
if ty.has_inherent_projections() {
// Bounds of type aliases that contain opaque types or inherent projections are respected.
// E.g: `type X = impl Trait;`, `type X = (impl Trait, Y);`, `type X = Type::Inherent;`.
return;
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ provide! { tcx, def_id, other, cdata,
inferred_outlives_of => { table_defaulted_array }
super_predicates_of => { table }
type_of => { table }
type_alias_is_lazy => { cdata.root.tables.type_alias_is_lazy.get(cdata, def_id.index) }
variances_of => { table }
fn_sig => { table }
codegen_fn_attrs => { table }
Expand Down
Loading

0 comments on commit b3abcff

Please sign in to comment.