Skip to content

Commit 0f7effe

Browse files
committed
---
yaml --- r: 157217 b: refs/heads/master c: a0ee7c9 h: refs/heads/master i: 157215: f1dbaa2 v: v3
1 parent d99045e commit 0f7effe

Some content is hidden

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

42 files changed

+389
-436
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: fc3ed0c8084960ea40e95ee0505d42ede96e8158
2+
refs/heads/master: a0ee7c9f55b90a541db1f6f36d18562bdf5ef6bf
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: d44ea720fa9dfe062ef06d0eb49a58d4e7e92344
55
refs/heads/try: 6ecdf1fa83d7cdbf44a0091132e9c6580be72275

trunk/mk/llvm.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ endif
3838
# the stamp in the source dir.
3939
$$(LLVM_STAMP_$(1)): $(S)src/rustllvm/llvm-auto-clean-trigger
4040
@$$(call E, make: cleaning llvm)
41-
$(Q)$(MAKE) clean-llvm$(1)
41+
$(Q)$(MAKE) clean-llvm
4242
@$$(call E, make: done cleaning llvm)
4343
touch $$@
4444

trunk/src/doc/guide-lifetimes.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ a reference.
5656
fn compute_distance(p1: &Point, p2: &Point) -> f64 {
5757
let x_d = p1.x - p2.x;
5858
let y_d = p1.y - p2.y;
59-
(x_d * x_d + y_d * y_d).sqrt()
59+
sqrt(x_d * x_d + y_d * y_d)
6060
}
6161
~~~
6262

trunk/src/doc/reference.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,7 +1153,7 @@ exposing an API making it possible for it to occur in safe code.
11531153

11541154
* Data races
11551155
* Dereferencing a null/dangling raw pointer
1156-
* Mutating an immutable value/reference without `UnsafeCell`
1156+
* Mutating an immutable value/reference
11571157
* Reads of [undef](http://llvm.org/docs/LangRef.html#undefined-values)
11581158
(uninitialized) memory
11591159
* Breaking the [pointer aliasing
@@ -1166,14 +1166,11 @@ exposing an API making it possible for it to occur in safe code.
11661166
* Using `std::ptr::copy_nonoverlapping_memory` (`memcpy32`/`memcpy64`
11671167
instrinsics) on overlapping buffers
11681168
* Invalid values in primitive types, even in private fields/locals:
1169-
* Dangling/null references or boxes
1169+
* Dangling/null pointers in non-raw pointers, or slices
11701170
* A value other than `false` (0) or `true` (1) in a `bool`
11711171
* A discriminant in an `enum` not included in the type definition
11721172
* A value in a `char` which is a surrogate or above `char::MAX`
11731173
* non-UTF-8 byte sequences in a `str`
1174-
* Unwinding into Rust from foreign code or unwinding from Rust into foreign
1175-
code. Rust's failure system is not compatible with exception handling in
1176-
other languages. Unwinding must be caught and handled at FFI boundaries.
11771174

11781175
##### Behaviour not considered unsafe
11791176

trunk/src/doc/rustdoc.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ testing this code, the `fib` function will be included (so it can compile).
221221

222222
Running tests often requires some special configuration to filter tests, find
223223
libraries, or try running ignored examples. The testing framework that rustdoc
224-
uses is built on crate `test`, which is also used when you compile crates with
224+
uses is build on crate `test`, which is also used when you compile crates with
225225
rustc's `--test` flag. Extra arguments can be passed to rustdoc's test harness
226226
with the `--test-args` flag.
227227

trunk/src/libarena/lib.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -208,13 +208,13 @@ impl Arena {
208208
}
209209

210210
#[inline]
211-
fn alloc_copy<T>(&self, op: || -> T) -> &mut T {
211+
fn alloc_copy<T>(&self, op: || -> T) -> &T {
212212
unsafe {
213213
let ptr = self.alloc_copy_inner(mem::size_of::<T>(),
214214
mem::min_align_of::<T>());
215215
let ptr = ptr as *mut T;
216216
ptr::write(&mut (*ptr), op());
217-
return &mut *ptr;
217+
return &*ptr;
218218
}
219219
}
220220

@@ -262,7 +262,7 @@ impl Arena {
262262
}
263263

264264
#[inline]
265-
fn alloc_noncopy<T>(&self, op: || -> T) -> &mut T {
265+
fn alloc_noncopy<T>(&self, op: || -> T) -> &T {
266266
unsafe {
267267
let tydesc = get_tydesc::<T>();
268268
let (ty_ptr, ptr) =
@@ -279,14 +279,14 @@ impl Arena {
279279
// the object is there.
280280
*ty_ptr = bitpack_tydesc_ptr(tydesc, true);
281281

282-
return &mut *ptr;
282+
return &*ptr;
283283
}
284284
}
285285

286286
/// Allocates a new item in the arena, using `op` to initialize the value,
287287
/// and returns a reference to it.
288288
#[inline]
289-
pub fn alloc<T>(&self, op: || -> T) -> &mut T {
289+
pub fn alloc<T>(&self, op: || -> T) -> &T {
290290
unsafe {
291291
if intrinsics::needs_drop::<T>() {
292292
self.alloc_noncopy(op)
@@ -458,12 +458,12 @@ impl<T> TypedArena<T> {
458458

459459
/// Allocates an object in the `TypedArena`, returning a reference to it.
460460
#[inline]
461-
pub fn alloc(&self, object: T) -> &mut T {
461+
pub fn alloc(&self, object: T) -> &T {
462462
if self.ptr == self.end {
463463
self.grow()
464464
}
465465

466-
let ptr: &mut T = unsafe {
466+
let ptr: &T = unsafe {
467467
let ptr: &mut T = mem::transmute(self.ptr);
468468
ptr::write(ptr, object);
469469
self.ptr.set(self.ptr.get().offset(1));

trunk/src/libcore/atomic.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ const UINT_TRUE: uint = -1;
9494
#[stable]
9595
impl AtomicBool {
9696
/// Create a new `AtomicBool`
97-
#[inline]
9897
pub fn new(v: bool) -> AtomicBool {
9998
let val = if v { UINT_TRUE } else { 0 };
10099
AtomicBool { v: UnsafeCell::new(val), nocopy: marker::NoCopy }
@@ -306,7 +305,6 @@ impl AtomicBool {
306305
#[stable]
307306
impl AtomicInt {
308307
/// Create a new `AtomicInt`
309-
#[inline]
310308
pub fn new(v: int) -> AtomicInt {
311309
AtomicInt {v: UnsafeCell::new(v), nocopy: marker::NoCopy}
312310
}
@@ -428,7 +426,6 @@ impl AtomicInt {
428426
#[stable]
429427
impl AtomicUint {
430428
/// Create a new `AtomicUint`
431-
#[inline]
432429
pub fn new(v: uint) -> AtomicUint {
433430
AtomicUint { v: UnsafeCell::new(v), nocopy: marker::NoCopy }
434431
}
@@ -550,7 +547,6 @@ impl AtomicUint {
550547
#[stable]
551548
impl<T> AtomicPtr<T> {
552549
/// Create a new `AtomicPtr`
553-
#[inline]
554550
pub fn new(p: *mut T) -> AtomicPtr<T> {
555551
AtomicPtr { p: UnsafeCell::new(p as uint), nocopy: marker::NoCopy }
556552
}

trunk/src/libcore/num/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1502,7 +1502,7 @@ pub trait Float: Signed + Primitive {
15021502

15031503
/// Take the square root of a number.
15041504
///
1505-
/// Returns NaN if `self` is a negative number.
1505+
/// Returns NaN if `self` is not a non-negative number.
15061506
fn sqrt(self) -> Self;
15071507
/// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
15081508
fn rsqrt(self) -> Self;

trunk/src/librustc/back/write.rs

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -226,10 +226,12 @@ fn create_target_machine(sess: &Session) -> TargetMachineRef {
226226
}
227227
};
228228

229-
let triple = sess.targ_cfg.target_strs.target_triple.as_slice();
230-
231-
let tm = unsafe {
232-
triple.with_c_str(|t| {
229+
unsafe {
230+
sess.targ_cfg
231+
.target_strs
232+
.target_triple
233+
.as_slice()
234+
.with_c_str(|t| {
233235
sess.opts.cg.target_cpu.as_slice().with_c_str(|cpu| {
234236
target_feature(sess).with_c_str(|features| {
235237
llvm::LLVMRustCreateTargetMachine(
@@ -247,15 +249,7 @@ fn create_target_machine(sess: &Session) -> TargetMachineRef {
247249
})
248250
})
249251
})
250-
};
251-
252-
if tm.is_null() {
253-
llvm_err(sess.diagnostic().handler(),
254-
format!("Could not create LLVM TargetMachine for triple: {}",
255-
triple).to_string());
256-
} else {
257-
return tm;
258-
};
252+
}
259253
}
260254

261255

trunk/src/librustc/diagnostics.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ register_diagnostics!(
5353
E0035,
5454
E0036,
5555
E0038,
56+
E0039,
5657
E0040,
5758
E0044,
5859
E0045,

trunk/src/librustc/lint/context.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,8 @@ impl LintStore {
221221

222222
add_lint_group!(sess, "unused",
223223
UNUSED_IMPORTS, UNUSED_VARIABLES, UNUSED_ASSIGNMENTS, DEAD_CODE,
224-
UNUSED_MUT, UNREACHABLE_CODE, UNUSED_EXTERN_CRATES, UNUSED_MUST_USE,
225-
UNUSED_UNSAFE, UNUSED_RESULTS, PATH_STATEMENTS)
224+
UNUSED_MUT, UNREACHABLE_CODE, UNUSED_MUST_USE,
225+
UNUSED_UNSAFE, PATH_STATEMENTS)
226226

227227
// We have one lint pass defined in this module.
228228
self.register_pass(sess, false, box GatherNodeLevels as LintPassObject);

trunk/src/librustc/middle/check_static_recursion.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -99,17 +99,7 @@ impl<'a, 'ast, 'v> Visitor<'v> for CheckItemRecursionVisitor<'a, 'ast> {
9999
Some(&DefStatic(def_id, _)) |
100100
Some(&DefConst(def_id)) if
101101
ast_util::is_local(def_id) => {
102-
match self.ast_map.get(def_id.node) {
103-
ast_map::NodeItem(item) =>
104-
self.visit_item(item),
105-
ast_map::NodeForeignItem(_) => {},
106-
_ => {
107-
self.sess.span_err(e.span,
108-
format!("expected item, found {}",
109-
self.ast_map.node_to_string(def_id.node)).as_slice());
110-
return;
111-
},
112-
}
102+
self.visit_item(&*self.ast_map.expect_item(def_id.node));
113103
}
114104
_ => ()
115105
}

trunk/src/librustc/middle/trans/expr.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -833,7 +833,7 @@ fn trans_def<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
833833
834834
let _icx = push_ctxt("trans_def_lvalue");
835835
match def {
836-
def::DefFn(..) | def::DefStaticMethod(..) | def::DefMethod(..) |
836+
def::DefFn(..) | def::DefStaticMethod(..) |
837837
def::DefStruct(_) | def::DefVariant(..) => {
838838
trans_def_fn_unadjusted(bcx, ref_expr, def)
839839
}
@@ -1191,12 +1191,10 @@ fn trans_def_fn_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
11911191
let llfn = match def {
11921192
def::DefFn(did, _, _) |
11931193
def::DefStruct(did) | def::DefVariant(_, did, _) |
1194-
def::DefStaticMethod(did, def::FromImpl(_), _) |
1195-
def::DefMethod(did, _, def::FromImpl(_)) => {
1194+
def::DefStaticMethod(did, def::FromImpl(_), _) => {
11961195
callee::trans_fn_ref(bcx, did, ExprId(ref_expr.id))
11971196
}
1198-
def::DefStaticMethod(impl_did, def::FromTrait(trait_did), _) |
1199-
def::DefMethod(impl_did, _, def::FromTrait(trait_did)) => {
1197+
def::DefStaticMethod(impl_did, def::FromTrait(trait_did), _) => {
12001198
meth::trans_static_method_callee(bcx, impl_did,
12011199
trait_did, ref_expr.id)
12021200
}

trunk/src/librustc/middle/ty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3631,7 +3631,7 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
36313631
def::DefFn(_, _, true) => RvalueDpsExpr,
36323632

36333633
// Fn pointers are just scalar values.
3634-
def::DefFn(..) | def::DefStaticMethod(..) | def::DefMethod(..) => RvalueDatumExpr,
3634+
def::DefFn(..) | def::DefStaticMethod(..) => RvalueDatumExpr,
36353635

36363636
// Note: there is actually a good case to be made that
36373637
// DefArg's, particularly those of immediate type, ought to

trunk/src/librustc/middle/typeck/astconv.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,7 @@ fn mk_pointer<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
674674
return constr(ty::mk_str(tcx));
675675
}
676676
RPtr(r) => {
677-
return ty::mk_str_slice(tcx, r, a_seq_mutbl);
677+
return ty::mk_str_slice(tcx, r, ast::MutImmutable);
678678
}
679679
}
680680
}

trunk/src/librustc/middle/typeck/check/method.rs

Lines changed: 82 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -619,12 +619,14 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
619619

620620
let tcx = self.tcx();
621621

622-
// It is illegal to invoke a method on a trait instance that refers to
623-
// the `Self` type. Here, we use a substitution that replaces `Self`
624-
// with the object type itself. Hence, a `&self` method will wind up
625-
// with an argument type like `&Trait`.
622+
// It is illegal to invoke a method on a trait instance that
623+
// refers to the `Self` type. An error will be reported by
624+
// `enforce_object_limitations()` if the method refers to the
625+
// `Self` type anywhere other than the receiver. Here, we use
626+
// a substitution that replaces `Self` with the object type
627+
// itself. Hence, a `&self` method will wind up with an
628+
// argument type like `&Trait`.
626629
let rcvr_substs = substs.with_self_ty(self_ty);
627-
628630
let trait_ref = Rc::new(TraitRef {
629631
def_id: did,
630632
substs: rcvr_substs.clone()
@@ -1334,7 +1336,16 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
13341336
self.ty_to_string(rcvr_ty),
13351337
candidate.repr(self.tcx()));
13361338

1337-
let rcvr_substs = candidate.rcvr_substs.clone();
1339+
let mut rcvr_substs = candidate.rcvr_substs.clone();
1340+
1341+
if !self.enforce_object_limitations(candidate) {
1342+
// Here we change `Self` from `Trait` to `err` in the case that
1343+
// this is an illegal object method. This is necessary to prevent
1344+
// the user from getting strange, derivative errors when the method
1345+
// takes an argument/return-type of type `Self` etc.
1346+
rcvr_substs.types.get_mut_slice(SelfSpace)[0] = ty::mk_err();
1347+
}
1348+
13381349
self.enforce_drop_trait_limitations(candidate);
13391350

13401351
// Determine the values for the generic parameters of the method.
@@ -1543,6 +1554,71 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
15431554
}
15441555
}
15451556

1557+
fn enforce_object_limitations(&self, candidate: &Candidate) -> bool {
1558+
/*!
1559+
* There are some limitations to calling functions through an
1560+
* object, because (a) the self type is not known
1561+
* (that's the whole point of a trait instance, after all, to
1562+
* obscure the self type) and (b) the call must go through a
1563+
* vtable and hence cannot be monomorphized.
1564+
*/
1565+
1566+
match candidate.origin {
1567+
MethodStatic(..) |
1568+
MethodTypeParam(..) |
1569+
MethodStaticUnboxedClosure(..) => {
1570+
return true; // not a call to a trait instance
1571+
}
1572+
MethodTraitObject(..) => {}
1573+
}
1574+
1575+
match candidate.method_ty.explicit_self {
1576+
ty::StaticExplicitSelfCategory => { // reason (a) above
1577+
self.tcx().sess.span_err(
1578+
self.span,
1579+
"cannot call a method without a receiver \
1580+
through an object");
1581+
return false;
1582+
}
1583+
1584+
ty::ByValueExplicitSelfCategory |
1585+
ty::ByReferenceExplicitSelfCategory(..) |
1586+
ty::ByBoxExplicitSelfCategory => {}
1587+
}
1588+
1589+
// reason (a) above
1590+
let check_for_self_ty = |ty| -> bool {
1591+
if ty::type_has_self(ty) {
1592+
span_err!(self.tcx().sess, self.span, E0038,
1593+
"cannot call a method whose type contains a \
1594+
self-type through an object");
1595+
false
1596+
} else {
1597+
true
1598+
}
1599+
};
1600+
let ref sig = candidate.method_ty.fty.sig;
1601+
for &input_ty in sig.inputs[1..].iter() {
1602+
if !check_for_self_ty(input_ty) {
1603+
return false;
1604+
}
1605+
}
1606+
if let ty::FnConverging(result_type) = sig.output {
1607+
if !check_for_self_ty(result_type) {
1608+
return false;
1609+
}
1610+
}
1611+
1612+
if candidate.method_ty.generics.has_type_params(subst::FnSpace) {
1613+
// reason (b) above
1614+
span_err!(self.tcx().sess, self.span, E0039,
1615+
"cannot call a generic method through an object");
1616+
return false;
1617+
}
1618+
1619+
true
1620+
}
1621+
15461622
fn enforce_drop_trait_limitations(&self, candidate: &Candidate) {
15471623
// No code can call the finalize method explicitly.
15481624
let bad = match candidate.origin {

trunk/src/librustc/middle/typeck/check/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1687,7 +1687,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16871687
self.register_unsize_obligations(span, &**u)
16881688
}
16891689
ty::UnsizeVtable(ref ty_trait, self_ty) => {
1690-
vtable::check_object_safety(self.tcx(), ty_trait, span);
16911690
// If the type is `Foo+'a`, ensures that the type
16921691
// being cast to `Foo+'a` implements `Foo`:
16931692
vtable::register_object_cast_obligations(self,

0 commit comments

Comments
 (0)