Skip to content

Commit 2655bc9

Browse files
committed
Add #[rustc_per_edition] for edition-dependent type aliases.
1 parent 6b56603 commit 2655bc9

File tree

3 files changed

+37
-7
lines changed

3 files changed

+37
-7
lines changed

compiler/rustc_feature/src/builtin_attrs.rs

+7
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,13 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
394394
may_dangle, Normal, template!(Word), dropck_eyepatch,
395395
"`may_dangle` has unstable semantics and may be removed in the future",
396396
),
397+
rustc_attr!(
398+
rustc_per_edition, AssumedUsed, template!(Word),
399+
"#[rustc_per_edition] can be applied to a type alias to make the resolution
400+
dependent on the edition of the crate using this type alias.
401+
It must be applied on an alias for a tuple, of which the fields correspond
402+
to the Rust editions.",
403+
),
397404

398405
// ==========================================================================
399406
// Internal attributes: Runtime related:

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -996,6 +996,7 @@ symbols! {
996996
rustc_peek_liveness,
997997
rustc_peek_maybe_init,
998998
rustc_peek_maybe_uninit,
999+
rustc_per_edition,
9991000
rustc_polymorphize_error,
10001001
rustc_private,
10011002
rustc_proc_macro_decls,

compiler/rustc_typeck/src/astconv/mod.rs

+29-7
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ use rustc_middle::ty::GenericParamDefKind;
2626
use rustc_middle::ty::{self, Const, DefIdTree, Ty, TyCtxt, TypeFoldable};
2727
use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
2828
use rustc_span::lev_distance::find_best_match_for_name;
29-
use rustc_span::symbol::{Ident, Symbol};
30-
use rustc_span::{Span, DUMMY_SP};
29+
use rustc_span::symbol::{sym, Ident, Symbol};
30+
use rustc_span::{edition, Span, DUMMY_SP};
3131
use rustc_target::spec::abi;
3232
use rustc_trait_selection::traits;
3333
use rustc_trait_selection::traits::astconv_object_safety_violations;
@@ -2053,12 +2053,34 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
20532053
let substs = self.ast_path_substs_for_ty(span, did, item_segment.0);
20542054
self.normalize_ty(span, tcx.mk_opaque(did, substs))
20552055
}
2056+
Res::Def(DefKind::TyAlias, did) => {
2057+
assert_eq!(opt_self_ty, None);
2058+
self.prohibit_generics(path.segments.split_last().unwrap().1);
2059+
let ty = self.ast_path_to_ty(span, did, path.segments.last().unwrap());
2060+
if self.tcx().has_attr(did, sym::rustc_per_edition) {
2061+
let ty = if let ty::Tuple(..) = ty.kind() {
2062+
let mut fields = ty.tuple_fields();
2063+
let edition = span.edition();
2064+
edition::ALL_EDITIONS
2065+
.iter()
2066+
.take_while(|&&e| e != edition)
2067+
.fold(fields.next(), |ty, _| fields.next().or(ty))
2068+
} else {
2069+
None
2070+
};
2071+
ty.unwrap_or_else(|| {
2072+
self.tcx().sess.span_err(
2073+
self.tcx().def_span(did),
2074+
"#[rustc_per_edition] type alias needs to be a tuple of at least one field",
2075+
);
2076+
tcx.ty_error()
2077+
})
2078+
} else {
2079+
ty
2080+
}
2081+
}
20562082
Res::Def(
2057-
DefKind::Enum
2058-
| DefKind::TyAlias
2059-
| DefKind::Struct
2060-
| DefKind::Union
2061-
| DefKind::ForeignTy,
2083+
DefKind::Enum | DefKind::Struct | DefKind::Union | DefKind::ForeignTy,
20622084
did,
20632085
) => {
20642086
assert_eq!(opt_self_ty, None);

0 commit comments

Comments
 (0)