Skip to content

[WIP] [crater-only] Make a watered-down version of lazy type aliases the default #122308

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

Closed
wants to merge 1 commit into from
Closed
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
20 changes: 14 additions & 6 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,15 +321,18 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
// `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) {
// 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);`.
let res = check_item_type(tcx, def_id, hir_ty.span, UnsizedHandling::Allow);
check_variances_for_type_defn(tcx, item, hir_generics);
res
// [[[[ /!\ CRATER-ONLY /!\ ]]]]
// Do not check the watered-down version of lazy type aliases for well-formedness.
let ty = tcx.type_of(item.owner_id).instantiate_identity();
let result = if !ty.references_error() && ty.has_opaque_types() {
check_item_type(tcx, def_id, hir_ty.span, UnsizedHandling::Allow)
} else {
Ok(())
};
if tcx.type_alias_is_lazy(item.owner_id) {
check_variances_for_type_defn(tcx, item, hir_generics);
}
result
}
_ => Ok(()),
};
Expand Down Expand Up @@ -1843,6 +1846,11 @@ fn check_variances_for_type_defn<'tcx>(
assert_eq!(ty_predicates.parent, None);
let variances = tcx.variances_of(item.owner_id);

if let ItemKind::TyAlias(..) = item.kind {
// [[[[ /!\ CRATER-ONLY /!\ ]]]]
return;
}

let mut constrained_parameters: FxHashSet<_> = variances
.iter()
.enumerate()
Expand Down
22 changes: 4 additions & 18 deletions compiler/rustc_hir_analysis/src/collect/type_of.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use core::ops::ControlFlow;
use rustc_errors::{Applicability, StashKey};
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
Expand Down Expand Up @@ -671,21 +670,8 @@ fn check_feature_inherent_assoc_ty(tcx: TyCtxt<'_>, span: Span) {
}
}

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;
impl<'tcx> Visitor<'tcx> for HasTait {
type Result = ControlFlow<()>;
fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) -> Self::Result {
if let hir::TyKind::OpaqueDef(..) = t.kind {
ControlFlow::Break(())
} else {
hir::intravisit::walk_ty(self, t)
}
}
}
HasTait.visit_ty(tcx.hir().expect_item(def_id).expect_ty_alias().0).is_break()
pub fn type_alias_is_lazy<'tcx>(_: TyCtxt<'tcx>, _: LocalDefId) -> bool {
// [[[[ /!\ CRATER-ONLY /!\ ]]]]
// All type aliases are lazy.
true
}
6 changes: 3 additions & 3 deletions compiler/rustc_hir_analysis/src/outlives/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub(crate) fn insert_outlives_predicate<'tcx>(
) {
// If the `'a` region is bound within the field type itself, we
// don't want to propagate this constraint to the header.
if !is_free_region(outlived_region) {
if !is_early_bound_region(outlived_region) {
return;
}

Expand Down Expand Up @@ -132,7 +132,7 @@ pub(crate) fn insert_outlives_predicate<'tcx>(
}

GenericArgKind::Lifetime(r) => {
if !is_free_region(r) {
if !is_early_bound_region(r) {
return;
}
required_predicates.entry(ty::OutlivesPredicate(kind, outlived_region)).or_insert(span);
Expand All @@ -144,7 +144,7 @@ pub(crate) fn insert_outlives_predicate<'tcx>(
}
}

fn is_free_region(region: Region<'_>) -> bool {
fn is_early_bound_region(region: Region<'_>) -> bool {
// First, screen for regions that might appear in a type header.
match *region {
// These correspond to `T: 'a` relationships:
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_infer/src/infer/outlives/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ fn compute_components<'tcx>(
// trait-ref. Therefore, if we see any higher-ranked regions,
// we simply fallback to the most restrictive rule, which
// requires that `Pi: 'a` for all `i`.
ty::Alias(_, alias_ty) => {
ty::Alias(ty::Projection | ty::Inherent | ty::Opaque, alias_ty) => {
if !alias_ty.has_escaping_bound_vars() {
// best case: no escaping regions, so push the
// projection and skip the subtree (thus generating no
Expand Down Expand Up @@ -178,6 +178,7 @@ fn compute_components<'tcx>(
ty::Float(..) | // OutlivesScalar
ty::Never | // ...
ty::Adt(..) | // OutlivesNominalType
ty::Alias(ty::Weak, _) |
ty::Foreign(..) | // OutlivesNominalType
ty::Str | // OutlivesScalar (ish)
ty::Slice(..) | // ...
Expand Down
11 changes: 9 additions & 2 deletions compiler/rustc_passes/src/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,8 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
i.kind,
hir::ItemKind::Impl(hir::Impl { of_trait: None, .. })
| hir::ItemKind::ForeignMod { .. }
// [[[[ /!\ CRATER-ONLY /!\ ]]]]
| hir::ItemKind::TyAlias(..)
) {
self.check_missing_stability(i.owner_id.def_id, i.span);
}
Expand All @@ -585,8 +587,13 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem<'tcx>) {
let impl_def_id = self.tcx.hir().get_parent_item(ii.hir_id());
if self.tcx.impl_trait_ref(impl_def_id).is_none() {
self.check_missing_stability(ii.owner_id.def_id, ii.span);
self.check_missing_const_stability(ii.owner_id.def_id, ii.span);
// [[[[ /!\ CRATER-ONLY /!\ ]]]]
// FIXME(fmease): The proper fix would be to peel_off_weak_alias_tys(impl_self_ty)
// and to get the owner this way. Not entirely sure.
if false {
self.check_missing_stability(ii.owner_id.def_id, ii.span);
self.check_missing_const_stability(ii.owner_id.def_id, ii.span);
}
}
intravisit::walk_impl_item(self, ii);
}
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_privacy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,8 @@ where
}
}
}
ty::Alias(kind @ (ty::Inherent | ty::Weak | ty::Projection), data) => {
// [[[[ /!\ CRATER-ONLY /!\ ]]]]
ty::Alias(kind @ (ty::Inherent | ty::Projection), data) => {
if V::SKIP_ASSOC_TYS {
// Visitors searching for minimal visibility/reachability want to
// conservatively approximate associated types like `Type::Alias`
Expand Down Expand Up @@ -234,6 +235,10 @@ where
)
};
}
// [[[[ /!\ CRATER-ONLY /!\ ]]]]
ty::Alias(ty::Weak, _) => {
return V::Result::output();
}
ty::Dynamic(predicates, ..) => {
// All traits in the list are considered the "primary" part of the type
// and are visited by shallow visitors.
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_trait_selection/src/traits/wf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
}
}

// NOTE(fmease): It should be fine to keep this.
ty::Alias(ty::Weak, ty::AliasTy { def_id, args, .. }) => {
let obligations = self.nominal_obligations(def_id, args);
self.out.extend(obligations);
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_traits/src/normalize_projection_ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ fn normalize_canonicalized_weak_ty<'tcx>(
tcx.infer_ctxt().enter_canonical_trait_query(
&goal,
|ocx, ParamEnvAnd { param_env, value: goal }| {
// NOTE(fmease): It should be fine to keep this for the crater run.
let obligations = tcx.predicates_of(goal.def_id).instantiate_own(tcx, goal.args).map(
|(predicate, span)| {
traits::Obligation::new(
Expand Down