Skip to content
Open
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
34 changes: 31 additions & 3 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3562,6 +3562,7 @@ impl Item {
| ItemKind::DelegationMac(_)
| ItemKind::MacroDef(..) => None,
ItemKind::Static(_) => None,
ItemKind::AutoImpl(_) => None,
ItemKind::Const(i) => Some(&i.generics),
ItemKind::Fn(i) => Some(&i.generics),
ItemKind::TyAlias(i) => Some(&i.generics),
Expand Down Expand Up @@ -3705,6 +3706,14 @@ pub struct Impl {
pub items: ThinVec<Box<AssocItem>>,
}

#[derive(Clone, Encodable, Decodable, Debug)]
pub struct AutoImpl {
pub generics: Generics,
pub constness: Const,
pub of_trait: Box<TraitImplHeader>,
pub items: ThinVec<Box<AssocItem>>,
}

#[derive(Clone, Encodable, Decodable, Debug)]
pub struct TraitImplHeader {
pub defaultness: Defaultness,
Expand Down Expand Up @@ -3857,6 +3866,8 @@ pub enum ItemKind {
///
/// E.g., `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`.
Impl(Impl),
/// An `auto impl` implementation, such as a supertrait `auto impl`.
AutoImpl(Box<AutoImpl>),
/// A macro invocation.
///
/// E.g., `foo!(..)`.
Expand Down Expand Up @@ -3893,6 +3904,7 @@ impl ItemKind {
| ItemKind::ForeignMod(_)
| ItemKind::GlobalAsm(_)
| ItemKind::Impl(_)
| ItemKind::AutoImpl(_)
| ItemKind::MacCall(_)
| ItemKind::DelegationMac(_) => None,
}
Expand All @@ -3905,7 +3917,12 @@ impl ItemKind {
Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
| Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
| Delegation(..) | DelegationMac(..) => "a",
ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
ExternCrate(..)
| ForeignMod(..)
| MacCall(..)
| Enum(..)
| Impl { .. }
| AutoImpl { .. } => "an",
}
}

Expand All @@ -3928,6 +3945,7 @@ impl ItemKind {
ItemKind::MacCall(..) => "item macro invocation",
ItemKind::MacroDef(..) => "macro definition",
ItemKind::Impl { .. } => "implementation",
ItemKind::AutoImpl { .. } => "`auto` implementation",
ItemKind::Delegation(..) => "delegated function",
ItemKind::DelegationMac(..) => "delegation",
}
Expand Down Expand Up @@ -3975,6 +3993,8 @@ pub enum AssocItemKind {
Delegation(Box<Delegation>),
/// An associated list or glob delegation item.
DelegationMac(Box<DelegationMac>),
/// An `auto impl` item
AutoImpl(Box<AutoImpl>),
}

impl AssocItemKind {
Expand All @@ -3985,15 +4005,21 @@ impl AssocItemKind {
| AssocItemKind::Type(box TyAlias { ident, .. })
| AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),

AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
AssocItemKind::MacCall(_)
| AssocItemKind::DelegationMac(_)
| AssocItemKind::AutoImpl(_) => None,
}
}

pub fn defaultness(&self) -> Defaultness {
match *self {
Self::Const(box ConstItem { defaultness, .. })
| Self::Fn(box Fn { defaultness, .. })
| Self::Type(box TyAlias { defaultness, .. }) => defaultness,
| Self::Type(box TyAlias { defaultness, .. })
| Self::AutoImpl(box AutoImpl {
of_trait: box TraitImplHeader { defaultness, .. },
..
}) => defaultness,
Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
Defaultness::Final
}
Expand All @@ -4010,6 +4036,7 @@ impl From<AssocItemKind> for ItemKind {
AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
AssocItemKind::AutoImpl(ai) => ItemKind::AutoImpl(ai),
}
}
}
Expand All @@ -4025,6 +4052,7 @@ impl TryFrom<ItemKind> for AssocItemKind {
ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
ItemKind::AutoImpl(ai) => AssocItemKind::AutoImpl(ai),
_ => return Err(item_kind),
})
}
Expand Down
16 changes: 16 additions & 0 deletions compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,7 @@ macro_rules! common_visitor_and_walkers {
//fn visit_assoc_item(AssocItem, _ctxt: AssocCtxt);
fn visit_assoc_item_constraint(AssocItemConstraint);
fn visit_attribute(Attribute);
fn visit_auto_impl(AutoImpl);
fn visit_block(Block);
//fn visit_nested_use_tree((UseTree, NodeId));
fn visit_capture_by(CaptureBy);
Expand Down Expand Up @@ -836,6 +837,8 @@ macro_rules! common_visitor_and_walkers {
visit_visitable!($($mut)? vis, ident, generics, variant_data),
ItemKind::Impl(impl_) =>
visit_visitable!($($mut)? vis, impl_),
ItemKind::AutoImpl(auto_impl_) =>
visit_visitable!($($mut)? vis, auto_impl_),
ItemKind::Trait(trait_) =>
visit_visitable!($($mut)? vis, trait_),
ItemKind::TraitAlias(box TraitAlias { constness, ident, generics, bounds}) => {
Expand Down Expand Up @@ -881,6 +884,8 @@ macro_rules! common_visitor_and_walkers {
visit_visitable!($($mut)? vis, delegation),
AssocItemKind::DelegationMac(dm) =>
visit_visitable!($($mut)? vis, dm),
AssocItemKind::AutoImpl(ai) =>
visit_visitable!($($mut)? vis, ai),
}
V::Result::output()
}
Expand Down Expand Up @@ -945,6 +950,17 @@ macro_rules! common_visitor_and_walkers {
V::Result::output()
});

impl_walkable!(|&$($mut)? $($lt)? self: AutoImpl, vis: &mut V| {
let AutoImpl { generics, of_trait, items, constness } = self;
let TraitImplHeader { defaultness, safety, polarity, trait_ref } = &$($mut)? **of_trait;

try_visit!(vis.visit_generics(generics));
visit_visitable!($($mut)? vis, defaultness, safety, constness, polarity, trait_ref);

visit_visitable_with!($($mut)? vis, items, AssocCtxt::Impl { of_trait: true });
V::Result::output()
});

// Special case to call `visit_method_receiver_expr`.
impl_walkable!(|&$($mut)? $($lt)? self: MethodCall, vis: &mut V| {
let MethodCall { seg, receiver, args, span } = self;
Expand Down
45 changes: 45 additions & 0 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use rustc_hir::{
use rustc_index::{IndexSlice, IndexVec};
use rustc_middle::span_bug;
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
use rustc_session::parse::feature_err;
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym};
use smallvec::{SmallVec, smallvec};
Expand Down Expand Up @@ -388,6 +389,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
constness,
})
}
ItemKind::AutoImpl(box AutoImpl { .. }) => todo!("we should implement lowering to HIR"),
ItemKind::Trait(box Trait {
constness,
is_auto,
Expand Down Expand Up @@ -887,6 +889,48 @@ impl<'hir> LoweringContext<'_, 'hir> {
true,
)
}
AssocItemKind::AutoImpl(ai) => {
let tcx = self.tcx;
if !tcx.features().supertrait_auto_impl() {
feature_err(
&tcx.sess,
sym::supertrait_auto_impl,
i.span,
"feature is under construction",
)
.emit();
}
let generics = tcx.arena.alloc(hir::Generics {
has_where_clause_predicates: false,
params: &[],
predicates: &[],
where_clause_span: DUMMY_SP,
span: DUMMY_SP,
});
(
Ident::dummy(),
&*generics,
hir::TraitItemKind::AutoImpl(
tcx.arena.alloc(self.lower_poly_trait_ref_inner(
&ai.generics.params,
&TraitBoundModifiers {
constness: BoundConstness::Never,
asyncness: BoundAsyncness::Normal,
polarity: match ai.of_trait.polarity {
ImplPolarity::Positive => BoundPolarity::Positive,
ImplPolarity::Negative(span) => BoundPolarity::Negative(span),
},
},
&ai.of_trait.trait_ref,
ai.of_trait.trait_ref.path.span,
RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::SuperTrait),
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
)),
&[],
),
false,
)
}
AssocItemKind::Type(box TyAlias {
ident,
generics,
Expand Down Expand Up @@ -1090,6 +1134,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
),
)
}
AssocItemKind::AutoImpl(_) => todo!(),
AssocItemKind::Delegation(box delegation) => {
let delegation_results = self.lower_delegation(delegation, i.id, is_in_trait_impl);
(
Expand Down
24 changes: 22 additions & 2 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2074,21 +2074,41 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
PolyTraitRef { bound_generic_params, modifiers, trait_ref, span, parens: _ }: &PolyTraitRef,
rbp: RelaxedBoundPolicy<'_>,
itctx: ImplTraitContext,
) -> hir::PolyTraitRef<'hir> {
self.lower_poly_trait_ref_inner(
bound_generic_params,
modifiers,
trait_ref,
*span,
rbp,
itctx,
)
}

#[instrument(level = "debug", skip(self))]
fn lower_poly_trait_ref_inner(
&mut self,
bound_generic_params: &[GenericParam],
modifiers: &TraitBoundModifiers,
trait_ref: &TraitRef,
span: Span,
rbp: RelaxedBoundPolicy<'_>,
itctx: ImplTraitContext,
) -> hir::PolyTraitRef<'hir> {
let bound_generic_params =
self.lower_lifetime_binder(trait_ref.ref_id, bound_generic_params);
let trait_ref = self.lower_trait_ref(*modifiers, trait_ref, itctx);
let modifiers = self.lower_trait_bound_modifiers(*modifiers);

if let ast::BoundPolarity::Maybe(_) = modifiers.polarity {
self.validate_relaxed_bound(trait_ref, *span, rbp);
self.validate_relaxed_bound(trait_ref, span, rbp);
}

hir::PolyTraitRef {
bound_generic_params,
modifiers,
trait_ref,
span: self.lower_span(*span),
span: self.lower_span(span),
}
}

Expand Down
54 changes: 53 additions & 1 deletion compiler/rustc_ast_pretty/src/pprust/state/item.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use ast::StaticItem;
use itertools::{Itertools, Position};
use rustc_ast::{self as ast, ModKind, TraitAlias};
use rustc_span::Ident;
use rustc_span::{Ident, Span};

use crate::pp::BoxMarker;
use crate::pp::Breaks::Inconsistent;
Expand Down Expand Up @@ -350,6 +350,32 @@ impl<'a> State<'a> {
let empty = item.attrs.is_empty() && items.is_empty();
self.bclose(item.span, empty, cb);
}
ast::ItemKind::AutoImpl(box ast::AutoImpl { generics, of_trait, items, constness }) => {
let (cb, ib) = self.head("");
self.print_visibility(&item.vis);

let &ast::TraitImplHeader { defaultness, safety, polarity, ref trait_ref } =
&**of_trait;
self.print_defaultness(defaultness);
self.print_safety(safety);
self.word("auto");
self.word("impl");
self.print_generic_params(&generics.params);
self.print_constness(*constness);
if let ast::ImplPolarity::Negative(_) = polarity {
self.word("!");
}
self.print_trait_ref(trait_ref);

self.space();
self.bopen(ib);
self.print_inner_attributes(&item.attrs);
for impl_item in items {
self.print_assoc_item(impl_item);
}
let empty = item.attrs.is_empty() && items.is_empty();
self.bclose(item.span, empty, cb);
}
ast::ItemKind::Trait(box ast::Trait {
constness,
safety,
Expand Down Expand Up @@ -601,6 +627,9 @@ impl<'a> State<'a> {
self.word(";");
}
}
ast::AssocItemKind::AutoImpl(ai) => {
self.print_assoc_auto_impl(&item.attrs, ai, item.span)
}
ast::AssocItemKind::Delegation(deleg) => self.print_delegation(
&item.attrs,
vis,
Expand All @@ -621,6 +650,29 @@ impl<'a> State<'a> {
self.ann.post(self, AnnNode::SubItem(id))
}

fn print_assoc_auto_impl(&mut self, attrs: &[ast::Attribute], ai: &ast::AutoImpl, span: Span) {
let (cb, ib) = self.head("");
let &ast::TraitImplHeader { defaultness, safety, polarity, ref trait_ref } = &*ai.of_trait;
self.print_defaultness(defaultness);
self.print_safety(safety);
self.word("auto");
self.word("impl");
self.print_constness(ai.constness);
if let ast::ImplPolarity::Negative(_) = polarity {
self.word("!");
}
self.print_trait_ref(trait_ref);

self.space();
self.bopen(ib);
self.print_inner_attributes(&attrs);
for impl_item in &ai.items {
self.print_assoc_item(impl_item);
}
let empty = attrs.is_empty() && ai.items.is_empty();
self.bclose(span, empty, cb);
}

fn print_delegation(
&mut self,
attrs: &[ast::Attribute],
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,8 @@ declare_features! (
(unstable, string_deref_patterns, "1.67.0", Some(87121)),
/// Allows `super let` statements.
(unstable, super_let, "1.88.0", Some(139076)),
/// Allows supertraits to be implemented with automatic defaults
(unstable, supertrait_auto_impl, "CURRENT_RUSTC_VERSION", Some(99999)),
/// Allows subtrait items to shadow supertrait items.
(unstable, supertrait_item_shadowing, "1.86.0", Some(89151)),
/// Allows the use of target_feature when a function is marked inline(always).
Expand Down
Loading
Loading