Skip to content

Commit f0897aa

Browse files
author
Jorge Aparicio
committed
OIBIT: for PhantomData<T> check T rather than the struct itself
1 parent 68740b4 commit f0897aa

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

src/librustc/middle/traits/select.rs

+7
Original file line numberDiff line numberDiff line change
@@ -1700,6 +1700,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
17001700
}
17011701
}
17021702

1703+
// for `PhantomData<T>`, we pass `T`
1704+
ty::ty_struct(def_id, substs)
1705+
if Some(def_id) == self.tcx().lang_items.phantom_data() =>
1706+
{
1707+
Some(substs.types.get_slice(TypeSpace).to_vec())
1708+
}
1709+
17031710
ty::ty_struct(def_id, substs) => {
17041711
Some(ty::struct_fields(self.tcx(), def_id, substs).iter()
17051712
.map(|f| f.mt.ty)
+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Ensure that OIBIT checks `T` when it encounters a `PhantomData<T>` field, instead of checking
12+
// the `PhantomData<T>` type itself (which almost always implements a "default" trait
13+
// (`impl Trait for ..`))
14+
15+
#![feature(optin_builtin_traits)]
16+
17+
use std::marker::{MarkerTrait, PhantomData};
18+
19+
unsafe trait Zen: MarkerTrait {}
20+
21+
unsafe impl Zen for .. {}
22+
23+
unsafe impl<'a, T: 'a> Zen for &'a T where T: Sync {}
24+
25+
struct Guard<'a, T: 'a> {
26+
_marker: PhantomData<&'a T>,
27+
}
28+
29+
struct Nested<T>(T);
30+
31+
fn is_zen<T: Zen>(_: T) {}
32+
33+
fn not_sync<T>(x: Guard<T>) {
34+
is_zen(x) //~ error: the trait `core::marker::Sync` is not implemented for the type `T`
35+
}
36+
37+
fn nested_not_sync<T>(x: Nested<Guard<T>>) {
38+
is_zen(x) //~ error: the trait `core::marker::Sync` is not implemented for the type `T`
39+
}
40+
41+
fn main() {}

0 commit comments

Comments
 (0)