Skip to content

[WIP] Expand free alias types during variance computation #141030

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1533,8 +1533,7 @@ fn detect_discriminant_duplicate<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)

fn check_type_alias_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) {
if tcx.type_alias_is_lazy(def_id) {
// Since we compute the variances for lazy type aliases and already reject bivariant
// parameters as unused, we can and should skip this check for lazy type aliases.
// FIXME(fmease): Explainer
return;
}

Expand Down
32 changes: 6 additions & 26 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,9 +322,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
hir::ItemKind::TraitAlias(..) => check_trait(tcx, item),
// `ForeignItem`s are handled separately.
hir::ItemKind::ForeignMod { .. } => Ok(()),
hir::ItemKind::TyAlias(_, hir_ty, hir_generics)
if tcx.type_alias_is_lazy(item.owner_id) =>
{
hir::ItemKind::TyAlias(_, hir_ty, _) if tcx.type_alias_is_lazy(item.owner_id) => {
let res = enter_wf_checking_ctxt(tcx, item.span, def_id, |wfcx| {
let ty = tcx.type_of(def_id).instantiate_identity();
let item_ty =
Expand All @@ -337,7 +335,6 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
check_where_clauses(wfcx, item.span, def_id);
Ok(())
});
check_variances_for_type_defn(tcx, item, hir_generics);
res
}
_ => Ok(()),
Expand Down Expand Up @@ -2044,15 +2041,7 @@ fn check_variances_for_type_defn<'tcx>(
hir_generics: &hir::Generics<'tcx>,
) {
match item.kind {
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) => {
// Ok
}
ItemKind::TyAlias(..) => {
assert!(
tcx.type_alias_is_lazy(item.owner_id),
"should not be computing variance of non-free type alias"
);
}
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) => {} // OK
kind => span_bug!(item.span, "cannot compute the variances of {kind:?}"),
}

Expand Down Expand Up @@ -2195,7 +2184,6 @@ fn report_bivariance<'tcx>(
errors::UnusedGenericParameterHelp::AdtNoPhantomData { param_name }
}
}
ItemKind::TyAlias(..) => errors::UnusedGenericParameterHelp::TyAlias { param_name },
item_kind => bug!("report_bivariance: unexpected item kind: {item_kind:?}"),
};

Expand Down Expand Up @@ -2268,9 +2256,6 @@ impl<'tcx> IsProbablyCyclical<'tcx> {
self.tcx.type_of(field.did).instantiate_identity().visit_with(self)
})
}
DefKind::TyAlias if self.tcx.type_alias_is_lazy(def_id) => {
self.tcx.type_of(def_id).instantiate_identity().visit_with(self)
}
_ => ControlFlow::Continue(()),
}
}
Expand All @@ -2280,17 +2265,12 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IsProbablyCyclical<'tcx> {
type Result = ControlFlow<(), ()>;

fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<(), ()> {
let def_id = match ty.kind() {
ty::Adt(adt_def, _) => Some(adt_def.did()),
ty::Alias(ty::Free, alias_ty) => Some(alias_ty.def_id),
_ => None,
};
if let Some(def_id) = def_id {
if def_id == self.item_def_id {
if let Some(adt_def) = ty.ty_adt_def() {
if adt_def.did() == self.item_def_id {
return ControlFlow::Break(());
}
if self.seen.insert(def_id) {
self.visit_def(def_id)?;
if self.seen.insert(adt_def.did()) {
self.visit_def(adt_def.did())?;
}
}
ty.super_visit_with(self)
Expand Down
22 changes: 5 additions & 17 deletions compiler/rustc_hir_analysis/src/variance/constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,6 @@ pub(crate) fn add_constraints_from_crate<'a, 'tcx>(
}
}
DefKind::Fn | DefKind::AssocFn => constraint_cx.build_constraints_for_item(def_id),
DefKind::TyAlias if tcx.type_alias_is_lazy(def_id) => {
constraint_cx.build_constraints_for_item(def_id)
}
_ => {}
}
}
Expand All @@ -107,15 +104,6 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
let current_item = &CurrentItem { inferred_start };
let ty = tcx.type_of(def_id).instantiate_identity();

// The type as returned by `type_of` is the underlying type and generally not a free alias.
// Therefore we need to check the `DefKind` first.
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;
}

match ty.kind() {
ty::Adt(def, _) => {
// Not entirely obvious: constraints on structs/enums do not
Expand Down Expand Up @@ -223,6 +211,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
variance: VarianceTermPtr<'a>,
) {
debug!("add_constraints_from_ty(ty={:?}, variance={:?})", ty, variance);
let ty = self.tcx().expand_free_alias_tys(ty);

match *ty.kind() {
ty::Bool
Expand Down Expand Up @@ -273,12 +262,11 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
self.add_constraints_from_args(current, def.did(), args, variance);
}

ty::Alias(ty::Projection | ty::Inherent | ty::Opaque, ref data) => {
self.add_constraints_from_invariant_args(current, data.args, variance);
}
// All free alias types should've been expanded beforehand.
ty::Alias(ty::Free, _) => panic!("unexpected free alias type"),

ty::Alias(ty::Free, ref data) => {
self.add_constraints_from_args(current, data.def_id, data.args, variance);
ty::Alias(_, ref alias_ty) => {
self.add_constraints_from_invariant_args(current, alias_ty.args, variance);
}

ty::Dynamic(data, r, _) => {
Expand Down
5 changes: 0 additions & 5 deletions compiler/rustc_hir_analysis/src/variance/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,6 @@ 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 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(&[]);
}
DefKind::AssocTy => match tcx.opt_rpitit_info(item_def_id.to_def_id()) {
Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
return variance_of_opaque(
Expand Down
3 changes: 0 additions & 3 deletions compiler/rustc_hir_analysis/src/variance/terms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,6 @@ pub(crate) fn determine_parameters_to_be_inferred<'a, 'tcx>(
}
}
DefKind::Fn | DefKind::AssocFn => terms_cx.add_inferreds_for_item(def_id),
DefKind::TyAlias if tcx.type_alias_is_lazy(def_id) => {
terms_cx.add_inferreds_for_item(def_id)
}
_ => {}
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1123,6 +1123,7 @@ fn should_encode_variances<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, def_kind: Def
| DefKind::Static { .. }
| DefKind::Const
| DefKind::ForeignMod
| DefKind::TyAlias
| DefKind::Impl { .. }
| DefKind::Trait
| DefKind::TraitAlias
Expand All @@ -1136,7 +1137,6 @@ fn should_encode_variances<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, def_kind: Def
| DefKind::Closure
| DefKind::ExternCrate
| DefKind::SyntheticCoroutineBody => false,
DefKind::TyAlias => tcx.type_alias_is_lazy(def_id),
}
}

Expand Down
Loading