Skip to content

Commit ed22606

Browse files
committed
auto merge of #20285 : FlaPer87/rust/oibit-send-and-friends, r=nikomatsakis
This commit introduces the syntax for negative implementations of traits as shown below: `impl !Trait for Type {}` cc #13231 Part of RFC rust-lang/rfcs#127 r? @nikomatsakis
2 parents ad9e759 + c062fac commit ed22606

35 files changed

+215
-39
lines changed

src/librustc/lint/builtin.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1762,7 +1762,7 @@ impl LintPass for Stability {
17621762
}
17631763
}
17641764
}
1765-
ast::ItemImpl(_, _, Some(ref t), _, _) => {
1765+
ast::ItemImpl(_, _, _, Some(ref t), _, _) => {
17661766
let id = ty::trait_ref_to_def_id(cx.tcx, t);
17671767
self.lint(cx, id, t.path.span);
17681768
}

src/librustc/metadata/common.rs

+2
Original file line numberDiff line numberDiff line change
@@ -259,3 +259,5 @@ pub const tag_unsafety: uint = 0xb1;
259259

260260
pub const tag_associated_type_names: uint = 0xb2;
261261
pub const tag_associated_type_name: uint = 0xb3;
262+
263+
pub const tag_polarity: uint = 0xb4;

src/librustc/metadata/encoder.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -1207,7 +1207,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
12071207
None => {}
12081208
}
12091209
}
1210-
ast::ItemImpl(unsafety, _, ref opt_trait, ref ty, ref ast_items) => {
1210+
ast::ItemImpl(unsafety, polarity, _, ref opt_trait, ref ty, ref ast_items) => {
12111211
// We need to encode information about the default methods we
12121212
// have inherited, so we drive this based on the impl structure.
12131213
let impl_items = tcx.impl_items.borrow();
@@ -1221,6 +1221,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
12211221
encode_name(rbml_w, item.ident.name);
12221222
encode_attributes(rbml_w, item.attrs[]);
12231223
encode_unsafety(rbml_w, unsafety);
1224+
encode_polarity(rbml_w, polarity);
12241225
match ty.node {
12251226
ast::TyPath(ref path, _) if path.segments.len() == 1 => {
12261227
let ident = path.segments.last().unwrap().identifier;
@@ -1704,6 +1705,14 @@ fn encode_associated_type_names(rbml_w: &mut Encoder, names: &[ast::Name]) {
17041705
rbml_w.end_tag();
17051706
}
17061707

1708+
fn encode_polarity(rbml_w: &mut Encoder, polarity: ast::ImplPolarity) {
1709+
let byte: u8 = match polarity {
1710+
ast::ImplPolarity::Positive => 0,
1711+
ast::ImplPolarity::Negative => 1,
1712+
};
1713+
rbml_w.wr_tagged_u8(tag_polarity, byte);
1714+
}
1715+
17071716
fn encode_crate_deps(rbml_w: &mut Encoder, cstore: &cstore::CStore) {
17081717
fn get_ordered_deps(cstore: &cstore::CStore) -> Vec<decoder::CrateDep> {
17091718
// Pull the cnums and name,vers,hash out of cstore
@@ -1885,7 +1894,7 @@ struct ImplVisitor<'a, 'b:'a, 'c:'a, 'tcx:'b> {
18851894

18861895
impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'b, 'c, 'tcx> {
18871896
fn visit_item(&mut self, item: &ast::Item) {
1888-
if let ast::ItemImpl(_, _, Some(ref trait_ref), _, _) = item.node {
1897+
if let ast::ItemImpl(_, _, _, Some(ref trait_ref), _, _) = item.node {
18891898
let def_map = &self.ecx.tcx.def_map;
18901899
let trait_def = def_map.borrow()[trait_ref.ref_id].clone();
18911900
let def_id = trait_def.def_id();

src/librustc/middle/dead.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ impl<'v> Visitor<'v> for LifeSeeder {
355355
ast::ItemEnum(ref enum_def, _) if allow_dead_code => {
356356
self.worklist.extend(enum_def.variants.iter().map(|variant| variant.node.id));
357357
}
358-
ast::ItemImpl(_, _, Some(ref _trait_ref), _, ref impl_items) => {
358+
ast::ItemImpl(_, _, _, Some(ref _trait_ref), _, ref impl_items) => {
359359
for impl_item in impl_items.iter() {
360360
match *impl_item {
361361
ast::MethodImplItem(ref method) => {

src/librustc/middle/infer/error_reporting.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1712,7 +1712,7 @@ fn lifetimes_in_scope(tcx: &ty::ctxt,
17121712
match tcx.map.find(parent) {
17131713
Some(node) => match node {
17141714
ast_map::NodeItem(item) => match item.node {
1715-
ast::ItemImpl(_, ref gen, _, _, _) => {
1715+
ast::ItemImpl(_, _, ref gen, _, _, _) => {
17161716
taken.push_all(gen.lifetimes.as_slice());
17171717
}
17181718
_ => ()

src/librustc/middle/privacy.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
287287
// undefined symbols at linkage time if this case is not handled.
288288
//
289289
// * Private trait impls for private types can be completely ignored
290-
ast::ItemImpl(_, _, _, ref ty, ref impl_items) => {
290+
ast::ItemImpl(_, _, _, _, ref ty, ref impl_items) => {
291291
let public_ty = match ty.node {
292292
ast::TyPath(_, id) => {
293293
match self.tcx.def_map.borrow()[id].clone() {
@@ -657,7 +657,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
657657
// invoked, and the struct/enum itself is private. Crawl
658658
// back up the chains to find the relevant struct/enum that
659659
// was private.
660-
ast::ItemImpl(_, _, _, ref ty, _) => {
660+
ast::ItemImpl(_, _, _, _, ref ty, _) => {
661661
let id = match ty.node {
662662
ast::TyPath(_, id) => id,
663663
_ => return Some((err_span, err_msg, None)),
@@ -1137,7 +1137,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
11371137
match item.node {
11381138
// implementations of traits don't need visibility qualifiers because
11391139
// that's controlled by having the trait in scope.
1140-
ast::ItemImpl(_, _, Some(..), _, ref impl_items) => {
1140+
ast::ItemImpl(_, _, _, Some(..), _, ref impl_items) => {
11411141
check_inherited(item.span, item.vis,
11421142
"visibility qualifiers have no effect on trait \
11431143
impls");
@@ -1216,7 +1216,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
12161216
};
12171217
check_inherited(tcx, item.span, item.vis);
12181218
match item.node {
1219-
ast::ItemImpl(_, _, _, _, ref impl_items) => {
1219+
ast::ItemImpl(_, _, _, _, _, ref impl_items) => {
12201220
for impl_item in impl_items.iter() {
12211221
match *impl_item {
12221222
ast::MethodImplItem(ref m) => {
@@ -1361,7 +1361,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
13611361
// (i.e. we could just return here to not check them at
13621362
// all, or some worse estimation of whether an impl is
13631363
// publicly visible.
1364-
ast::ItemImpl(_, ref g, ref trait_ref, ref self_, ref impl_items) => {
1364+
ast::ItemImpl(_, _, ref g, ref trait_ref, ref self_, ref impl_items) => {
13651365
// `impl [... for] Private` is never visible.
13661366
let self_contains_private;
13671367
// impl [... for] Public<...>, but not `impl [... for]

src/librustc/middle/reachable.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ fn item_might_be_inlined(item: &ast::Item) -> bool {
5555
}
5656

5757
match item.node {
58-
ast::ItemImpl(_, ref generics, _, _, _) |
58+
ast::ItemImpl(_, _, ref generics, _, _, _) |
5959
ast::ItemFn(_, _, _, ref generics, _) => {
6060
generics_require_inlining(generics)
6161
}
@@ -216,7 +216,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
216216
.map
217217
.expect_item(impl_did.node)
218218
.node {
219-
ast::ItemImpl(_, ref generics, _, _, _) => {
219+
ast::ItemImpl(_, _, ref generics, _, _, _) => {
220220
generics_require_inlining(generics)
221221
}
222222
_ => false

src/librustc/middle/resolve_lifetime.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
106106
ast::ItemEnum(_, ref generics) |
107107
ast::ItemStruct(_, ref generics) |
108108
ast::ItemTrait(_, ref generics, _, _) |
109-
ast::ItemImpl(_, ref generics, _, _, _) => {
109+
ast::ItemImpl(_, _, ref generics, _, _, _) => {
110110
// These kinds of items have only early bound lifetime parameters.
111111
let lifetimes = &generics.lifetimes;
112112
let early_scope = EarlyScope(subst::TypeSpace, lifetimes, &ROOT_SCOPE);

src/librustc/middle/stability.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ impl<'v> Visitor<'v> for Annotator {
8282
// stability of the trait. This is WRONG, but expedient to get
8383
// libstd stabilized for the 1.0 release.
8484
let use_parent = match i.node {
85-
ast::ItemImpl(_, _, Some(_), _, _) => false,
85+
ast::ItemImpl(_, _, _, Some(_), _, _) => false,
8686
_ => true,
8787
};
8888

src/librustc/middle/ty.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5127,7 +5127,7 @@ pub fn impl_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
51275127
match cx.map.find(id.node) {
51285128
Some(ast_map::NodeItem(item)) => {
51295129
match item.node {
5130-
ast::ItemImpl(_, _, ref opt_trait, _, _) => {
5130+
ast::ItemImpl(_, _, _, ref opt_trait, _, _) => {
51315131
match opt_trait {
51325132
&Some(ref t) => {
51335133
let trait_ref = ty::node_id_to_trait_ref(cx, t.ref_id);

src/librustc_resolve/build_reduced_graph.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
386386
parent.clone()
387387
}
388388

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

530-
ItemImpl(_, _, Some(_), _, _) => parent.clone(),
530+
ItemImpl(_, _, _, Some(_), _, _) => parent.clone(),
531531

532532
ItemTrait(_, _, _, ref items) => {
533533
let name_bindings =

src/librustc_resolve/lib.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -972,7 +972,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
972972
}
973973
}
974974

975-
976975
// Import resolution
977976
//
978977
// This is a fixed-point algorithm. We resolve imports until our efforts
@@ -2837,7 +2836,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
28372836
});
28382837
}
28392838

2840-
ItemImpl(_,
2839+
ItemImpl(_, _,
28412840
ref generics,
28422841
ref implemented_traits,
28432842
ref self_type,

src/librustc_trans/save/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
283283
NodeItem(item) => {
284284
scope_id = item.id;
285285
match item.node {
286-
ast::ItemImpl(_, _, _, ref ty, _) => {
286+
ast::ItemImpl(_, _, _, _, ref ty, _) => {
287287
let mut result = String::from_str("<");
288288
result.push_str(ty_to_string(&**ty)[]);
289289

@@ -1040,7 +1040,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
10401040
self.process_const(item, &**typ, &**expr),
10411041
ast::ItemStruct(ref def, ref ty_params) => self.process_struct(item, &**def, ty_params),
10421042
ast::ItemEnum(ref def, ref ty_params) => self.process_enum(item, def, ty_params),
1043-
ast::ItemImpl(_,
1043+
ast::ItemImpl(_, _,
10441044
ref ty_params,
10451045
ref trait_ref,
10461046
ref typ,

src/librustc_trans/trans/base.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2317,7 +2317,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
23172317
let mut v = TransItemVisitor{ ccx: ccx };
23182318
v.visit_block(&**body);
23192319
}
2320-
ast::ItemImpl(_, ref generics, _, _, ref impl_items) => {
2320+
ast::ItemImpl(_, _, ref generics, _, _, ref impl_items) => {
23212321
meth::trans_impl(ccx,
23222322
item.ident,
23232323
impl_items[],

src/librustc_typeck/check/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,7 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
699699
let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id);
700700
check_bare_fn(ccx, &**decl, &**body, it.id, fn_pty.ty, param_env);
701701
}
702-
ast::ItemImpl(_, _, _, _, ref impl_items) => {
702+
ast::ItemImpl(_, _, _, _, _, ref impl_items) => {
703703
debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id);
704704

705705
let impl_pty = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id));

src/librustc_typeck/coherence/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for CoherenceCheckVisitor<'a, 'tcx> {
102102
//debug!("(checking coherence) item '{}'", token::get_ident(item.ident));
103103

104104
match item.node {
105-
ItemImpl(_, _, ref opt_trait, _, _) => {
105+
ItemImpl(_, _, _, ref opt_trait, _, _) => {
106106
match opt_trait.clone() {
107107
Some(opt_trait) => {
108108
self.cc.check_implementation(item, &[opt_trait]);
@@ -283,7 +283,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
283283
// Converts an implementation in the AST to a vector of items.
284284
fn create_impl_from_item(&self, item: &Item) -> Vec<ImplOrTraitItemId> {
285285
match item.node {
286-
ItemImpl(_, _, ref trait_refs, _, ref ast_items) => {
286+
ItemImpl(_, _, _, ref trait_refs, _, ref ast_items) => {
287287
let mut items: Vec<ImplOrTraitItemId> =
288288
ast_items.iter()
289289
.map(|ast_item| {

src/librustc_typeck/coherence/orphan.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
4444
fn visit_item(&mut self, item: &'v ast::Item) {
4545
let def_id = ast_util::local_def(item.id);
4646
match item.node {
47-
ast::ItemImpl(_, _, None, _, _) => {
47+
ast::ItemImpl(_, _, _, None, _, _) => {
4848
// For inherent impls, self type must be a nominal type
4949
// defined in this crate.
5050
debug!("coherence2::orphan check: inherent impl {}", item.repr(self.tcx));
@@ -69,7 +69,7 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
6969
}
7070
}
7171
}
72-
ast::ItemImpl(_, _, Some(_), _, _) => {
72+
ast::ItemImpl(_, _, _, Some(_), _, _) => {
7373
// "Trait" impl
7474
debug!("coherence2::orphan check: trait impl {}", item.repr(self.tcx));
7575
match traits::orphan_check(self.tcx, def_id) {

src/librustc_typeck/coherence/unsafety.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ struct UnsafetyChecker<'cx, 'tcx:'cx> {
3030
impl<'cx, 'tcx,'v> visit::Visitor<'v> for UnsafetyChecker<'cx, 'tcx> {
3131
fn visit_item(&mut self, item: &'v ast::Item) {
3232
match item.node {
33-
ast::ItemImpl(unsafety, _, _, _, _) => {
33+
ast::ItemImpl(unsafety, _, _, _, _, _) => {
3434
match ty::impl_trait_ref(self.tcx, ast_util::local_def(item.id)) {
3535
None => {
3636
// Inherent impl.

src/librustc_typeck/collect.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
549549
enum_definition.variants.as_slice(),
550550
generics);
551551
},
552-
ast::ItemImpl(_,
552+
ast::ItemImpl(_, _,
553553
ref generics,
554554
ref opt_trait_ref,
555555
ref selfty,

src/librustdoc/doctree.rs

+1
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ pub struct Trait {
182182

183183
pub struct Impl {
184184
pub unsafety: ast::Unsafety,
185+
pub polarity: ast::ImplPolarity,
185186
pub generics: ast::Generics,
186187
pub trait_: Option<ast::TraitRef>,
187188
pub for_: P<ast::Ty>,

src/librustdoc/visit_ast.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -337,9 +337,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
337337
};
338338
om.traits.push(t);
339339
},
340-
ast::ItemImpl(unsafety, ref gen, ref tr, ref ty, ref items) => {
340+
ast::ItemImpl(unsafety, polarity, ref gen, ref tr, ref ty, ref items) => {
341341
let i = Impl {
342342
unsafety: unsafety,
343+
polarity: polarity,
343344
generics: gen.clone(),
344345
trait_: tr.clone(),
345346
for_: ty.clone(),

src/libsyntax/ast.rs

+19
Original file line numberDiff line numberDiff line change
@@ -1299,6 +1299,24 @@ impl fmt::Show for Unsafety {
12991299
}
13001300
}
13011301

1302+
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
1303+
pub enum ImplPolarity {
1304+
/// impl Trait for Type
1305+
Positive,
1306+
/// impl !Trait for Type
1307+
Negative,
1308+
}
1309+
1310+
impl fmt::Show for ImplPolarity {
1311+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1312+
match *self {
1313+
ImplPolarity::Positive => "positive".fmt(f),
1314+
ImplPolarity::Negative => "negative".fmt(f),
1315+
}
1316+
}
1317+
}
1318+
1319+
13021320
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
13031321
pub enum FunctionRetTy {
13041322
/// Functions with return type ! that always
@@ -1587,6 +1605,7 @@ pub enum Item_ {
15871605
TyParamBounds,
15881606
Vec<TraitItem>),
15891607
ItemImpl(Unsafety,
1608+
ImplPolarity,
15901609
Generics,
15911610
Option<TraitRef>, // (optional) trait this impl implements
15921611
P<Ty>, // self

src/libsyntax/ast_map/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -755,7 +755,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
755755
let parent = self.parent;
756756
self.parent = i.id;
757757
match i.node {
758-
ItemImpl(_, _, _, _, ref impl_items) => {
758+
ItemImpl(_, _, _, _, _, ref impl_items) => {
759759
for impl_item in impl_items.iter() {
760760
match *impl_item {
761761
MethodImplItem(ref m) => {

src/libsyntax/config.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,11 @@ fn fold_item_underscore<F>(cx: &mut Context<F>, item: ast::Item_) -> ast::Item_
133133
F: FnMut(&[ast::Attribute]) -> bool
134134
{
135135
let item = match item {
136-
ast::ItemImpl(u, a, b, c, impl_items) => {
136+
ast::ItemImpl(u, o, a, b, c, impl_items) => {
137137
let impl_items = impl_items.into_iter()
138138
.filter(|ii| impl_item_in_cfg(cx, ii))
139139
.collect();
140-
ast::ItemImpl(u, a, b, c, impl_items)
140+
ast::ItemImpl(u, o, a, b, c, impl_items)
141141
}
142142
ast::ItemTrait(u, a, b, methods) => {
143143
let methods = methods.into_iter()

src/libsyntax/ext/deriving/generic/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,7 @@ impl<'a> TraitDef<'a> {
488488
ident,
489489
a,
490490
ast::ItemImpl(ast::Unsafety::Normal,
491+
ast::ImplPolarity::Positive,
491492
trait_generics,
492493
opt_trait_ref,
493494
self_type,

src/libsyntax/ext/expand.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1111,7 +1111,7 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
11111111

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

0 commit comments

Comments
 (0)