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

Add syntax for negative implementations of traits #20285

Merged
merged 2 commits into from
Jan 5, 2015
Merged
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
2 changes: 1 addition & 1 deletion src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1762,7 +1762,7 @@ impl LintPass for Stability {
}
}
}
ast::ItemImpl(_, _, Some(ref t), _, _) => {
ast::ItemImpl(_, _, _, Some(ref t), _, _) => {
let id = ty::trait_ref_to_def_id(cx.tcx, t);
self.lint(cx, id, t.path.span);
}
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/metadata/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,3 +259,5 @@ pub const tag_unsafety: uint = 0xb1;

pub const tag_associated_type_names: uint = 0xb2;
pub const tag_associated_type_name: uint = 0xb3;

pub const tag_polarity: uint = 0xb4;
13 changes: 11 additions & 2 deletions src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1207,7 +1207,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
None => {}
}
}
ast::ItemImpl(unsafety, _, ref opt_trait, ref ty, ref ast_items) => {
ast::ItemImpl(unsafety, polarity, _, ref opt_trait, ref ty, ref ast_items) => {
// We need to encode information about the default methods we
// have inherited, so we drive this based on the impl structure.
let impl_items = tcx.impl_items.borrow();
Expand All @@ -1221,6 +1221,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
encode_name(rbml_w, item.ident.name);
encode_attributes(rbml_w, item.attrs[]);
encode_unsafety(rbml_w, unsafety);
encode_polarity(rbml_w, polarity);
match ty.node {
ast::TyPath(ref path, _) if path.segments.len() == 1 => {
let ident = path.segments.last().unwrap().identifier;
Expand Down Expand Up @@ -1704,6 +1705,14 @@ fn encode_associated_type_names(rbml_w: &mut Encoder, names: &[ast::Name]) {
rbml_w.end_tag();
}

fn encode_polarity(rbml_w: &mut Encoder, polarity: ast::ImplPolarity) {
let byte: u8 = match polarity {
ast::ImplPolarity::Positive => 0,
ast::ImplPolarity::Negative => 1,
};
rbml_w.wr_tagged_u8(tag_polarity, byte);
}

fn encode_crate_deps(rbml_w: &mut Encoder, cstore: &cstore::CStore) {
fn get_ordered_deps(cstore: &cstore::CStore) -> Vec<decoder::CrateDep> {
// Pull the cnums and name,vers,hash out of cstore
Expand Down Expand Up @@ -1885,7 +1894,7 @@ struct ImplVisitor<'a, 'b:'a, 'c:'a, 'tcx:'b> {

impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'b, 'c, 'tcx> {
fn visit_item(&mut self, item: &ast::Item) {
if let ast::ItemImpl(_, _, Some(ref trait_ref), _, _) = item.node {
if let ast::ItemImpl(_, _, _, Some(ref trait_ref), _, _) = item.node {
let def_map = &self.ecx.tcx.def_map;
let trait_def = def_map.borrow()[trait_ref.ref_id].clone();
let def_id = trait_def.def_id();
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/dead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ impl<'v> Visitor<'v> for LifeSeeder {
ast::ItemEnum(ref enum_def, _) if allow_dead_code => {
self.worklist.extend(enum_def.variants.iter().map(|variant| variant.node.id));
}
ast::ItemImpl(_, _, Some(ref _trait_ref), _, ref impl_items) => {
ast::ItemImpl(_, _, _, Some(ref _trait_ref), _, ref impl_items) => {
for impl_item in impl_items.iter() {
match *impl_item {
ast::MethodImplItem(ref method) => {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/infer/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1712,7 +1712,7 @@ fn lifetimes_in_scope(tcx: &ty::ctxt,
match tcx.map.find(parent) {
Some(node) => match node {
ast_map::NodeItem(item) => match item.node {
ast::ItemImpl(_, ref gen, _, _, _) => {
ast::ItemImpl(_, _, ref gen, _, _, _) => {
taken.push_all(gen.lifetimes.as_slice());
}
_ => ()
Expand Down
10 changes: 5 additions & 5 deletions src/librustc/middle/privacy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
// undefined symbols at linkage time if this case is not handled.
//
// * Private trait impls for private types can be completely ignored
ast::ItemImpl(_, _, _, ref ty, ref impl_items) => {
ast::ItemImpl(_, _, _, _, ref ty, ref impl_items) => {
let public_ty = match ty.node {
ast::TyPath(_, id) => {
match self.tcx.def_map.borrow()[id].clone() {
Expand Down Expand Up @@ -657,7 +657,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
// invoked, and the struct/enum itself is private. Crawl
// back up the chains to find the relevant struct/enum that
// was private.
ast::ItemImpl(_, _, _, ref ty, _) => {
ast::ItemImpl(_, _, _, _, ref ty, _) => {
let id = match ty.node {
ast::TyPath(_, id) => id,
_ => return Some((err_span, err_msg, None)),
Expand Down Expand Up @@ -1137,7 +1137,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
match item.node {
// implementations of traits don't need visibility qualifiers because
// that's controlled by having the trait in scope.
ast::ItemImpl(_, _, Some(..), _, ref impl_items) => {
ast::ItemImpl(_, _, _, Some(..), _, ref impl_items) => {
check_inherited(item.span, item.vis,
"visibility qualifiers have no effect on trait \
impls");
Expand Down Expand Up @@ -1216,7 +1216,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
};
check_inherited(tcx, item.span, item.vis);
match item.node {
ast::ItemImpl(_, _, _, _, ref impl_items) => {
ast::ItemImpl(_, _, _, _, _, ref impl_items) => {
for impl_item in impl_items.iter() {
match *impl_item {
ast::MethodImplItem(ref m) => {
Expand Down Expand Up @@ -1361,7 +1361,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
// (i.e. we could just return here to not check them at
// all, or some worse estimation of whether an impl is
// publicly visible.
ast::ItemImpl(_, ref g, ref trait_ref, ref self_, ref impl_items) => {
ast::ItemImpl(_, _, ref g, ref trait_ref, ref self_, ref impl_items) => {
// `impl [... for] Private` is never visible.
let self_contains_private;
// impl [... for] Public<...>, but not `impl [... for]
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/reachable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ fn item_might_be_inlined(item: &ast::Item) -> bool {
}

match item.node {
ast::ItemImpl(_, ref generics, _, _, _) |
ast::ItemImpl(_, _, ref generics, _, _, _) |
ast::ItemFn(_, _, _, ref generics, _) => {
generics_require_inlining(generics)
}
Expand Down Expand Up @@ -216,7 +216,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
.map
.expect_item(impl_did.node)
.node {
ast::ItemImpl(_, ref generics, _, _, _) => {
ast::ItemImpl(_, _, ref generics, _, _, _) => {
generics_require_inlining(generics)
}
_ => false
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/resolve_lifetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
ast::ItemEnum(_, ref generics) |
ast::ItemStruct(_, ref generics) |
ast::ItemTrait(_, ref generics, _, _) |
ast::ItemImpl(_, ref generics, _, _, _) => {
ast::ItemImpl(_, _, ref generics, _, _, _) => {
// These kinds of items have only early bound lifetime parameters.
let lifetimes = &generics.lifetimes;
let early_scope = EarlyScope(subst::TypeSpace, lifetimes, &ROOT_SCOPE);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ impl<'v> Visitor<'v> for Annotator {
// stability of the trait. This is WRONG, but expedient to get
// libstd stabilized for the 1.0 release.
let use_parent = match i.node {
ast::ItemImpl(_, _, Some(_), _, _) => false,
ast::ItemImpl(_, _, _, Some(_), _, _) => false,
_ => true,
};

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5128,7 +5128,7 @@ pub fn impl_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
match cx.map.find(id.node) {
Some(ast_map::NodeItem(item)) => {
match item.node {
ast::ItemImpl(_, _, ref opt_trait, _, _) => {
ast::ItemImpl(_, _, _, ref opt_trait, _, _) => {
match opt_trait {
&Some(ref t) => {
let trait_ref = ty::node_id_to_trait_ref(cx, t.ref_id);
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
parent.clone()
}

ItemImpl(_, _, None, ref ty, ref impl_items) => {
ItemImpl(_, _, _, None, ref ty, ref impl_items) => {
// If this implements an anonymous trait, then add all the
// methods within to a new module, if the type was defined
// within this module.
Expand Down Expand Up @@ -527,7 +527,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
parent.clone()
}

ItemImpl(_, _, Some(_), _, _) => parent.clone(),
ItemImpl(_, _, _, Some(_), _, _) => parent.clone(),

ItemTrait(_, _, _, ref items) => {
let name_bindings =
Expand Down
3 changes: 1 addition & 2 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -972,7 +972,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
}


// Import resolution
//
// This is a fixed-point algorithm. We resolve imports until our efforts
Expand Down Expand Up @@ -2841,7 +2840,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
});
}

ItemImpl(_,
ItemImpl(_, _,
ref generics,
ref implemented_traits,
ref self_type,
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_trans/save/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
NodeItem(item) => {
scope_id = item.id;
match item.node {
ast::ItemImpl(_, _, _, ref ty, _) => {
ast::ItemImpl(_, _, _, _, ref ty, _) => {
let mut result = String::from_str("<");
result.push_str(ty_to_string(&**ty)[]);

Expand Down Expand Up @@ -1040,7 +1040,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
self.process_const(item, &**typ, &**expr),
ast::ItemStruct(ref def, ref ty_params) => self.process_struct(item, &**def, ty_params),
ast::ItemEnum(ref def, ref ty_params) => self.process_enum(item, def, ty_params),
ast::ItemImpl(_,
ast::ItemImpl(_, _,
ref ty_params,
ref trait_ref,
ref typ,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2317,7 +2317,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
let mut v = TransItemVisitor{ ccx: ccx };
v.visit_block(&**body);
}
ast::ItemImpl(_, ref generics, _, _, ref impl_items) => {
ast::ItemImpl(_, _, ref generics, _, _, ref impl_items) => {
meth::trans_impl(ccx,
item.ident,
impl_items[],
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,7 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id);
check_bare_fn(ccx, &**decl, &**body, it.id, fn_pty.ty, param_env);
}
ast::ItemImpl(_, _, _, _, ref impl_items) => {
ast::ItemImpl(_, _, _, _, _, ref impl_items) => {
debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id);

let impl_pty = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id));
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_typeck/coherence/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for CoherenceCheckVisitor<'a, 'tcx> {
//debug!("(checking coherence) item '{}'", token::get_ident(item.ident));

match item.node {
ItemImpl(_, _, ref opt_trait, _, _) => {
ItemImpl(_, _, _, ref opt_trait, _, _) => {
match opt_trait.clone() {
Some(opt_trait) => {
self.cc.check_implementation(item, &[opt_trait]);
Expand Down Expand Up @@ -283,7 +283,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
// Converts an implementation in the AST to a vector of items.
fn create_impl_from_item(&self, item: &Item) -> Vec<ImplOrTraitItemId> {
match item.node {
ItemImpl(_, _, ref trait_refs, _, ref ast_items) => {
ItemImpl(_, _, _, ref trait_refs, _, ref ast_items) => {
let mut items: Vec<ImplOrTraitItemId> =
ast_items.iter()
.map(|ast_item| {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_typeck/coherence/orphan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
fn visit_item(&mut self, item: &'v ast::Item) {
let def_id = ast_util::local_def(item.id);
match item.node {
ast::ItemImpl(_, _, None, _, _) => {
ast::ItemImpl(_, _, _, None, _, _) => {
// For inherent impls, self type must be a nominal type
// defined in this crate.
debug!("coherence2::orphan check: inherent impl {}", item.repr(self.tcx));
Expand All @@ -69,7 +69,7 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
}
}
}
ast::ItemImpl(_, _, Some(_), _, _) => {
ast::ItemImpl(_, _, _, Some(_), _, _) => {
// "Trait" impl
debug!("coherence2::orphan check: trait impl {}", item.repr(self.tcx));
match traits::orphan_check(self.tcx, def_id) {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_typeck/coherence/unsafety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ struct UnsafetyChecker<'cx, 'tcx:'cx> {
impl<'cx, 'tcx,'v> visit::Visitor<'v> for UnsafetyChecker<'cx, 'tcx> {
fn visit_item(&mut self, item: &'v ast::Item) {
match item.node {
ast::ItemImpl(unsafety, _, _, _, _) => {
ast::ItemImpl(unsafety, _, _, _, _, _) => {
match ty::impl_trait_ref(self.tcx, ast_util::local_def(item.id)) {
None => {
// Inherent impl.
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_typeck/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
enum_definition.variants.as_slice(),
generics);
},
ast::ItemImpl(_,
ast::ItemImpl(_, _,
ref generics,
ref opt_trait_ref,
ref selfty,
Expand Down
1 change: 1 addition & 0 deletions src/librustdoc/doctree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ pub struct Trait {

pub struct Impl {
pub unsafety: ast::Unsafety,
pub polarity: ast::ImplPolarity,
pub generics: ast::Generics,
pub trait_: Option<ast::TraitRef>,
pub for_: P<ast::Ty>,
Expand Down
3 changes: 2 additions & 1 deletion src/librustdoc/visit_ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,9 +337,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
};
om.traits.push(t);
},
ast::ItemImpl(unsafety, ref gen, ref tr, ref ty, ref items) => {
ast::ItemImpl(unsafety, polarity, ref gen, ref tr, ref ty, ref items) => {
let i = Impl {
unsafety: unsafety,
polarity: polarity,
generics: gen.clone(),
trait_: tr.clone(),
for_: ty.clone(),
Expand Down
19 changes: 19 additions & 0 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1299,6 +1299,24 @@ impl fmt::Show for Unsafety {
}
}

#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
pub enum ImplPolarity {
/// impl Trait for Type
Positive,
/// impl !Trait for Type
Negative,
}

impl fmt::Show for ImplPolarity {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
ImplPolarity::Positive => "positive".fmt(f),
ImplPolarity::Negative => "negative".fmt(f),
}
}
}


#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
pub enum FunctionRetTy {
/// Functions with return type ! that always
Expand Down Expand Up @@ -1587,6 +1605,7 @@ pub enum Item_ {
TyParamBounds,
Vec<TraitItem>),
ItemImpl(Unsafety,
ImplPolarity,
Generics,
Option<TraitRef>, // (optional) trait this impl implements
P<Ty>, // self
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/ast_map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -755,7 +755,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
let parent = self.parent;
self.parent = i.id;
match i.node {
ItemImpl(_, _, _, _, ref impl_items) => {
ItemImpl(_, _, _, _, _, ref impl_items) => {
for impl_item in impl_items.iter() {
match *impl_item {
MethodImplItem(ref m) => {
Expand Down
4 changes: 2 additions & 2 deletions src/libsyntax/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,11 @@ fn fold_item_underscore<F>(cx: &mut Context<F>, item: ast::Item_) -> ast::Item_
F: FnMut(&[ast::Attribute]) -> bool
{
let item = match item {
ast::ItemImpl(u, a, b, c, impl_items) => {
ast::ItemImpl(u, o, a, b, c, impl_items) => {
let impl_items = impl_items.into_iter()
.filter(|ii| impl_item_in_cfg(cx, ii))
.collect();
ast::ItemImpl(u, a, b, c, impl_items)
ast::ItemImpl(u, o, a, b, c, impl_items)
}
ast::ItemTrait(u, a, b, methods) => {
let methods = methods.into_iter()
Expand Down
1 change: 1 addition & 0 deletions src/libsyntax/ext/deriving/generic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,7 @@ impl<'a> TraitDef<'a> {
ident,
a,
ast::ItemImpl(ast::Unsafety::Normal,
ast::ImplPolarity::Positive,
trait_generics,
opt_trait_ref,
self_type,
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/ext/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1111,7 +1111,7 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {

fn fold_item(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
let prev_type = self.current_impl_type.clone();
if let ast::Item_::ItemImpl(_, _, _, ref ty, _) = item.node {
if let ast::Item_::ItemImpl(_, _, _, _, ref ty, _) = item.node {
self.current_impl_type = Some(ty.clone());
}

Expand Down
Loading