Skip to content
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

[Syntax] Implement auto trait syntax #45247

Merged
merged 15 commits into from
Nov 4, 2017
Merged
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
Original file line number Diff line number Diff line change
@@ -24,9 +24,7 @@ Example:
```rust
#![feature(optin_builtin_traits)]

trait Valid {}

impl Valid for .. {}
auto trait Valid {}

struct True;
struct False;
6 changes: 6 additions & 0 deletions src/libcore/marker.rs
Original file line number Diff line number Diff line change
@@ -46,6 +46,8 @@ pub unsafe trait Send {
}

#[stable(feature = "rust1", since = "1.0.0")]
#[allow(unknown_lints)]
#[allow(auto_impl)]
unsafe impl Send for .. { }

#[stable(feature = "rust1", since = "1.0.0")]
@@ -349,6 +351,8 @@ pub unsafe trait Sync {
}

#[stable(feature = "rust1", since = "1.0.0")]
#[allow(unknown_lints)]
#[allow(auto_impl)]
unsafe impl Sync for .. { }

#[stable(feature = "rust1", since = "1.0.0")]
@@ -562,6 +566,8 @@ mod impls {
#[lang = "freeze"]
unsafe trait Freeze {}

#[allow(unknown_lints)]
#[allow(auto_impl)]
unsafe impl Freeze for .. {}

impl<T: ?Sized> !Freeze for UnsafeCell<T> {}
2 changes: 1 addition & 1 deletion src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
@@ -498,7 +498,7 @@ define_dep_nodes!( <'tcx>
[] SuperPredicatesOfItem(DefId),
[] TraitDefOfItem(DefId),
[] AdtDefOfItem(DefId),
[] IsDefaultImpl(DefId),
[] IsAutoImpl(DefId),
[] ImplTraitRef(DefId),
[] ImplPolarity(DefId),
[] ClosureKind(DefId),
4 changes: 2 additions & 2 deletions src/librustc/hir/intravisit.rs
Original file line number Diff line number Diff line change
@@ -503,7 +503,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
// visit_enum_def() takes care of visiting the Item's NodeId
visitor.visit_enum_def(enum_definition, type_parameters, item.id, item.span)
}
ItemDefaultImpl(_, ref trait_ref) => {
ItemAutoImpl(_, ref trait_ref) => {
visitor.visit_id(item.id);
visitor.visit_trait_ref(trait_ref)
}
@@ -520,7 +520,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
visitor.visit_id(item.id);
visitor.visit_variant_data(struct_definition, item.name, generics, item.id, item.span);
}
ItemTrait(_, ref generics, ref bounds, ref trait_item_refs) => {
ItemTrait(.., ref generics, ref bounds, ref trait_item_refs) => {
visitor.visit_id(item.id);
visitor.visit_generics(generics);
walk_list!(visitor, visit_ty_param_bound, bounds);
26 changes: 17 additions & 9 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
@@ -96,7 +96,7 @@ pub struct LoweringContext<'a> {
exported_macros: Vec<hir::MacroDef>,

trait_impls: BTreeMap<DefId, Vec<NodeId>>,
trait_default_impl: BTreeMap<DefId, NodeId>,
trait_auto_impl: BTreeMap<DefId, NodeId>,

is_generator: bool,

@@ -146,7 +146,7 @@ pub fn lower_crate(sess: &Session,
impl_items: BTreeMap::new(),
bodies: BTreeMap::new(),
trait_impls: BTreeMap::new(),
trait_default_impl: BTreeMap::new(),
trait_auto_impl: BTreeMap::new(),
exported_macros: Vec::new(),
catch_scopes: Vec::new(),
loop_scopes: Vec::new(),
@@ -198,7 +198,7 @@ impl<'a> LoweringContext<'a> {
ItemKind::Union(_, ref generics) |
ItemKind::Enum(_, ref generics) |
ItemKind::Ty(_, ref generics) |
ItemKind::Trait(_, ref generics, ..) => {
ItemKind::Trait(_, _, ref generics, ..) => {
let def_id = self.lctx.resolver.definitions().local_def_id(item.id);
let count = generics.lifetimes.len();
self.lctx.type_def_lifetime_params.insert(def_id, count);
@@ -284,7 +284,7 @@ impl<'a> LoweringContext<'a> {
bodies: self.bodies,
body_ids,
trait_impls: self.trait_impls,
trait_default_impl: self.trait_default_impl,
trait_auto_impl: self.trait_auto_impl,
}
}

@@ -1479,14 +1479,14 @@ impl<'a> LoweringContext<'a> {
let vdata = self.lower_variant_data(vdata);
hir::ItemUnion(vdata, self.lower_generics(generics))
}
ItemKind::DefaultImpl(unsafety, ref trait_ref) => {
ItemKind::AutoImpl(unsafety, ref trait_ref) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to see all evidence of impl Trait for .. go away by the time HIR lowering is done. That is, I think the HIR should not include impl Trait for ..-style impls, and instead we should lower any trait that contains such an impl to have hir::IsAuto set to true.

This will presumably require one of two things:

  • A pre-pass that identifies the set of traits targeted by auto-impls, so that later, when we lower traits, we can set hir::IsAuto to true.
  • Or, alternatively, we could collect the set as we walk, and update the lowered form of traits after the fact. I suspect we still have unique access and can mutate them in place?

let trait_ref = self.lower_trait_ref(trait_ref);

if let Def::Trait(def_id) = trait_ref.path.def {
self.trait_default_impl.insert(def_id, id);
self.trait_auto_impl.insert(def_id, id);
}

hir::ItemDefaultImpl(self.lower_unsafety(unsafety),
hir::ItemAutoImpl(self.lower_unsafety(unsafety),
trait_ref)
}
ItemKind::Impl(unsafety,
@@ -1515,10 +1515,11 @@ impl<'a> LoweringContext<'a> {
self.lower_ty(ty),
new_impl_items)
}
ItemKind::Trait(unsafety, ref generics, ref bounds, ref items) => {
ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref items) => {
let bounds = self.lower_bounds(bounds);
let items = items.iter().map(|item| self.lower_trait_item_ref(item)).collect();
hir::ItemTrait(self.lower_unsafety(unsafety),
hir::ItemTrait(self.lower_is_auto(is_auto),
self.lower_unsafety(unsafety),
self.lower_generics(generics),
bounds,
items)
@@ -1741,6 +1742,13 @@ impl<'a> LoweringContext<'a> {
}
}

fn lower_is_auto(&mut self, a: IsAuto) -> hir::IsAuto {
match a {
IsAuto::Yes => hir::IsAuto::Yes,
IsAuto::No => hir::IsAuto::No,
}
}

fn lower_unsafety(&mut self, u: Unsafety) -> hir::Unsafety {
match u {
Unsafety::Unsafe => hir::Unsafety::Unsafe,
2 changes: 1 addition & 1 deletion src/librustc/hir/map/collector.rs
Original file line number Diff line number Diff line change
@@ -71,7 +71,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
impl_items: _,
bodies: _,
trait_impls: _,
trait_default_impl: _,
trait_auto_impl: _,
body_ids: _,
} = *krate;

2 changes: 1 addition & 1 deletion src/librustc/hir/map/def_collector.rs
Original file line number Diff line number Diff line change
@@ -104,7 +104,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
// Pick the def data. This need not be unique, but the more
// information we encapsulate into
let def_data = match i.node {
ItemKind::DefaultImpl(..) | ItemKind::Impl(..) =>
ItemKind::AutoImpl(..) | ItemKind::Impl(..) =>
DefPathData::Impl,
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) | ItemKind::Trait(..) |
ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | ItemKind::Ty(..) =>
8 changes: 4 additions & 4 deletions src/librustc/hir/map/mod.rs
Original file line number Diff line number Diff line change
@@ -474,16 +474,16 @@ impl<'hir> Map<'hir> {
self.forest.krate.trait_impls.get(&trait_did).map_or(&[], |xs| &xs[..])
}

pub fn trait_default_impl(&self, trait_did: DefId) -> Option<NodeId> {
pub fn trait_auto_impl(&self, trait_did: DefId) -> Option<NodeId> {
self.dep_graph.read(DepNode::new_no_params(DepKind::AllLocalTraitImpls));

// NB: intentionally bypass `self.forest.krate()` so that we
// do not trigger a read of the whole krate here
self.forest.krate.trait_default_impl.get(&trait_did).cloned()
self.forest.krate.trait_auto_impl.get(&trait_did).cloned()
}

pub fn trait_is_auto(&self, trait_did: DefId) -> bool {
self.trait_default_impl(trait_did).is_some()
self.trait_auto_impl(trait_did).is_some()
}

/// Get the attributes on the krate. This is preferable to
@@ -1140,7 +1140,7 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
ItemUnion(..) => "union",
ItemTrait(..) => "trait",
ItemImpl(..) => "impl",
ItemDefaultImpl(..) => "default impl",
ItemAutoImpl(..) => "default impl",
};
format!("{} {}{}", item_str, path_str(), id_str)
}
19 changes: 13 additions & 6 deletions src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
@@ -499,7 +499,7 @@ pub struct Crate {
pub impl_items: BTreeMap<ImplItemId, ImplItem>,
pub bodies: BTreeMap<BodyId, Body>,
pub trait_impls: BTreeMap<DefId, Vec<NodeId>>,
pub trait_default_impl: BTreeMap<DefId, NodeId>,
pub trait_auto_impl: BTreeMap<DefId, NodeId>,

/// A list of the body ids written out in the order in which they
/// appear in the crate. If you're going to process all the bodies
@@ -1500,6 +1500,13 @@ pub struct FnDecl {
pub has_implicit_self: bool,
}

/// Is the trait definition an auto trait?
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum IsAuto {
Yes,
No
}

#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum Unsafety {
Unsafe,
@@ -1811,12 +1818,12 @@ pub enum Item_ {
/// A union definition, e.g. `union Foo<A, B> {x: A, y: B}`
ItemUnion(VariantData, Generics),
/// Represents a Trait Declaration
ItemTrait(Unsafety, Generics, TyParamBounds, HirVec<TraitItemRef>),
ItemTrait(IsAuto, Unsafety, Generics, TyParamBounds, HirVec<TraitItemRef>),

// Default trait implementations
/// Auto trait implementations
///
/// `impl Trait for .. {}`
ItemDefaultImpl(Unsafety, TraitRef),
ItemAutoImpl(Unsafety, TraitRef),
/// An implementation, eg `impl<A> Trait for Foo { .. }`
ItemImpl(Unsafety,
ImplPolarity,
@@ -1844,7 +1851,7 @@ impl Item_ {
ItemUnion(..) => "union",
ItemTrait(..) => "trait",
ItemImpl(..) |
ItemDefaultImpl(..) => "item",
ItemAutoImpl(..) => "item",
}
}

@@ -1864,7 +1871,7 @@ impl Item_ {
ItemEnum(_, ref generics) |
ItemStruct(_, ref generics) |
ItemUnion(_, ref generics) |
ItemTrait(_, ref generics, _, _) |
ItemTrait(_, _, ref generics, _, _) |
ItemImpl(_, _, _, ref generics, _, _, _)=> generics,
_ => return None
})
12 changes: 10 additions & 2 deletions src/librustc/hir/print.rs
Original file line number Diff line number Diff line change
@@ -660,7 +660,7 @@ impl<'a> State<'a> {
self.head(&visibility_qualified(&item.vis, "union"))?;
self.print_struct(struct_def, generics, item.name, item.span, true)?;
}
hir::ItemDefaultImpl(unsafety, ref trait_ref) => {
hir::ItemAutoImpl(unsafety, ref trait_ref) => {
self.head("")?;
self.print_visibility(&item.vis)?;
self.print_unsafety(unsafety)?;
@@ -717,9 +717,10 @@ impl<'a> State<'a> {
}
self.bclose(item.span)?;
}
hir::ItemTrait(unsafety, ref generics, ref bounds, ref trait_items) => {
hir::ItemTrait(is_auto, unsafety, ref generics, ref bounds, ref trait_items) => {
self.head("")?;
self.print_visibility(&item.vis)?;
self.print_is_auto(is_auto)?;
self.print_unsafety(unsafety)?;
self.word_nbsp("trait")?;
self.print_name(item.name)?;
@@ -2274,6 +2275,13 @@ impl<'a> State<'a> {
hir::Unsafety::Unsafe => self.word_nbsp("unsafe"),
}
}

pub fn print_is_auto(&mut self, s: hir::IsAuto) -> io::Result<()> {
match s {
hir::IsAuto::Yes => self.word_nbsp("auto"),
hir::IsAuto::No => Ok(()),
}
}
}

// Dup'ed from parse::classify, but adapted for the HIR.
10 changes: 7 additions & 3 deletions src/librustc/ich/impls_hir.rs
Original file line number Diff line number Diff line change
@@ -898,7 +898,7 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::Item {
hir::ItemForeignMod(..) |
hir::ItemGlobalAsm(..) |
hir::ItemMod(..) |
hir::ItemDefaultImpl(..) |
hir::ItemAutoImpl(..) |
hir::ItemTrait(..) |
hir::ItemImpl(..) |
hir::ItemTy(..) |
@@ -944,8 +944,8 @@ impl_stable_hash_for!(enum hir::Item_ {
ItemEnum(enum_def, generics),
ItemStruct(variant_data, generics),
ItemUnion(variant_data, generics),
ItemTrait(unsafety, generics, bounds, item_refs),
ItemDefaultImpl(unsafety, trait_ref),
ItemTrait(is_auto, unsafety, generics, bounds, item_refs),
ItemAutoImpl(unsafety, trait_ref),
ItemImpl(unsafety, impl_polarity, impl_defaultness, generics, trait_ref, ty, impl_item_refs)
});

@@ -1126,6 +1126,10 @@ impl_stable_hash_for!(enum hir::Mutability {
MutImmutable
});

impl_stable_hash_for!(enum hir::IsAuto {
Yes,
No
});

impl_stable_hash_for!(enum hir::Unsafety {
Unsafe,
10 changes: 5 additions & 5 deletions src/librustc/ich/impls_ty.rs
Original file line number Diff line number Diff line change
@@ -731,13 +731,13 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::TraitDef {
def_id: _,
unsafety,
paren_sugar,
has_default_impl,
has_auto_impl,
def_path_hash,
} = *self;

unsafety.hash_stable(hcx, hasher);
paren_sugar.hash_stable(hcx, hasher);
has_default_impl.hash_stable(hcx, hasher);
has_auto_impl.hash_stable(hcx, hasher);
def_path_hash.hash_stable(hcx, hasher);
}
}
@@ -856,7 +856,7 @@ for traits::Vtable<'gcx, N> where N: HashStable<StableHashingContext<'gcx>> {

match self {
&VtableImpl(ref table_impl) => table_impl.hash_stable(hcx, hasher),
&VtableDefaultImpl(ref table_def_impl) => table_def_impl.hash_stable(hcx, hasher),
&VtableAutoImpl(ref table_def_impl) => table_def_impl.hash_stable(hcx, hasher),
&VtableParam(ref table_param) => table_param.hash_stable(hcx, hasher),
&VtableObject(ref table_obj) => table_obj.hash_stable(hcx, hasher),
&VtableBuiltin(ref table_builtin) => table_builtin.hash_stable(hcx, hasher),
@@ -884,11 +884,11 @@ for traits::VtableImplData<'gcx, N> where N: HashStable<StableHashingContext<'gc
}

impl<'gcx, N> HashStable<StableHashingContext<'gcx>>
for traits::VtableDefaultImplData<N> where N: HashStable<StableHashingContext<'gcx>> {
for traits::VtableAutoImplData<N> where N: HashStable<StableHashingContext<'gcx>> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'gcx>,
hasher: &mut StableHasher<W>) {
let traits::VtableDefaultImplData {
let traits::VtableAutoImplData {
trait_def_id,
ref nested,
} = *self;
2 changes: 1 addition & 1 deletion src/librustc/middle/dead.rs
Original file line number Diff line number Diff line change
@@ -562,7 +562,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
hir::ItemStruct(..) |
hir::ItemUnion(..) |
hir::ItemTrait(..) |
hir::ItemDefaultImpl(..) |
hir::ItemAutoImpl(..) |
hir::ItemImpl(..) => self.tcx.sess.codemap().def_span(item.span),
_ => item.span,
};
2 changes: 1 addition & 1 deletion src/librustc/middle/reachable.rs
Original file line number Diff line number Diff line change
@@ -270,7 +270,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
hir::ItemMod(..) | hir::ItemForeignMod(..) |
hir::ItemImpl(..) | hir::ItemTrait(..) |
hir::ItemStruct(..) | hir::ItemEnum(..) |
hir::ItemUnion(..) | hir::ItemDefaultImpl(..) |
hir::ItemUnion(..) | hir::ItemAutoImpl(..) |
hir::ItemGlobalAsm(..) => {}
}
}
Loading