Skip to content

Commit 6a7d82e

Browse files
author
Jorge Aparicio
committed
add BoundPod, change the semantics of BoundCopy
1 parent 668c647 commit 6a7d82e

File tree

11 files changed

+86
-54
lines changed

11 files changed

+86
-54
lines changed

src/librustc/metadata/tydecode.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -891,9 +891,12 @@ fn parse_builtin_bounds_<F>(st: &mut PState, _conv: &mut F) -> ty::BuiltinBounds
891891
'Z' => {
892892
builtin_bounds.insert(ty::BoundSized);
893893
}
894-
'P' => {
894+
'C' => {
895895
builtin_bounds.insert(ty::BoundCopy);
896896
}
897+
'P' => {
898+
builtin_bounds.insert(ty::BoundPod);
899+
}
897900
'T' => {
898901
builtin_bounds.insert(ty::BoundSync);
899902
}

src/librustc/metadata/tyencode.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,8 @@ pub fn enc_builtin_bounds(w: &mut Encoder, _cx: &ctxt, bs: &ty::BuiltinBounds) {
365365
match bound {
366366
ty::BoundSend => mywrite!(w, "S"),
367367
ty::BoundSized => mywrite!(w, "Z"),
368-
ty::BoundCopy => mywrite!(w, "P"),
368+
ty::BoundCopy => mywrite!(w, "C"),
369+
ty::BoundPod => mywrite!(w, "P"),
369370
ty::BoundSync => mywrite!(w, "T"),
370371
}
371372
}

src/librustc/middle/lang_items.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ impl LanguageItems {
9595
ty::BoundSend => self.require(SendTraitLangItem),
9696
ty::BoundSized => self.require(SizedTraitLangItem),
9797
ty::BoundCopy => self.require(CopyTraitLangItem),
98+
ty::BoundPod => self.require(PodTraitLangItem),
9899
ty::BoundSync => self.require(SyncTraitLangItem),
99100
}
100101
}
@@ -106,6 +107,8 @@ impl LanguageItems {
106107
Some(ty::BoundSized)
107108
} else if Some(id) == self.copy_trait() {
108109
Some(ty::BoundCopy)
110+
} else if Some(id) == self.pod_trait() {
111+
Some(ty::BoundPod)
109112
} else if Some(id) == self.sync_trait() {
110113
Some(ty::BoundSync)
111114
} else {
@@ -242,6 +245,7 @@ lets_do_this! {
242245
SendTraitLangItem, "send", send_trait;
243246
SizedTraitLangItem, "sized", sized_trait;
244247
CopyTraitLangItem, "copy", copy_trait;
248+
PodTraitLangItem, "pod", pod_trait;
245249
SyncTraitLangItem, "sync", sync_trait;
246250

247251
DropTraitLangItem, "drop", drop_trait;

src/librustc/middle/traits/select.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -817,16 +817,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
817817
// and applicable impls. There is a certain set of precedence rules here.
818818

819819
match self.tcx().lang_items.to_builtin_kind(obligation.predicate.def_id()) {
820-
Some(ty::BoundCopy) => {
820+
Some(bound @ ty::BoundCopy) | Some(bound @ ty::BoundPod) => {
821821
debug!("obligation self ty is {}",
822822
obligation.predicate.0.self_ty().repr(self.tcx()));
823823

824-
// User-defined copy impls are permitted, but only for
824+
// User-defined copy/pod impls are permitted, but only for
825825
// structs and enums.
826826
try!(self.assemble_candidates_from_impls(obligation, &mut candidates));
827827

828828
// For other types, we'll use the builtin rules.
829-
try!(self.assemble_builtin_bound_candidates(ty::BoundCopy,
829+
try!(self.assemble_builtin_bound_candidates(bound,
830830
stack,
831831
&mut candidates));
832832
}
@@ -1362,7 +1362,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
13621362
// BUILTIN BOUNDS
13631363
//
13641364
// These cover the traits that are built-in to the language
1365-
// itself. This includes `Copy` and `Sized` for sure. For the
1365+
// itself. This includes `Copy`, `Pod` and `Sized` for sure. For the
13661366
// moment, it also includes `Send` / `Sync` and a few others, but
13671367
// those will hopefully change to library-defined traits in the
13681368
// future.
@@ -1415,7 +1415,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
14151415

14161416
ty::ty_uniq(_) => { // Box<T>
14171417
match bound {
1418-
ty::BoundCopy => Err(Unimplemented),
1418+
ty::BoundCopy | ty::BoundPod => Err(Unimplemented),
14191419

14201420
ty::BoundSized => Ok(If(Vec::new())),
14211421

@@ -1427,7 +1427,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
14271427

14281428
ty::ty_ptr(..) => { // *const T, *mut T
14291429
match bound {
1430-
ty::BoundCopy | ty::BoundSized => Ok(If(Vec::new())),
1430+
ty::BoundCopy | ty::BoundPod | ty::BoundSized => Ok(If(Vec::new())),
14311431

14321432
ty::BoundSync | ty::BoundSend => {
14331433
self.tcx().sess.bug("Send/Sync shouldn't occur in builtin_bounds()");
@@ -1438,7 +1438,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
14381438
ty::ty_trait(ref data) => {
14391439
match bound {
14401440
ty::BoundSized => Err(Unimplemented),
1441-
ty::BoundCopy => {
1441+
ty::BoundCopy | ty::BoundPod => {
14421442
if data.bounds.builtin_bounds.contains(&bound) {
14431443
Ok(If(Vec::new()))
14441444
} else {
@@ -1466,7 +1466,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
14661466
ty::ty_rptr(_, ty::mt { ty: _, mutbl }) => {
14671467
// &mut T or &T
14681468
match bound {
1469-
ty::BoundCopy => {
1469+
ty::BoundCopy | ty::BoundPod => {
14701470
match mutbl {
14711471
// &mut T is affine and hence never `Copy`
14721472
ast::MutMutable => Err(Unimplemented),
@@ -1487,9 +1487,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
14871487
ty::ty_vec(element_ty, ref len) => {
14881488
// [T, ..n] and [T]
14891489
match bound {
1490-
ty::BoundCopy => {
1490+
ty::BoundCopy | ty::BoundPod => {
14911491
match *len {
1492-
// [T, ..n] is copy iff T is copy
1492+
// [T, ..n] is copy iff T is copy, likewise with pod
14931493
Some(_) => Ok(If(vec![element_ty])),
14941494

14951495
// [T] is unsized and hence affine
@@ -1518,7 +1518,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
15181518
self.tcx().sess.bug("Send/Sync shouldn't occur in builtin_bounds()");
15191519
}
15201520

1521-
ty::BoundCopy | ty::BoundSized => Err(Unimplemented),
1521+
ty::BoundCopy | ty::BoundPod | ty::BoundSized => Err(Unimplemented),
15221522
}
15231523
}
15241524

@@ -1612,7 +1612,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
16121612
// First check for markers and other nonsense.
16131613
match bound {
16141614
// Fallback to whatever user-defined impls exist in this case.
1615-
ty::BoundCopy => Ok(ParameterBuiltin),
1615+
ty::BoundCopy | ty::BoundPod => Ok(ParameterBuiltin),
16161616

16171617
// Sized if all the component types are sized.
16181618
ty::BoundSized => Ok(If(types)),

src/librustc/middle/ty.rs

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ pub use self::IntVarValue::*;
3636
pub use self::ExprAdjustment::*;
3737
pub use self::vtable_origin::*;
3838
pub use self::MethodOrigin::*;
39-
pub use self::CopyImplementationError::*;
39+
pub use self::PodImplementationError::*;
4040

4141
use back::svh::Svh;
4242
use session::Session;
@@ -834,6 +834,11 @@ pub struct ctxt<'tcx> {
834834
/// results are dependent on the parameter environment.
835835
pub type_impls_copy_cache: RefCell<HashMap<Ty<'tcx>,bool>>,
836836

837+
/// Caches whether types are known to impl Pod. Note that type
838+
/// parameters are never placed into this cache, because their
839+
/// results are dependent on the parameter environment.
840+
pub type_impls_pod_cache: RefCell<HashMap<Ty<'tcx>,bool>>,
841+
837842
/// Caches whether types are known to impl Sized. Note that type
838843
/// parameters are never placed into this cache, because their
839844
/// results are dependent on the parameter environment.
@@ -1601,6 +1606,7 @@ pub enum BuiltinBound {
16011606
BoundSend,
16021607
BoundSized,
16031608
BoundCopy,
1609+
BoundPod,
16041610
BoundSync,
16051611
}
16061612

@@ -2612,6 +2618,7 @@ pub fn mk_ctxt<'tcx>(s: Session,
26122618
selection_cache: traits::SelectionCache::new(),
26132619
repr_hint_cache: RefCell::new(DefIdMap()),
26142620
type_impls_copy_cache: RefCell::new(HashMap::new()),
2621+
type_impls_pod_cache: RefCell::new(HashMap::new()),
26152622
type_impls_sized_cache: RefCell::new(HashMap::new()),
26162623
object_safety_cache: RefCell::new(DefIdMap()),
26172624
const_qualif_map: RefCell::new(NodeMap()),
@@ -3747,7 +3754,7 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
37473754
let mut tc = TC::All - TC::InteriorParam;
37483755
for bound in &bounds.builtin_bounds {
37493756
tc = tc - match bound {
3750-
BoundSync | BoundSend | BoundCopy => TC::None,
3757+
BoundSync | BoundSend | BoundCopy | BoundPod => TC::None,
37513758
BoundSized => TC::Nonsized,
37523759
};
37533760
}
@@ -3803,6 +3810,15 @@ pub fn type_moves_by_default<'a,'tcx>(param_env: &ParameterEnvironment<'a,'tcx>,
38033810
!type_impls_bound(param_env, &tcx.type_impls_copy_cache, ty, ty::BoundCopy, span)
38043811
}
38053812

3813+
pub fn type_is_pod<'a,'tcx>(param_env: &ParameterEnvironment<'a,'tcx>,
3814+
span: Span,
3815+
ty: Ty<'tcx>)
3816+
-> bool
3817+
{
3818+
let tcx = param_env.tcx;
3819+
!type_impls_bound(param_env, &tcx.type_impls_pod_cache, ty, ty::BoundPod, span)
3820+
}
3821+
38063822
pub fn type_is_sized<'a,'tcx>(param_env: &ParameterEnvironment<'a,'tcx>,
38073823
span: Span,
38083824
ty: Ty<'tcx>)
@@ -6968,26 +6984,26 @@ pub fn make_substs_for_receiver_types<'tcx>(tcx: &ty::ctxt<'tcx>,
69686984
}
69696985

69706986
#[derive(Copy)]
6971-
pub enum CopyImplementationError {
6972-
FieldDoesNotImplementCopy(ast::Name),
6973-
VariantDoesNotImplementCopy(ast::Name),
6987+
pub enum PodImplementationError {
6988+
FieldDoesNotImplementPod(ast::Name),
6989+
VariantDoesNotImplementPod(ast::Name),
69746990
TypeIsStructural,
69756991
TypeHasDestructor,
69766992
}
69776993

6978-
pub fn can_type_implement_copy<'a,'tcx>(param_env: &ParameterEnvironment<'a, 'tcx>,
6979-
span: Span,
6980-
self_type: Ty<'tcx>)
6981-
-> Result<(),CopyImplementationError>
6994+
pub fn can_type_implement_pod<'a,'tcx>(param_env: &ParameterEnvironment<'a, 'tcx>,
6995+
span: Span,
6996+
self_type: Ty<'tcx>)
6997+
-> Result<(), PodImplementationError>
69826998
{
69836999
let tcx = param_env.tcx;
69847000

69857001
let did = match self_type.sty {
69867002
ty::ty_struct(struct_did, substs) => {
69877003
let fields = ty::struct_fields(tcx, struct_did, substs);
69887004
for field in &fields {
6989-
if type_moves_by_default(param_env, span, field.mt.ty) {
6990-
return Err(FieldDoesNotImplementCopy(field.name))
7005+
if type_is_pod(param_env, span, field.mt.ty) {
7006+
return Err(FieldDoesNotImplementPod(field.name))
69917007
}
69927008
}
69937009
struct_did
@@ -6998,8 +7014,8 @@ pub fn can_type_implement_copy<'a,'tcx>(param_env: &ParameterEnvironment<'a, 'tc
69987014
for variant_arg_type in &variant.args {
69997015
let substd_arg_type =
70007016
variant_arg_type.subst(tcx, substs);
7001-
if type_moves_by_default(param_env, span, substd_arg_type) {
7002-
return Err(VariantDoesNotImplementCopy(variant.name))
7017+
if type_is_pod(param_env, span, substd_arg_type) {
7018+
return Err(VariantDoesNotImplementPod(variant.name))
70037019
}
70047020
}
70057021
}

src/librustc/util/ppaux.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,7 @@ impl<'tcx> Repr<'tcx> for ty::BuiltinBounds {
789789
ty::BoundSend => "Send".to_string(),
790790
ty::BoundSized => "Sized".to_string(),
791791
ty::BoundCopy => "Copy".to_string(),
792+
ty::BoundPod => "Pod".to_string(),
792793
ty::BoundSync => "Sync".to_string(),
793794
});
794795
}
@@ -1181,6 +1182,7 @@ impl<'tcx> UserString<'tcx> for ty::BuiltinBound {
11811182
ty::BoundSend => "Send".to_string(),
11821183
ty::BoundSized => "Sized".to_string(),
11831184
ty::BoundCopy => "Copy".to_string(),
1185+
ty::BoundPod => "Pod".to_string(),
11841186
ty::BoundSync => "Sync".to_string(),
11851187
}
11861188
}

src/librustc_lint/builtin.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -605,10 +605,12 @@ impl LintPass for RawPointerDerive {
605605
}
606606
let did = match item.node {
607607
ast::ItemImpl(_, _, _, ref t_ref_opt, _, _) => {
608-
// Deriving the Copy trait does not cause a warning
608+
// Deriving the Copy/Pod trait does not cause a warning
609609
if let &Some(ref trait_ref) = t_ref_opt {
610610
let def_id = ty::trait_ref_to_def_id(cx.tcx, trait_ref);
611-
if Some(def_id) == cx.tcx.lang_items.copy_trait() {
611+
if Some(def_id) == cx.tcx.lang_items.copy_trait() ||
612+
Some(def_id) == cx.tcx.lang_items.pod_trait()
613+
{
612614
return;
613615
}
614616
}
@@ -1674,11 +1676,11 @@ impl LintPass for MissingCopyImplementations {
16741676
if !ty::type_moves_by_default(&parameter_environment, item.span, ty) {
16751677
return;
16761678
}
1677-
if ty::can_type_implement_copy(&parameter_environment, item.span, ty).is_ok() {
1679+
if ty::can_type_implement_pod(&parameter_environment, item.span, ty).is_ok() {
16781680
cx.span_lint(MISSING_COPY_IMPLEMENTATIONS,
16791681
item.span,
1680-
"type could implement `Copy`; consider adding `impl \
1681-
Copy`")
1682+
"type could implement `Pod`; consider adding `impl \
1683+
Pod`")
16821684
}
16831685
}
16841686
}

src/librustc_typeck/check/dropck.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>(
231231
Some(ty::BoundSend) |
232232
Some(ty::BoundSized) |
233233
Some(ty::BoundCopy) |
234+
Some(ty::BoundPod) |
234235
Some(ty::BoundSync) => false,
235236
_ => true,
236237
}

src/librustc_typeck/check/wf.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
266266
}
267267
}
268268

269-
if fcx.tcx().lang_items.copy_trait() == Some(trait_ref.def_id) {
269+
if fcx.tcx().lang_items.pod_trait() == Some(trait_ref.def_id) {
270270
// This is checked in coherence.
271271
return
272272
}

0 commit comments

Comments
 (0)