Skip to content

Commit 2890508

Browse files
committed
Auto merge of #21689 - FlaPer87:oibit-send-and-friends, r=nikomatsakis
This is one more step towards completing #13231 This series of commits add support for default trait implementations. The changes in this PR don't break existing code and they are expected to preserve the existing behavior in the compiler as far as built-in bounds checks go. The PR adds negative implementations of `Send`/`Sync` for some types and it removes the special cases for `Send`/`Sync` during the trait obligations checks. That is, it now fully relies on the traits check rather than lang items. Once this patch lands and a new snapshot is created, it'll be possible to add default impls for `Send` and `Sync` and remove entirely the use of `BuiltinBound::{BoundSend,BoundSync}` for positive implementations as well. This PR also removes the restriction on negative implementations. That is, it is now possible to add negative implementations for traits other than `Send`/`Sync`
2 parents c4fe7d6 + 3dcc631 commit 2890508

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+1208
-176
lines changed

src/libcore/cell.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@
144144
use clone::Clone;
145145
use cmp::PartialEq;
146146
use default::Default;
147-
use marker::{Copy, Send};
147+
use marker::{Copy, Send, Sync};
148148
use ops::{Deref, DerefMut, Drop};
149149
use option::Option;
150150
use option::Option::{None, Some};
@@ -660,6 +660,8 @@ pub struct UnsafeCell<T> {
660660
pub value: T,
661661
}
662662

663+
impl<T> !Sync for UnsafeCell<T> {}
664+
663665
impl<T> UnsafeCell<T> {
664666
/// Construct a new instance of `UnsafeCell` which will wrap the specified
665667
/// value.

src/libcore/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
#![feature(staged_api)]
6969
#![feature(unboxed_closures)]
7070
#![feature(rustc_attrs)]
71+
#![feature(optin_builtin_traits)]
7172

7273
#[macro_use]
7374
mod macros;

src/libcore/marker.rs

+8
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ pub unsafe trait Send : MarkerTrait {
3939
// empty.
4040
}
4141

42+
impl<T> !Send for *const T { }
43+
impl<T> !Send for *mut T { }
44+
impl !Send for Managed { }
45+
4246
/// Types with a constant size known at compile-time.
4347
#[stable(feature = "rust1", since = "1.0.0")]
4448
#[lang="sized"]
@@ -204,6 +208,10 @@ pub unsafe trait Sync : MarkerTrait {
204208
// Empty
205209
}
206210

211+
impl<T> !Sync for *const T { }
212+
impl<T> !Sync for *mut T { }
213+
impl !Sync for Managed { }
214+
207215
/// A type which is considered "not POD", meaning that it is not
208216
/// implicitly copyable. This is typically embedded in other types to
209217
/// ensure that they are never copied, even if they lack a destructor.

src/librustc/metadata/csearch.rs

+4
Original file line numberDiff line numberDiff line change
@@ -410,3 +410,7 @@ pub fn is_associated_type(cstore: &cstore::CStore, def: ast::DefId) -> bool {
410410
decoder::is_associated_type(&*cdata, def.node)
411411
}
412412

413+
pub fn is_default_trait(cstore: &cstore::CStore, def: ast::DefId) -> bool {
414+
let cdata = cstore.get_crate_data(def.krate);
415+
decoder::is_default_trait(&*cdata, def.node)
416+
}

src/librustc/metadata/decoder.rs

+15-4
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ enum Family {
126126
TupleVariant, // v
127127
StructVariant, // V
128128
Impl, // i
129+
DefaultImpl, // d
129130
Trait, // I
130131
Struct, // S
131132
PublicField, // g
@@ -151,6 +152,7 @@ fn item_family(item: rbml::Doc) -> Family {
151152
'v' => TupleVariant,
152153
'V' => StructVariant,
153154
'i' => Impl,
155+
'd' => DefaultImpl,
154156
'I' => Trait,
155157
'S' => Struct,
156158
'g' => PublicField,
@@ -355,9 +357,9 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum)
355357
let enum_did = item_reqd_and_translated_parent_item(cnum, item);
356358
DlDef(def::DefVariant(enum_did, did, false))
357359
}
358-
Trait => DlDef(def::DefTrait(did)),
360+
Trait => DlDef(def::DefaultImpl(did)),
359361
Enum => DlDef(def::DefTy(did, true)),
360-
Impl => DlImpl(did),
362+
Impl | DefaultImpl => DlImpl(did),
361363
PublicField | InheritedField => DlField,
362364
}
363365
}
@@ -480,7 +482,7 @@ pub fn get_impl_trait<'tcx>(cdata: Cmd,
480482
let item_doc = lookup_item(id, cdata.data());
481483
let fam = item_family(item_doc);
482484
match fam {
483-
Family::Impl => {
485+
Family::Impl | Family::DefaultImpl => {
484486
reader::maybe_get_doc(item_doc, tag_item_trait_ref).map(|tp| {
485487
doc_trait_ref(tp, tcx, cdata)
486488
})
@@ -1356,7 +1358,7 @@ pub fn get_trait_of_item(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt)
13561358
let parent_item_doc = lookup_item(parent_item_id.node, cdata.data());
13571359
match item_family(parent_item_doc) {
13581360
Trait => Some(item_def_id(parent_item_doc, cdata)),
1359-
Impl => {
1361+
Impl | DefaultImpl => {
13601362
reader::maybe_get_doc(parent_item_doc, tag_item_trait_ref)
13611363
.map(|_| item_trait_ref(parent_item_doc, tcx, cdata).def_id)
13621364
}
@@ -1561,3 +1563,12 @@ pub fn is_associated_type(cdata: Cmd, id: ast::NodeId) -> bool {
15611563
Some(item) => item_sort(item) == 't',
15621564
}
15631565
}
1566+
1567+
1568+
pub fn is_default_trait<'tcx>(cdata: Cmd, id: ast::NodeId) -> bool {
1569+
let item_doc = lookup_item(id, cdata.data());
1570+
match item_family(item_doc) {
1571+
Family::DefaultImpl => true,
1572+
_ => false
1573+
}
1574+
}

src/librustc/metadata/encoder.rs

+12
Original file line numberDiff line numberDiff line change
@@ -1193,6 +1193,18 @@ fn encode_info_for_item(ecx: &EncodeContext,
11931193
None => {}
11941194
}
11951195
}
1196+
ast::ItemDefaultImpl(unsafety, ref ast_trait_ref) => {
1197+
add_to_index(item, rbml_w, index);
1198+
rbml_w.start_tag(tag_items_data_item);
1199+
encode_def_id(rbml_w, def_id);
1200+
encode_family(rbml_w, 'd');
1201+
encode_name(rbml_w, item.ident.name);
1202+
encode_unsafety(rbml_w, unsafety);
1203+
1204+
let trait_ref = ty::node_id_to_trait_ref(tcx, ast_trait_ref.ref_id);
1205+
encode_trait_ref(rbml_w, ecx, &*trait_ref, tag_item_trait_ref);
1206+
rbml_w.end_tag();
1207+
}
11961208
ast::ItemImpl(unsafety, polarity, _, ref opt_trait, ref ty, ref ast_items) => {
11971209
// We need to encode information about the default methods we
11981210
// have inherited, so we drive this based on the impl structure.

src/librustc/middle/astencode.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ impl tr for def::Def {
440440
def::DefVariant(e_did, v_did, is_s) => {
441441
def::DefVariant(e_did.tr(dcx), v_did.tr(dcx), is_s)
442442
},
443-
def::DefTrait(did) => def::DefTrait(did.tr(dcx)),
443+
def::DefaultImpl(did) => def::DefaultImpl(did.tr(dcx)),
444444
def::DefTy(did, is_enum) => def::DefTy(did.tr(dcx), is_enum),
445445
def::DefAssociatedTy(did) => def::DefAssociatedTy(did.tr(dcx)),
446446
def::DefAssociatedPath(def::TyParamProvenance::FromSelf(did), ident) =>

src/librustc/middle/def.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ pub enum Def {
3838
// type `U` (indicated by the Ident).
3939
// FIXME(#20301) -- should use Name
4040
DefAssociatedPath(TyParamProvenance, ast::Ident),
41-
DefTrait(ast::DefId),
41+
DefaultImpl(ast::DefId),
4242
DefPrimTy(ast::PrimTy),
4343
DefTyParam(ParamSpace, u32, ast::DefId, ast::Name),
4444
DefUse(ast::DefId),
@@ -135,7 +135,7 @@ impl Def {
135135
DefFn(id, _) | DefStaticMethod(id, _) | DefMod(id) |
136136
DefForeignMod(id) | DefStatic(id, _) |
137137
DefVariant(_, id, _) | DefTy(id, _) | DefAssociatedTy(id) |
138-
DefTyParam(_, _, id, _) | DefUse(id) | DefStruct(id) | DefTrait(id) |
138+
DefTyParam(_, _, id, _) | DefUse(id) | DefStruct(id) | DefaultImpl(id) |
139139
DefMethod(id, _, _) | DefConst(id) |
140140
DefAssociatedPath(TyParamProvenance::FromSelf(id), _) |
141141
DefAssociatedPath(TyParamProvenance::FromParam(id), _) => {

src/librustc/middle/mem_categorization.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
579579
Ok(self.cat_rvalue_node(id, span, expr_ty))
580580
}
581581
def::DefMod(_) | def::DefForeignMod(_) | def::DefUse(_) |
582-
def::DefTrait(_) | def::DefTy(..) | def::DefPrimTy(_) |
582+
def::DefaultImpl(_) | def::DefTy(..) | def::DefPrimTy(_) |
583583
def::DefTyParam(..) | def::DefTyParamBinder(..) | def::DefRegion(_) |
584584
def::DefLabel(_) | def::DefSelfTy(..) |
585585
def::DefAssociatedTy(..) | def::DefAssociatedPath(..)=> {

src/librustc/middle/reachable.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,8 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
290290
ast::ItemTy(..) | ast::ItemStatic(_, _, _) |
291291
ast::ItemMod(..) | ast::ItemForeignMod(..) |
292292
ast::ItemImpl(..) | ast::ItemTrait(..) |
293-
ast::ItemStruct(..) | ast::ItemEnum(..) => {}
293+
ast::ItemStruct(..) | ast::ItemEnum(..) |
294+
ast::ItemDefaultImpl(..) => {}
294295

295296
_ => {
296297
self.tcx.sess.span_bug(item.span,

src/librustc/middle/resolve_lifetime.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
115115
ast::ItemUse(_) |
116116
ast::ItemMod(..) |
117117
ast::ItemMac(..) |
118+
ast::ItemDefaultImpl(..) |
118119
ast::ItemForeignMod(..) |
119120
ast::ItemStatic(..) |
120121
ast::ItemConst(..) => {
@@ -168,7 +169,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
168169
// if this path references a trait, then this will resolve to
169170
// a trait ref, which introduces a binding scope.
170171
match self.def_map.borrow().get(&id) {
171-
Some(&def::DefTrait(..)) => {
172+
Some(&def::DefaultImpl(..)) => {
172173
self.with(LateScope(&Vec::new(), self.scope), |_, this| {
173174
this.visit_path(path, id);
174175
});

src/librustc/middle/traits/mod.rs

+42-3
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,12 @@ pub enum Vtable<'tcx, N> {
221221
/// Vtable identifying a particular impl.
222222
VtableImpl(VtableImplData<'tcx, N>),
223223

224+
/// Vtable for default trait implementations
225+
/// This carries the information and nested obligations with regards
226+
/// to a default implementation for a trait `Trait`. The nested obligations
227+
/// ensure the trait implementation holds for all the constituent types.
228+
VtableDefaultImpl(VtableDefaultImplData<N>),
229+
224230
/// Successful resolution to an obligation provided by the caller
225231
/// for some type parameter. The `Vec<N>` represents the
226232
/// obligations incurred from normalizing the where-clause (if
@@ -259,6 +265,12 @@ pub struct VtableImplData<'tcx, N> {
259265
pub nested: subst::VecPerParamSpace<N>
260266
}
261267

268+
#[derive(Debug,Clone)]
269+
pub struct VtableDefaultImplData<N> {
270+
pub trait_def_id: ast::DefId,
271+
pub nested: Vec<N>
272+
}
273+
262274
#[derive(Debug,Clone)]
263275
pub struct VtableBuiltinData<N> {
264276
pub nested: subst::VecPerParamSpace<N>
@@ -513,17 +525,18 @@ impl<'tcx, N> Vtable<'tcx, N> {
513525
pub fn iter_nested(&self) -> Iter<N> {
514526
match *self {
515527
VtableImpl(ref i) => i.iter_nested(),
516-
VtableFnPointer(..) => (&[]).iter(),
517-
VtableClosure(..) => (&[]).iter(),
518528
VtableParam(ref n) => n.iter(),
519-
VtableObject(_) => (&[]).iter(),
520529
VtableBuiltin(ref i) => i.iter_nested(),
530+
VtableObject(_) |
531+
VtableDefaultImpl(..) | VtableFnPointer(..) |
532+
VtableClosure(..) => (&[]).iter(),
521533
}
522534
}
523535

524536
pub fn map_nested<M, F>(&self, op: F) -> Vtable<'tcx, M> where F: FnMut(&N) -> M {
525537
match *self {
526538
VtableImpl(ref i) => VtableImpl(i.map_nested(op)),
539+
VtableDefaultImpl(ref t) => VtableDefaultImpl(t.map_nested(op)),
527540
VtableFnPointer(ref sig) => VtableFnPointer((*sig).clone()),
528541
VtableClosure(d, ref s) => VtableClosure(d, s.clone()),
529542
VtableParam(ref n) => VtableParam(n.iter().map(op).collect()),
@@ -539,6 +552,7 @@ impl<'tcx, N> Vtable<'tcx, N> {
539552
VtableImpl(i) => VtableImpl(i.map_move_nested(op)),
540553
VtableFnPointer(sig) => VtableFnPointer(sig),
541554
VtableClosure(d, s) => VtableClosure(d, s),
555+
VtableDefaultImpl(t) => VtableDefaultImpl(t.map_move_nested(op)),
542556
VtableParam(n) => VtableParam(n.into_iter().map(op).collect()),
543557
VtableObject(p) => VtableObject(p),
544558
VtableBuiltin(no) => VtableBuiltin(no.map_move_nested(op)),
@@ -573,6 +587,31 @@ impl<'tcx, N> VtableImplData<'tcx, N> {
573587
}
574588
}
575589

590+
impl<N> VtableDefaultImplData<N> {
591+
pub fn iter_nested(&self) -> Iter<N> {
592+
self.nested.iter()
593+
}
594+
595+
pub fn map_nested<M, F>(&self, op: F) -> VtableDefaultImplData<M> where
596+
F: FnMut(&N) -> M,
597+
{
598+
VtableDefaultImplData {
599+
trait_def_id: self.trait_def_id,
600+
nested: self.nested.iter().map(op).collect()
601+
}
602+
}
603+
604+
pub fn map_move_nested<M, F>(self, op: F) -> VtableDefaultImplData<M> where
605+
F: FnMut(N) -> M,
606+
{
607+
let VtableDefaultImplData { trait_def_id, nested } = self;
608+
VtableDefaultImplData {
609+
trait_def_id: trait_def_id,
610+
nested: nested.into_iter().map(op).collect()
611+
}
612+
}
613+
}
614+
576615
impl<N> VtableBuiltinData<N> {
577616
pub fn iter_nested(&self) -> Iter<N> {
578617
self.nested.iter()

src/librustc/middle/traits/project.rs

+1
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,7 @@ fn assemble_candidates_from_impls<'cx,'tcx>(
709709
// projection. And the projection where clause is handled
710710
// in `assemble_candidates_from_param_env`.
711711
}
712+
super::VtableDefaultImpl(..) |
712713
super::VtableBuiltin(..) => {
713714
// These traits have no associated types.
714715
selcx.tcx().sess.span_bug(

0 commit comments

Comments
 (0)