Skip to content
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
9 changes: 1 addition & 8 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -974,7 +974,6 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
tcx.ensure_ok().generics_of(def_id);
tcx.ensure_ok().type_of(def_id);
tcx.ensure_ok().predicates_of(def_id);
check_type_alias_type_params_are_used(tcx, def_id);
let ty = tcx.type_of(def_id).instantiate_identity();
let span = tcx.def_span(def_id);
if tcx.type_alias_is_lazy(def_id) {
Expand All @@ -988,8 +987,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
check_where_clauses(wfcx, def_id);
Ok(())
}));
check_variances_for_type_defn(tcx, def_id);
} else {
check_type_alias_type_params_are_used(tcx, def_id);
res = res.and(enter_wf_checking_ctxt(tcx, def_id, |wfcx| {
// HACK: We sometimes incidentally check that const arguments have the correct
// type as a side effect of the anon const desugaring. To make this "consistent"
Expand Down Expand Up @@ -2064,12 +2063,6 @@ 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.
return;
}

let generics = tcx.generics_of(def_id);
if generics.own_counts().types == 0 {
return;
Expand Down
23 changes: 4 additions & 19 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2049,12 +2049,6 @@ pub(super) fn check_variances_for_type_defn<'tcx>(tcx: TyCtxt<'tcx>, def_id: Loc
DefKind::Enum | DefKind::Struct | DefKind::Union => {
// Ok
}
DefKind::TyAlias => {
assert!(
tcx.type_alias_is_lazy(def_id),
"should not be computing variance of non-free type alias"
);
}
kind => span_bug!(tcx.def_span(def_id), "cannot compute the variances of {kind:?}"),
}

Expand Down Expand Up @@ -2206,7 +2200,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 @@ -2288,9 +2281,6 @@ impl<'tcx> IsProbablyCyclical<'tcx> {
.visit_with(self)
})
}
DefKind::TyAlias if self.tcx.type_alias_is_lazy(def_id) => {
self.tcx.type_of(def_id).instantiate_identity().skip_norm_wip().visit_with(self)
}
_ => ControlFlow::Continue(()),
}
}
Expand All @@ -2300,17 +2290,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::AliasTy { kind: ty::Free { def_id }, .. }) => Some(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
4 changes: 3 additions & 1 deletion compiler/rustc_hir_analysis/src/coherence/orphan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ pub(crate) fn orphan_check_impl(

if tcx.trait_is_auto(trait_def_id) {
let self_ty = trait_ref.self_ty();
// FIXME(lazy_type_alias): Audit.
let self_ty = tcx.expand_free_alias_tys(self_ty);

// If the impl is in the same crate as the auto-trait, almost anything
// goes.
Expand Down Expand Up @@ -190,7 +192,7 @@ pub(crate) fn orphan_check_impl(
ty::Projection { .. } => "associated type",
// type Foo = (impl Sized, bool)
// impl AutoTrait for Foo {}
ty::Free { .. } => "type alias",
ty::Free { .. } => bug!("unexpected free alias type"),
// type Opaque = impl Trait;
// impl AutoTrait for Opaque {}
ty::Opaque { .. } => "opaque type",
Expand Down
19 changes: 18 additions & 1 deletion compiler/rustc_hir_analysis/src/collect/predicates_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,24 @@ pub(super) fn explicit_predicates_of<'tcx>(
predicates: { tcx.arena.alloc_from_iter(filtered_predicates) },
};
}
gather_explicit_predicates_of(tcx, def_id)

let predicates = gather_explicit_predicates_of(tcx, def_id);

// // FIXME: FIXME: FIXME: MAJOR HACK: SAD.
// if let DefKind::TyAlias = def_kind
// && !tcx.type_alias_is_lazy(def_id)
// {
// return GenericPredicates {
// parent: None,
// predicates: tcx.arena.alloc_from_iter(
// predicates.predicates.iter().copied().filter(|(clause, _)| {
// matches!(clause.kind().skip_binder(), ty::ClauseKind::ConstArgHasType(..))
// }),
// ),
// };
// }

predicates
}
}

Expand Down
7 changes: 1 addition & 6 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1211,12 +1211,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let tcx = self.tcx();
let args = self.lower_generic_args_of_path_segment(span, def_id, item_segment);

if let DefKind::TyAlias = tcx.def_kind(def_id)
&& tcx.type_alias_is_lazy(def_id)
{
// 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.
if let DefKind::TyAlias = tcx.def_kind(def_id) {
let alias_ty = ty::AliasTy::new_from_args(tcx, ty::Free { def_id }, args);
Ty::new_alias(tcx, alias_ty)
} else {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub(super) fn infer_predicates(
}
}

DefKind::TyAlias if tcx.type_alias_is_lazy(item_did) => {
DefKind::TyAlias => {
insert_required_predicates_to_be_wf(
tcx,
tcx.type_of(item_did).instantiate_identity().skip_norm_wip(),
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/outlives/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub(super) fn inferred_outlives_of(
let crate_map = tcx.inferred_outlives_crate(());
crate_map.predicates.get(&item_def_id.to_def_id()).copied().unwrap_or(&[])
}
DefKind::TyAlias if tcx.type_alias_is_lazy(item_def_id) => {
DefKind::TyAlias => {
let crate_map = tcx.inferred_outlives_crate(());
crate_map.predicates.get(&item_def_id.to_def_id()).copied().unwrap_or(&[])
}
Expand Down
20 changes: 4 additions & 16 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().skip_norm_wip();

// 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 @@ -216,14 +204,13 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
/// Adds constraints appropriate for an instance of `ty` appearing
/// in a context with the generics defined in `generics` and
/// ambient variance `variance`
#[instrument(level = "debug", skip(self, current))]
fn add_constraints_from_ty(
&mut self,
current: &CurrentItem,
ty: Ty<'tcx>,
variance: VarianceTermPtr<'a>,
) {
debug!("add_constraints_from_ty(ty={:?}, variance={:?})", ty, variance);

match *ty.kind() {
ty::Bool
| ty::Char
Expand Down Expand Up @@ -281,8 +268,9 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
self.add_constraints_from_invariant_args(current, args, variance);
}

ty::Alias(ty::AliasTy { kind: ty::Free { def_id }, args, .. }) => {
self.add_constraints_from_args(current, def_id, args, variance);
ty::Alias(ty::AliasTy { kind: ty::Free { .. }, .. }) => {
let ty = self.tcx().expand_free_alias_tys(ty);
self.add_constraints_from_ty(current, ty, variance);
}

ty::Dynamic(data, r) => {
Expand Down
8 changes: 3 additions & 5 deletions compiler/rustc_hir_analysis/src/variance/dump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,16 @@ pub(crate) fn variances(tcx: TyCtxt<'_>) {
}

match tcx.def_kind(id) {
DefKind::AssocFn | DefKind::Fn | DefKind::Enum | DefKind::Struct | DefKind::Union => {}
DefKind::TyAlias if tcx.type_alias_is_lazy(id) => {}
DefKind::AssocFn | DefKind::Fn | DefKind::Enum | DefKind::Struct | DefKind::Union => {
tcx.dcx().span_err(tcx.def_span(id), format_variances(tcx, id.def_id));
}
kind => {
let message = format!(
"attr parsing didn't report an error for `#[{}]` on {kind:?}",
rustc_span::sym::rustc_dump_variances,
);
tcx.dcx().span_delayed_bug(tcx.def_span(id), message);
continue;
}
}

tcx.dcx().span_err(tcx.def_span(id), format_variances(tcx, id.def_id));
}
}
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 @@ -52,11 +52,6 @@ pub(super) fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Va
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
48 changes: 37 additions & 11 deletions compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -699,23 +699,49 @@ impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations {
return;
}

let Some(debug) = cx.tcx.get_diagnostic_item(sym::Debug) else { return };
let Some(debug_trait_def_id) = cx.tcx.get_diagnostic_item(sym::Debug) else { return };

let has_impl = cx
let ty = cx.tcx.type_of(item.owner_id);

// FIXME: unaudited potential fast path
if cx
.tcx
.non_blanket_impls_for_ty(
debug,
cx.tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip(),
debug_trait_def_id,
ty.instantiate_identity().skip_normalization(),
)
.next()
.is_some();
if !has_impl {
cx.emit_span_lint(
MISSING_DEBUG_IMPLEMENTATIONS,
item.span,
BuiltinMissingDebugImpl { tcx: cx.tcx, def_id: debug },
);
.is_some()
{
return;
}

// FIXME: unaudited

let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(cx.typing_env());
let ty = ty
.instantiate(cx.tcx, infcx.fresh_args_for_item(item.span, item.owner_id.to_def_id()))
.skip_normalization();

let trait_ref = ty::TraitRef::new(cx.tcx, debug_trait_def_id, [ty]);
let obligation = traits::Obligation {
cause: traits::ObligationCause::dummy(),
param_env,
recursion_depth: 0,
predicate: trait_ref.upcast(cx.tcx),
};

// FIXME: `predicate_must_hold_modulo_regions` is too strict but ideally we would use that
// wouldn't we? Kinda bad that free alias types "throw off" PMHMR, no?
if infcx.predicate_may_hold(&obligation) {
return;
}

cx.emit_span_lint(
MISSING_DEBUG_IMPLEMENTATIONS,
item.span,
BuiltinMissingDebugImpl { tcx: cx.tcx, def_id: debug_trait_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 @@ -1153,6 +1153,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 @@ -1166,7 +1167,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
14 changes: 1 addition & 13 deletions compiler/rustc_middle/src/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,19 +332,7 @@ rustc_queries! {
}
}

/// Returns whether the type alias given by `DefId` is lazy.
///
/// I.e., if the type alias expands / ought to expand to a [free] [alias type]
/// instead of the underlying aliased type.
///
/// Relevant for features `lazy_type_alias` and `type_alias_impl_trait`.
///
/// # Panics
///
/// This query *may* panic if the given definition is not a type alias.
///
/// [free]: rustc_middle::ty::Free
/// [alias type]: rustc_middle::ty::AliasTy
// NOTE: Whether this is a **checked** LTA.
query type_alias_is_lazy(key: DefId) -> bool {
desc {
"computing whether the type alias `{path}` is lazy",
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_middle/src/ty/context/impl_interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
// See trait-system-refactor-initiative#234.
}

fn expand_free_alias_tys<T: TypeFoldable<TyCtxt<'tcx>>>(self, t: T) -> T {
self.expand_free_alias_tys(t)
}

fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, t: T) -> T {
self.expand_abstract_consts(t)
}
Expand Down
Loading
Loading