Rollup merge of #114566 - fmease:type-alias-laziness-is-crate-specific, r=oli-obk
Store the laziness of type aliases in their `DefKind` Previously, we would treat paths referring to type aliases as *lazy* type aliases if the current crate had lazy type aliases enabled independently of whether the crate which the alias was defined in had the feature enabled or not. With this PR, the laziness of a type alias depends on the crate it is defined in. This generally makes more sense to me especially if / once lazy type aliases become the default in a new edition and we need to think about *edition interoperability*: Consider the hypothetical case where the dependency crate has an older edition (and thus eager type aliases), it exports a type alias with bounds & a where-clause (which are void but technically valid), the dependent crate has the latest edition (and thus lazy type aliases) and it uses that type alias. Arguably, the bounds should *not* be checked since at any time, the dependency crate should be allowed to change the bounds at will with a *non*-major version bump & without negatively affecting downstream crates. As for the reverse case (dependency: lazy type aliases, dependent: eager type aliases), I guess it rules out anything from slight confusion to mild annoyance from upstream crate authors that would be caused by the compiler ignoring the bounds of their type aliases in downstream crates with older editions. --- This fixes #114468 since before, my assumption that the type alias associated with a given weak projection was lazy (and therefore had its variances computed) did not necessarily hold in cross-crate scenarios (which [I kinda had a hunch about](https://github.com/rust-lang/rust/pull/114253#discussion_r1278608099)) as outlined above. Now it does hold. `@rustbot` label F-lazy_type_alias r? `@oli-obk`
This commit is contained in:
commit
3cd0a109a8
49 changed files with 208 additions and 93 deletions
|
@ -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(
|
||||
|
|
|
@ -61,7 +61,9 @@ pub enum DefKind {
|
|||
Variant,
|
||||
Trait,
|
||||
/// Type alias: `type Foo = Bar;`
|
||||
TyAlias,
|
||||
TyAlias {
|
||||
lazy: bool,
|
||||
},
|
||||
/// Type from an `extern` block.
|
||||
ForeignTy,
|
||||
/// Trait alias: `trait IntIterator = Iterator<Item = i32>;`
|
||||
|
@ -141,7 +143,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",
|
||||
|
@ -197,7 +199,7 @@ impl DefKind {
|
|||
| DefKind::Variant
|
||||
| DefKind::Trait
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::TyAlias
|
||||
| DefKind::TyAlias { .. }
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::TraitAlias
|
||||
| DefKind::AssocTy
|
||||
|
@ -248,7 +250,7 @@ impl DefKind {
|
|||
| DefKind::Enum
|
||||
| DefKind::Variant
|
||||
| DefKind::Trait
|
||||
| DefKind::TyAlias
|
||||
| DefKind::TyAlias { .. }
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::TraitAlias
|
||||
| DefKind::AssocTy
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -907,19 +907,21 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
did: DefId,
|
||||
item_segment: &hir::PathSegment<'_>,
|
||||
) -> Ty<'tcx> {
|
||||
let tcx = self.tcx();
|
||||
let args = self.ast_path_args_for_ty(span, did, item_segment);
|
||||
let ty = self.tcx().at(span).type_of(did);
|
||||
let ty = tcx.at(span).type_of(did);
|
||||
|
||||
if matches!(self.tcx().def_kind(did), DefKind::TyAlias)
|
||||
&& (ty.skip_binder().has_opaque_types() || self.tcx().features().lazy_type_alias)
|
||||
if let DefKind::TyAlias { lazy } = tcx.def_kind(did)
|
||||
&& (lazy || 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
|
||||
// referencing a single opaque type) as well as those 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 = self.tcx().mk_alias_ty(did, args);
|
||||
Ty::new_alias(self.tcx(), ty::Weak, alias_ty)
|
||||
let alias_ty = tcx.mk_alias_ty(did, args);
|
||||
Ty::new_alias(tcx, ty::Weak, alias_ty)
|
||||
} else {
|
||||
ty.instantiate(self.tcx(), args)
|
||||
ty.instantiate(tcx, args)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2158,7 +2160,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
}
|
||||
Res::Def(
|
||||
DefKind::Enum
|
||||
| DefKind::TyAlias
|
||||
| DefKind::TyAlias { .. }
|
||||
| DefKind::Struct
|
||||
| DefKind::Union
|
||||
| DefKind::ForeignTy,
|
||||
|
|
|
@ -728,7 +728,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);
|
||||
|
|
|
@ -1480,7 +1480,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),
|
||||
|
@ -1990,7 +1990,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.
|
||||
|
|
|
@ -78,9 +78,8 @@ pub fn add_constraints_from_crate<'a, 'tcx>(
|
|||
}
|
||||
}
|
||||
DefKind::Fn | DefKind::AssocFn => constraint_cx.build_constraints_for_item(def_id),
|
||||
DefKind::TyAlias
|
||||
if tcx.features().lazy_type_alias
|
||||
|| tcx.type_of(def_id).instantiate_identity().has_opaque_types() =>
|
||||
DefKind::TyAlias { lazy }
|
||||
if lazy || tcx.type_of(def_id).instantiate_identity().has_opaque_types() =>
|
||||
{
|
||||
constraint_cx.build_constraints_for_item(def_id)
|
||||
}
|
||||
|
@ -111,8 +110,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 = tcx.def_kind(def_id)
|
||||
&& (tcx.features().lazy_type_alias || ty.has_opaque_types())
|
||||
if let DefKind::TyAlias { lazy } = tcx.def_kind(def_id)
|
||||
&& (lazy || ty.has_opaque_types())
|
||||
{
|
||||
self.add_constraints_from_ty(current_item, ty, self.covariant);
|
||||
return;
|
||||
|
|
|
@ -56,9 +56,8 @@ 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.features().lazy_type_alias
|
||||
|| tcx.type_of(item_def_id).instantiate_identity().has_opaque_types() =>
|
||||
DefKind::TyAlias { lazy }
|
||||
if lazy || tcx.type_of(item_def_id).instantiate_identity().has_opaque_types() =>
|
||||
{
|
||||
// These are inferred.
|
||||
let crate_map = tcx.crate_variances(());
|
||||
|
|
|
@ -97,9 +97,8 @@ pub fn determine_parameters_to_be_inferred<'a, 'tcx>(
|
|||
}
|
||||
}
|
||||
DefKind::Fn | DefKind::AssocFn => terms_cx.add_inferreds_for_item(def_id),
|
||||
DefKind::TyAlias
|
||||
if tcx.features().lazy_type_alias
|
||||
|| tcx.type_of(def_id).instantiate_identity().has_opaque_types() =>
|
||||
DefKind::TyAlias { lazy }
|
||||
if lazy || tcx.type_of(def_id).instantiate_identity().has_opaque_types() =>
|
||||
{
|
||||
terms_cx.add_inferreds_for_item(def_id)
|
||||
}
|
||||
|
|
|
@ -1359,7 +1359,10 @@ 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() => {
|
||||
|
|
|
@ -557,7 +557,10 @@ 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 { .. } => {
|
||||
|
|
|
@ -951,7 +951,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()
|
||||
{
|
||||
|
@ -1080,7 +1080,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.
|
||||
|
|
|
@ -819,7 +819,7 @@ fn should_encode_span(def_kind: DefKind) -> bool {
|
|||
| DefKind::Enum
|
||||
| DefKind::Variant
|
||||
| DefKind::Trait
|
||||
| DefKind::TyAlias
|
||||
| DefKind::TyAlias { .. }
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::TraitAlias
|
||||
| DefKind::AssocTy
|
||||
|
@ -854,7 +854,7 @@ fn should_encode_attrs(def_kind: DefKind) -> bool {
|
|||
| DefKind::Enum
|
||||
| DefKind::Variant
|
||||
| DefKind::Trait
|
||||
| DefKind::TyAlias
|
||||
| DefKind::TyAlias { .. }
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::TraitAlias
|
||||
| DefKind::AssocTy
|
||||
|
@ -895,7 +895,7 @@ fn should_encode_expn_that_defined(def_kind: DefKind) -> bool {
|
|||
| DefKind::Variant
|
||||
| DefKind::Trait
|
||||
| DefKind::Impl { .. } => true,
|
||||
DefKind::TyAlias
|
||||
DefKind::TyAlias { .. }
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::TraitAlias
|
||||
| DefKind::AssocTy
|
||||
|
@ -930,7 +930,7 @@ fn should_encode_visibility(def_kind: DefKind) -> bool {
|
|||
| DefKind::Enum
|
||||
| DefKind::Variant
|
||||
| DefKind::Trait
|
||||
| DefKind::TyAlias
|
||||
| DefKind::TyAlias { .. }
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::TraitAlias
|
||||
| DefKind::AssocTy
|
||||
|
@ -974,7 +974,7 @@ fn should_encode_stability(def_kind: DefKind) -> bool {
|
|||
| DefKind::Const
|
||||
| DefKind::Fn
|
||||
| DefKind::ForeignMod
|
||||
| DefKind::TyAlias
|
||||
| DefKind::TyAlias { .. }
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::Enum
|
||||
| DefKind::Union
|
||||
|
@ -1067,9 +1067,8 @@ fn should_encode_variances<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, def_kind: Def
|
|||
| DefKind::Closure
|
||||
| DefKind::Generator
|
||||
| DefKind::ExternCrate => false,
|
||||
DefKind::TyAlias => {
|
||||
tcx.features().lazy_type_alias
|
||||
|| tcx.type_of(def_id).instantiate_identity().has_opaque_types()
|
||||
DefKind::TyAlias { lazy } => {
|
||||
lazy || tcx.type_of(def_id).instantiate_identity().has_opaque_types()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1081,7 +1080,7 @@ fn should_encode_generics(def_kind: DefKind) -> bool {
|
|||
| DefKind::Enum
|
||||
| DefKind::Variant
|
||||
| DefKind::Trait
|
||||
| DefKind::TyAlias
|
||||
| DefKind::TyAlias { .. }
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::TraitAlias
|
||||
| DefKind::AssocTy
|
||||
|
@ -1121,7 +1120,7 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
|
|||
| DefKind::Fn
|
||||
| DefKind::Const
|
||||
| DefKind::Static(..)
|
||||
| DefKind::TyAlias
|
||||
| DefKind::TyAlias { .. }
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::Impl { .. }
|
||||
| DefKind::AssocFn
|
||||
|
@ -1181,7 +1180,7 @@ fn should_encode_fn_sig(def_kind: DefKind) -> bool {
|
|||
| DefKind::Const
|
||||
| DefKind::Static(..)
|
||||
| DefKind::Ctor(..)
|
||||
| DefKind::TyAlias
|
||||
| DefKind::TyAlias { .. }
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::Impl { .. }
|
||||
|
@ -1222,7 +1221,7 @@ fn should_encode_constness(def_kind: DefKind) -> bool {
|
|||
| DefKind::AssocConst
|
||||
| DefKind::AnonConst
|
||||
| DefKind::Static(..)
|
||||
| DefKind::TyAlias
|
||||
| DefKind::TyAlias { .. }
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::Impl { of_trait: false }
|
||||
| DefKind::ForeignTy
|
||||
|
@ -1255,7 +1254,7 @@ fn should_encode_const(def_kind: DefKind) -> bool {
|
|||
| DefKind::Field
|
||||
| DefKind::Fn
|
||||
| DefKind::Static(..)
|
||||
| DefKind::TyAlias
|
||||
| DefKind::TyAlias { .. }
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::Impl { .. }
|
||||
|
|
|
@ -126,7 +126,8 @@ fixed_size_enum! {
|
|||
( Enum )
|
||||
( Variant )
|
||||
( Trait )
|
||||
( TyAlias )
|
||||
( TyAlias { lazy: false } )
|
||||
( TyAlias { lazy: true } )
|
||||
( ForeignTy )
|
||||
( TraitAlias )
|
||||
( AssocTy )
|
||||
|
|
|
@ -196,7 +196,9 @@ impl<'hir> Map<'hir> {
|
|||
ItemKind::Macro(_, macro_kind) => DefKind::Macro(macro_kind),
|
||||
ItemKind::Mod(..) => DefKind::Mod,
|
||||
ItemKind::OpaqueTy(..) => DefKind::OpaqueTy,
|
||||
ItemKind::TyAlias(..) => DefKind::TyAlias,
|
||||
ItemKind::TyAlias(..) => {
|
||||
DefKind::TyAlias { lazy: self.tcx.features().lazy_type_alias }
|
||||
}
|
||||
ItemKind::Enum(..) => DefKind::Enum,
|
||||
ItemKind::Struct(..) => DefKind::Struct,
|
||||
ItemKind::Union(..) => DefKind::Union,
|
||||
|
|
|
@ -231,7 +231,7 @@ rustc_queries! {
|
|||
action = {
|
||||
use rustc_hir::def::DefKind;
|
||||
match tcx.def_kind(key) {
|
||||
DefKind::TyAlias => "expanding type alias",
|
||||
DefKind::TyAlias { .. } => "expanding type alias",
|
||||
DefKind::TraitAlias => "expanding trait alias",
|
||||
_ => "computing type of",
|
||||
}
|
||||
|
|
|
@ -448,7 +448,7 @@ impl<'tcx> AdtDef<'tcx> {
|
|||
Res::Def(DefKind::Ctor(..), cid) => self.variant_with_ctor_id(cid),
|
||||
Res::Def(DefKind::Struct, _)
|
||||
| Res::Def(DefKind::Union, _)
|
||||
| Res::Def(DefKind::TyAlias, _)
|
||||
| Res::Def(DefKind::TyAlias { .. }, _)
|
||||
| Res::Def(DefKind::AssocTy, _)
|
||||
| Res::SelfTyParam { .. }
|
||||
| Res::SelfTyAlias { .. }
|
||||
|
|
|
@ -1062,7 +1062,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir().fn_decl_by_hir_id(hir_id)
|
||||
&& let hir::TyKind::Path(hir::QPath::Resolved(
|
||||
None,
|
||||
hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
|
||||
hir::Path { res: hir::def::Res::Def(DefKind::TyAlias { .. }, def_id), .. }, )) = hir_output.kind
|
||||
&& let Some(local_id) = def_id.as_local()
|
||||
&& let Some(alias_ty) = self.hir().get_by_def_id(local_id).alias_ty() // it is type alias
|
||||
&& let Some(alias_generics) = self.hir().get_by_def_id(local_id).generics()
|
||||
|
|
|
@ -492,7 +492,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IsSuggestableVisitor<'tcx> {
|
|||
Alias(Opaque, AliasTy { def_id, .. }) => {
|
||||
let parent = self.tcx.parent(def_id);
|
||||
let parent_ty = self.tcx.type_of(parent).instantiate_identity();
|
||||
if let DefKind::TyAlias | DefKind::AssocTy = self.tcx.def_kind(parent)
|
||||
if let DefKind::TyAlias { .. } | DefKind::AssocTy = self.tcx.def_kind(parent)
|
||||
&& let Alias(Opaque, AliasTy { def_id: parent_opaque_def_id, .. }) = *parent_ty.kind()
|
||||
&& parent_opaque_def_id == def_id
|
||||
{
|
||||
|
@ -576,7 +576,7 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for MakeSuggestableFolder<'tcx> {
|
|||
Alias(Opaque, AliasTy { def_id, .. }) => {
|
||||
let parent = self.tcx.parent(def_id);
|
||||
let parent_ty = self.tcx.type_of(parent).instantiate_identity();
|
||||
if let hir::def::DefKind::TyAlias | hir::def::DefKind::AssocTy = self.tcx.def_kind(parent)
|
||||
if let hir::def::DefKind::TyAlias { .. } | hir::def::DefKind::AssocTy = self.tcx.def_kind(parent)
|
||||
&& let Alias(Opaque, AliasTy { def_id: parent_opaque_def_id, .. }) = *parent_ty.kind()
|
||||
&& parent_opaque_def_id == def_id
|
||||
{
|
||||
|
|
|
@ -364,7 +364,7 @@ pub trait PrettyPrinter<'tcx>:
|
|||
self.write_str(get_local_name(&self, symbol, parent, parent_key).as_str())?;
|
||||
self.write_str("::")?;
|
||||
} else if let DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::Trait
|
||||
| DefKind::TyAlias | DefKind::Fn | DefKind::Const | DefKind::Static(_) = kind
|
||||
| DefKind::TyAlias { .. } | DefKind::Fn | DefKind::Const | DefKind::Static(_) = kind
|
||||
{
|
||||
} else {
|
||||
// If not covered above, like for example items out of `impl` blocks, fallback.
|
||||
|
@ -766,7 +766,7 @@ pub trait PrettyPrinter<'tcx>:
|
|||
|
||||
let parent = self.tcx().parent(def_id);
|
||||
match self.tcx().def_kind(parent) {
|
||||
DefKind::TyAlias | DefKind::AssocTy => {
|
||||
DefKind::TyAlias { .. } | DefKind::AssocTy => {
|
||||
// NOTE: I know we should check for NO_QUERIES here, but it's alright.
|
||||
// `type_of` on a type alias or assoc type should never cause a cycle.
|
||||
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: d, .. }) =
|
||||
|
@ -2983,7 +2983,7 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N
|
|||
|
||||
match child.res {
|
||||
def::Res::Def(DefKind::AssocTy, _) => {}
|
||||
def::Res::Def(DefKind::TyAlias, _) => {}
|
||||
def::Res::Def(DefKind::TyAlias { .. }, _) => {}
|
||||
def::Res::Def(defkind, def_id) => {
|
||||
if let Some(ns) = defkind.ns() {
|
||||
collect_fn(&child.ident, ns, def_id);
|
||||
|
|
|
@ -1223,7 +1223,7 @@ impl<'tcx> AliasTy<'tcx> {
|
|||
DefKind::AssocTy if let DefKind::Impl { of_trait: false } = tcx.def_kind(tcx.parent(self.def_id)) => ty::Inherent,
|
||||
DefKind::AssocTy => ty::Projection,
|
||||
DefKind::OpaqueTy => ty::Opaque,
|
||||
DefKind::TyAlias => ty::Weak,
|
||||
DefKind::TyAlias { .. } => ty::Weak,
|
||||
kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
|
||||
}
|
||||
}
|
||||
|
@ -1945,7 +1945,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
(kind, tcx.def_kind(alias_ty.def_id)),
|
||||
(ty::Opaque, DefKind::OpaqueTy)
|
||||
| (ty::Projection | ty::Inherent, DefKind::AssocTy)
|
||||
| (ty::Weak, DefKind::TyAlias)
|
||||
| (ty::Weak, DefKind::TyAlias { .. })
|
||||
);
|
||||
Ty::new(tcx, Alias(kind, alias_ty))
|
||||
}
|
||||
|
|
|
@ -156,7 +156,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
| DefKind::Enum
|
||||
| DefKind::Trait
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::TyAlias
|
||||
| DefKind::TyAlias { .. }
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::TraitAlias
|
||||
| DefKind::AssocTy
|
||||
|
|
|
@ -209,7 +209,7 @@ fn find_item_ty_spans(
|
|||
match ty.kind {
|
||||
hir::TyKind::Path(hir::QPath::Resolved(_, path)) => {
|
||||
if let Res::Def(kind, def_id) = path.res
|
||||
&& kind != DefKind::TyAlias {
|
||||
&& !matches!(kind, DefKind::TyAlias { .. }) {
|
||||
let check_params = def_id.as_local().map_or(true, |def_id| {
|
||||
if def_id == needle {
|
||||
spans.push(ty.span);
|
||||
|
|
|
@ -439,7 +439,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
|||
DefKind::Struct
|
||||
| DefKind::Ctor(CtorOf::Struct, ..)
|
||||
| DefKind::Union
|
||||
| DefKind::TyAlias
|
||||
| DefKind::TyAlias { .. }
|
||||
| DefKind::AssocTy,
|
||||
_,
|
||||
)
|
||||
|
|
|
@ -143,7 +143,7 @@ fn mark_used_by_default_parameters<'tcx>(
|
|||
| DefKind::Enum
|
||||
| DefKind::Variant
|
||||
| DefKind::Trait
|
||||
| DefKind::TyAlias
|
||||
| DefKind::TyAlias { .. }
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::TraitAlias
|
||||
| DefKind::AssocTy
|
||||
|
|
|
@ -87,7 +87,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
|
|||
|
||||
fn handle_res(&mut self, res: Res) {
|
||||
match res {
|
||||
Res::Def(DefKind::Const | DefKind::AssocConst | DefKind::TyAlias, def_id) => {
|
||||
Res::Def(DefKind::Const | DefKind::AssocConst | DefKind::TyAlias { .. }, def_id) => {
|
||||
self.check_def_id(def_id);
|
||||
}
|
||||
_ if self.in_pat => {}
|
||||
|
@ -861,7 +861,7 @@ impl<'tcx> DeadVisitor<'tcx> {
|
|||
| DefKind::Fn
|
||||
| DefKind::Static(_)
|
||||
| DefKind::Const
|
||||
| DefKind::TyAlias
|
||||
| DefKind::TyAlias { .. }
|
||||
| DefKind::Enum
|
||||
| DefKind::Union
|
||||
| DefKind::ForeignTy => self.warn_dead_code(def_id, "used"),
|
||||
|
|
|
@ -16,7 +16,7 @@ pub fn test_layout(tcx: TyCtxt<'_>) {
|
|||
for id in tcx.hir().items() {
|
||||
if matches!(
|
||||
tcx.def_kind(id.owner_id),
|
||||
DefKind::TyAlias | DefKind::Enum | DefKind::Struct | DefKind::Union
|
||||
DefKind::TyAlias { .. } | DefKind::Enum | DefKind::Struct | DefKind::Union
|
||||
) {
|
||||
for attr in tcx.get_attrs(id.owner_id, sym::rustc_layout) {
|
||||
dump_layout_of(tcx, id.owner_id.def_id, attr);
|
||||
|
|
|
@ -583,7 +583,7 @@ impl<'tcx> EmbargoVisitor<'tcx> {
|
|||
self.update(def_id, macro_ev, Level::Reachable);
|
||||
match def_kind {
|
||||
// No type privacy, so can be directly marked as reachable.
|
||||
DefKind::Const | DefKind::Static(_) | DefKind::TraitAlias | DefKind::TyAlias => {
|
||||
DefKind::Const | DefKind::Static(_) | DefKind::TraitAlias | DefKind::TyAlias { .. } => {
|
||||
if vis.is_accessible_from(module, self.tcx) {
|
||||
self.update(def_id, macro_ev, Level::Reachable);
|
||||
}
|
||||
|
@ -1992,8 +1992,8 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx, '_> {
|
|||
let def_kind = tcx.def_kind(def_id);
|
||||
|
||||
match def_kind {
|
||||
DefKind::Const | DefKind::Static(_) | DefKind::Fn | DefKind::TyAlias => {
|
||||
if let DefKind::TyAlias = def_kind {
|
||||
DefKind::Const | DefKind::Static(_) | DefKind::Fn | DefKind::TyAlias { .. } => {
|
||||
if let DefKind::TyAlias { .. } = def_kind {
|
||||
self.check_unnameable(def_id, effective_vis);
|
||||
}
|
||||
self.check(def_id, item_visibility, effective_vis).generics().predicates().ty();
|
||||
|
|
|
@ -592,7 +592,10 @@ pub(crate) fn report_cycle<'a, D: DepKind>(
|
|||
});
|
||||
}
|
||||
|
||||
let alias = if stack.iter().all(|entry| entry.query.def_kind == Some(DefKind::TyAlias)) {
|
||||
let alias = if stack
|
||||
.iter()
|
||||
.all(|entry| matches!(entry.query.def_kind, Some(DefKind::TyAlias { .. })))
|
||||
{
|
||||
Some(crate::error::Alias::Ty)
|
||||
} else if stack.iter().all(|entry| entry.query.def_kind == Some(DefKind::TraitAlias)) {
|
||||
Some(crate::error::Alias::Trait)
|
||||
|
|
|
@ -700,7 +700,10 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
|
|||
|
||||
// These items live in the type namespace.
|
||||
ItemKind::TyAlias(..) => {
|
||||
let res = Res::Def(DefKind::TyAlias, def_id);
|
||||
let res = Res::Def(
|
||||
DefKind::TyAlias { lazy: self.r.tcx.features().lazy_type_alias },
|
||||
def_id,
|
||||
);
|
||||
self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion));
|
||||
}
|
||||
|
||||
|
@ -948,7 +951,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
|
|||
DefKind::Struct
|
||||
| DefKind::Union
|
||||
| DefKind::Variant
|
||||
| DefKind::TyAlias
|
||||
| DefKind::TyAlias { .. }
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::TraitAlias
|
||||
|
|
|
@ -470,7 +470,7 @@ impl<'a> PathSource<'a> {
|
|||
| DefKind::Enum
|
||||
| DefKind::Trait
|
||||
| DefKind::TraitAlias
|
||||
| DefKind::TyAlias
|
||||
| DefKind::TyAlias { .. }
|
||||
| DefKind::AssocTy
|
||||
| DefKind::TyParam
|
||||
| DefKind::OpaqueTy
|
||||
|
@ -509,7 +509,7 @@ impl<'a> PathSource<'a> {
|
|||
DefKind::Struct
|
||||
| DefKind::Union
|
||||
| DefKind::Variant
|
||||
| DefKind::TyAlias
|
||||
| DefKind::TyAlias { .. }
|
||||
| DefKind::AssocTy,
|
||||
_,
|
||||
) | Res::SelfTyParam { .. }
|
||||
|
@ -1740,7 +1740,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
|||
Res::Def(DefKind::Struct, def_id)
|
||||
| Res::Def(DefKind::Union, def_id)
|
||||
| Res::Def(DefKind::Enum, def_id)
|
||||
| Res::Def(DefKind::TyAlias, def_id)
|
||||
| Res::Def(DefKind::TyAlias { .. }, def_id)
|
||||
| Res::Def(DefKind::Trait, def_id)
|
||||
if i + 1 == proj_start =>
|
||||
{
|
||||
|
|
|
@ -1419,7 +1419,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
|
|||
(Res::Def(DefKind::Macro(MacroKind::Bang), _), _) => {
|
||||
err.span_label(span, fallback_label.to_string());
|
||||
}
|
||||
(Res::Def(DefKind::TyAlias, def_id), PathSource::Trait(_)) => {
|
||||
(Res::Def(DefKind::TyAlias { .. }, def_id), PathSource::Trait(_)) => {
|
||||
err.span_label(span, "type aliases cannot be used as traits");
|
||||
if self.r.tcx.sess.is_nightly_build() {
|
||||
let msg = "you might have meant to use `#![feature(trait_alias)]` instead of a \
|
||||
|
@ -1588,7 +1588,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
|
|||
err.span_label(span, fallback_label.to_string());
|
||||
err.note("can't use `Self` as a constructor, you must use the implemented struct");
|
||||
}
|
||||
(Res::Def(DefKind::TyAlias | DefKind::AssocTy, _), _) if ns == ValueNS => {
|
||||
(Res::Def(DefKind::TyAlias { .. } | DefKind::AssocTy, _), _) if ns == ValueNS => {
|
||||
err.note("can't use a type alias as a constructor");
|
||||
}
|
||||
_ => return false,
|
||||
|
|
|
@ -58,7 +58,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
}
|
||||
DefKind::AnonConst => self.normalize_anon_const(goal),
|
||||
DefKind::OpaqueTy => self.normalize_opaque_type(goal),
|
||||
DefKind::TyAlias => self.normalize_weak_type(goal),
|
||||
DefKind::TyAlias { .. } => self.normalize_weak_type(goal),
|
||||
kind => bug!("unknown DefKind {} in projection goal: {goal:#?}", kind.descr(def_id)),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -128,7 +128,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
|
|||
},
|
||||
DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.local_parent(def_id)),
|
||||
DefKind::OpaqueTy => match tcx.def_kind(tcx.local_parent(def_id)) {
|
||||
DefKind::TyAlias => ty::List::empty(),
|
||||
DefKind::TyAlias { .. } => ty::List::empty(),
|
||||
DefKind::AssocTy => tcx.assumed_wf_types(tcx.local_parent(def_id)),
|
||||
// Nested opaque types only occur in associated types:
|
||||
// ` type Opaque<T> = impl Trait<&'static T, AssocTy = impl Nested>; `
|
||||
|
@ -145,7 +145,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
|
|||
| DefKind::Enum
|
||||
| DefKind::Variant
|
||||
| DefKind::Trait
|
||||
| DefKind::TyAlias
|
||||
| DefKind::TyAlias { .. }
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::TraitAlias
|
||||
| DefKind::TyParam
|
||||
|
|
|
@ -53,7 +53,9 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
|
|||
|
||||
fn parent(&self) -> Option<LocalDefId> {
|
||||
match self.tcx.def_kind(self.item) {
|
||||
DefKind::AnonConst | DefKind::InlineConst | DefKind::Fn | DefKind::TyAlias => None,
|
||||
DefKind::AnonConst | DefKind::InlineConst | DefKind::Fn | DefKind::TyAlias { .. } => {
|
||||
None
|
||||
}
|
||||
DefKind::AssocFn | DefKind::AssocTy | DefKind::AssocConst => {
|
||||
Some(self.tcx.local_parent(self.item))
|
||||
}
|
||||
|
@ -116,7 +118,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
|
|||
#[instrument(level = "trace", skip(self))]
|
||||
fn visit_nested_item(&mut self, id: rustc_hir::ItemId) {
|
||||
let id = id.owner_id.def_id;
|
||||
if let DefKind::TyAlias = self.collector.tcx.def_kind(id) {
|
||||
if let DefKind::TyAlias { .. } = self.collector.tcx.def_kind(id) {
|
||||
let items = self.collector.tcx.opaque_types_defined_by(id);
|
||||
self.collector.opaques.extend(items);
|
||||
}
|
||||
|
@ -295,7 +297,7 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [
|
|||
collector.collect_body_and_predicate_taits();
|
||||
}
|
||||
// We're also doing this for `AssocTy` for the wf checks in `check_opaque_meets_bounds`
|
||||
DefKind::TyAlias | DefKind::AssocTy => {
|
||||
DefKind::TyAlias { .. } | DefKind::AssocTy => {
|
||||
tcx.type_of(item).instantiate_identity().visit_with(&mut collector);
|
||||
}
|
||||
DefKind::OpaqueTy => {
|
||||
|
|
|
@ -79,7 +79,7 @@ pub(crate) fn try_inline(
|
|||
build_impls(cx, did, attrs_without_docs, &mut ret);
|
||||
clean::UnionItem(build_union(cx, did))
|
||||
}
|
||||
Res::Def(DefKind::TyAlias, did) => {
|
||||
Res::Def(DefKind::TyAlias { .. }, did) => {
|
||||
record_extern_fqn(cx, did, ItemType::Typedef);
|
||||
build_impls(cx, did, attrs_without_docs, &mut ret);
|
||||
clean::TypedefItem(build_type_alias(cx, did))
|
||||
|
|
|
@ -1706,7 +1706,7 @@ fn maybe_expand_private_type_alias<'tcx>(
|
|||
cx: &mut DocContext<'tcx>,
|
||||
path: &hir::Path<'tcx>,
|
||||
) -> Option<Type> {
|
||||
let Res::Def(DefKind::TyAlias, def_id) = path.res else { return None };
|
||||
let Res::Def(DefKind::TyAlias { .. }, def_id) = path.res else { return None };
|
||||
// Substitute private type aliases
|
||||
let def_id = def_id.as_local()?;
|
||||
let alias = if !cx.cache.effective_visibilities.is_exported(cx.tcx, def_id.to_def_id())
|
||||
|
@ -1970,7 +1970,7 @@ impl<'tcx> ContainerTy<'tcx> {
|
|||
let (DefKind::Struct
|
||||
| DefKind::Union
|
||||
| DefKind::Enum
|
||||
| DefKind::TyAlias
|
||||
| DefKind::TyAlias { .. }
|
||||
| DefKind::Trait
|
||||
| DefKind::AssocTy
|
||||
| DefKind::Variant) = tcx.def_kind(container)
|
||||
|
@ -2709,7 +2709,7 @@ fn clean_impl<'tcx>(
|
|||
let for_ = clean_ty(impl_.self_ty, cx);
|
||||
let type_alias =
|
||||
for_.def_id(&cx.cache).and_then(|alias_def_id: DefId| match tcx.def_kind(alias_def_id) {
|
||||
DefKind::TyAlias => Some(clean_middle_ty(
|
||||
DefKind::TyAlias { .. } => Some(clean_middle_ty(
|
||||
ty::Binder::dummy(tcx.type_of(def_id).instantiate_identity()),
|
||||
cx,
|
||||
Some(def_id.to_def_id()),
|
||||
|
|
|
@ -504,8 +504,22 @@ pub(crate) fn register_res(cx: &mut DocContext<'_>, res: Res) -> DefId {
|
|||
|
||||
let (kind, did) = match res {
|
||||
Res::Def(
|
||||
kind @ (AssocTy | AssocFn | AssocConst | Variant | Fn | TyAlias | Enum | Trait | Struct
|
||||
| Union | Mod | ForeignTy | Const | Static(_) | Macro(..) | TraitAlias),
|
||||
kind @ (AssocTy
|
||||
| AssocFn
|
||||
| AssocConst
|
||||
| Variant
|
||||
| Fn
|
||||
| TyAlias { .. }
|
||||
| Enum
|
||||
| Trait
|
||||
| Struct
|
||||
| Union
|
||||
| Mod
|
||||
| ForeignTy
|
||||
| Const
|
||||
| Static(_)
|
||||
| Macro(..)
|
||||
| TraitAlias),
|
||||
did,
|
||||
) => (kind.into(), did),
|
||||
|
||||
|
|
|
@ -115,7 +115,7 @@ impl From<DefKind> for ItemType {
|
|||
DefKind::Struct => Self::Struct,
|
||||
DefKind::Union => Self::Union,
|
||||
DefKind::Trait => Self::Trait,
|
||||
DefKind::TyAlias => Self::Typedef,
|
||||
DefKind::TyAlias { .. } => Self::Typedef,
|
||||
DefKind::TraitAlias => Self::TraitAlias,
|
||||
DefKind::Macro(kind) => match kind {
|
||||
MacroKind::Bang => ItemType::Macro,
|
||||
|
|
|
@ -592,7 +592,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
|||
.unwrap_or(Vec::new())
|
||||
}
|
||||
}
|
||||
Res::Def(DefKind::TyAlias, did) => {
|
||||
Res::Def(DefKind::TyAlias { .. }, did) => {
|
||||
// Resolve the link on the type the alias points to.
|
||||
// FIXME: if the associated item is defined directly on the type alias,
|
||||
// it will show up on its documentation page, we should link there instead.
|
||||
|
@ -1865,7 +1865,12 @@ fn resolution_failure(
|
|||
}
|
||||
return;
|
||||
}
|
||||
Trait | TyAlias | ForeignTy | OpaqueTy | TraitAlias | TyParam
|
||||
Trait
|
||||
| TyAlias { .. }
|
||||
| ForeignTy
|
||||
| OpaqueTy
|
||||
| TraitAlias
|
||||
| TyParam
|
||||
| Static(_) => "associated item",
|
||||
Impl { .. } | GlobalAsm => unreachable!("not a path"),
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ impl<'tcx> LateLintPass<'tcx> for NumberedFields {
|
|||
&& fields
|
||||
.iter()
|
||||
.all(|f| f.ident.as_str().as_bytes().iter().all(u8::is_ascii_digit))
|
||||
&& !matches!(cx.qpath_res(path, e.hir_id), Res::Def(DefKind::TyAlias, ..))
|
||||
&& !matches!(cx.qpath_res(path, e.hir_id), Res::Def(DefKind::TyAlias { .. }, ..))
|
||||
{
|
||||
let expr_spans = fields
|
||||
.iter()
|
||||
|
|
|
@ -286,7 +286,7 @@ pub fn is_wild(pat: &Pat<'_>) -> bool {
|
|||
/// Checks if the given `QPath` belongs to a type alias.
|
||||
pub fn is_ty_alias(qpath: &QPath<'_>) -> bool {
|
||||
match *qpath {
|
||||
QPath::Resolved(_, path) => matches!(path.res, Res::Def(DefKind::TyAlias | DefKind::AssocTy, ..)),
|
||||
QPath::Resolved(_, path) => matches!(path.res, Res::Def(DefKind::TyAlias { .. } | DefKind::AssocTy, ..)),
|
||||
QPath::TypeRelative(ty, _) if let TyKind::Path(qpath) = ty.kind => { is_ty_alias(&qpath) },
|
||||
_ => false,
|
||||
}
|
||||
|
|
|
@ -219,7 +219,7 @@ fn path_segment_certainty(
|
|||
// See the comment preceding `qpath_certainty`. `def_id` could refer to a type or a value.
|
||||
let certainty = lhs.join_clearing_def_ids(rhs);
|
||||
if resolves_to_type {
|
||||
if cx.tcx.def_kind(def_id) == DefKind::TyAlias {
|
||||
if let DefKind::TyAlias { .. } = cx.tcx.def_kind(def_id) {
|
||||
adt_def_id(cx.tcx.type_of(def_id).instantiate_identity())
|
||||
.map_or(certainty, |def_id| certainty.with_def_id(def_id))
|
||||
} else {
|
||||
|
|
6
tests/ui/lazy-type-alias/auxiliary/eager.rs
Normal file
6
tests/ui/lazy-type-alias/auxiliary/eager.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
// This crate does *not* have lazy type aliases enabled.
|
||||
|
||||
#![allow(type_alias_bounds)]
|
||||
|
||||
// The `Copy` bound is ignored both locally and externally for backward compatibility.
|
||||
pub type Alias<T: Copy> = Option<T>;
|
4
tests/ui/lazy-type-alias/auxiliary/lazy.rs
Normal file
4
tests/ui/lazy-type-alias/auxiliary/lazy.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
#![feature(lazy_type_alias)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
pub type Alias<T: Copy> = Option<T>;
|
|
@ -0,0 +1,23 @@
|
|||
// This test serves as a regression test for issue #114468 and it also ensures that we consider
|
||||
// type aliases from external crates that don't have `lazy_type_alias` enabled to be eager.
|
||||
|
||||
// aux-crate:eager=eager.rs
|
||||
// edition: 2021
|
||||
// check-pass
|
||||
|
||||
#![feature(lazy_type_alias)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
// This used to crash when we were computing the variances of `Struct` since we would convert
|
||||
// `eager::Alias<T>` to a weak projection due to the presence of `#![feature(lazy_type_alias)]` in
|
||||
// this (!) crate and subsequently attempt to obtain the variances of the type alias associated with
|
||||
// the weak projection which would panic because we don't compute this information for eager type
|
||||
// aliases at all.
|
||||
struct Struct<T>(eager::Alias<T>);
|
||||
|
||||
fn main() {
|
||||
// We want to ignore (or rather “end up ignoring”) the bound `T: Copy` since `Alias` should be
|
||||
// treated as an eager type alias not just inside the crate it is defined in but also in
|
||||
// dependent crates (like this one).
|
||||
let _: eager::Alias<String>;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
error[E0277]: the trait bound `String: Copy` is not satisfied
|
||||
--> $DIR/extern-crate-has-lazy-type-aliases.rs:15:12
|
||||
|
|
||||
LL | let _: lazy::Alias<String>;
|
||||
| ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
|
||||
|
|
||||
note: required by a bound on the type alias `Alias`
|
||||
--> $DIR/auxiliary/lazy.rs:4:19
|
||||
|
|
||||
LL | pub type Alias<T: Copy> = Option<T>;
|
||||
| ^^^^ required by this bound
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
|
@ -0,0 +1,15 @@
|
|||
error[E0277]: the trait bound `String: Copy` is not satisfied
|
||||
--> $DIR/extern-crate-has-lazy-type-aliases.rs:15:12
|
||||
|
|
||||
LL | let _: lazy::Alias<String>;
|
||||
| ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
|
||||
|
|
||||
note: required by a bound on the type alias `Alias`
|
||||
--> $DIR/auxiliary/lazy.rs:4:19
|
||||
|
|
||||
LL | pub type Alias<T: Copy> = Option<T>;
|
||||
| ^^^^ required by this bound
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
|
@ -0,0 +1,16 @@
|
|||
// revisions: locally_eager locally_lazy
|
||||
// aux-crate:lazy=lazy.rs
|
||||
// edition: 2021
|
||||
|
||||
// Test that we treat lazy type aliases from external crates as lazy independently of whether the
|
||||
// local crate enables `lazy_type_alias` or not.
|
||||
|
||||
#![cfg_attr(
|
||||
locally_lazy,
|
||||
feature(lazy_type_alias),
|
||||
allow(incomplete_features)
|
||||
)]
|
||||
|
||||
fn main() {
|
||||
let _: lazy::Alias<String>; //~ ERROR the trait bound `String: Copy` is not satisfied
|
||||
}
|
Loading…
Add table
Reference in a new issue