Skip to content

Commit d01d97a

Browse files
committed
---
yaml --- r: 123901 b: refs/heads/snap-stage3 c: f9fe251 h: refs/heads/master i: 123899: 9ad804f v: v3
1 parent a6869a0 commit d01d97a

File tree

11 files changed

+547
-526
lines changed

11 files changed

+547
-526
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: 4e2da7cb79143b0e7206a684629ed942599ec8e9
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: 6f96abf7389c6a031c549a9df0b672b7989fbe8b
4+
refs/heads/snap-stage3: f9fe251777e9f1cc557a6d5b82b45403935d0a10
55
refs/heads/try: 296eb104620b346d88bc4a2c2ab7693e6d3db019
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/libcore/iter.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,7 @@ impl<A, B, T: ExactSize<A>, U: ExactSize<B>> ExactSize<(A, B)> for Zip<T, U> {}
751751

752752
/// An double-ended iterator with the direction inverted
753753
#[deriving(Clone)]
754+
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
754755
pub struct Rev<T> {
755756
iter: T
756757
}
@@ -779,6 +780,7 @@ impl<A, T: DoubleEndedIterator<A> + RandomAccessIterator<A>> RandomAccessIterato
779780
}
780781

781782
/// A mutable reference to an iterator
783+
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
782784
pub struct ByRef<'a, T> {
783785
iter: &'a mut T
784786
}
@@ -1039,6 +1041,7 @@ impl<A, T: Clone + Iterator<A>> CloneableIterator for T {
10391041

10401042
/// An iterator that repeats endlessly
10411043
#[deriving(Clone)]
1044+
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
10421045
pub struct Cycle<T> {
10431046
orig: T,
10441047
iter: T,
@@ -1090,6 +1093,7 @@ impl<A, T: Clone + RandomAccessIterator<A>> RandomAccessIterator<A> for Cycle<T>
10901093

10911094
/// An iterator which strings two iterators together
10921095
#[deriving(Clone)]
1096+
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
10931097
pub struct Chain<T, U> {
10941098
a: T,
10951099
b: U,
@@ -1159,6 +1163,7 @@ for Chain<T, U> {
11591163

11601164
/// An iterator which iterates two other iterators simultaneously
11611165
#[deriving(Clone)]
1166+
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
11621167
pub struct Zip<T, U> {
11631168
a: T,
11641169
b: U
@@ -1237,6 +1242,7 @@ RandomAccessIterator<(A, B)> for Zip<T, U> {
12371242
}
12381243

12391244
/// An iterator which maps the values of `iter` with `f`
1245+
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
12401246
pub struct Map<'a, A, B, T> {
12411247
iter: T,
12421248
f: |A|: 'a -> B
@@ -1287,6 +1293,7 @@ impl<'a, A, B, T: RandomAccessIterator<A>> RandomAccessIterator<B> for Map<'a, A
12871293
}
12881294

12891295
/// An iterator which filters the elements of `iter` with `predicate`
1296+
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
12901297
pub struct Filter<'a, A, T> {
12911298
iter: T,
12921299
predicate: |&A|: 'a -> bool
@@ -1331,6 +1338,7 @@ impl<'a, A, T: DoubleEndedIterator<A>> DoubleEndedIterator<A> for Filter<'a, A,
13311338
}
13321339

13331340
/// An iterator which uses `f` to both filter and map elements from `iter`
1341+
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
13341342
pub struct FilterMap<'a, A, B, T> {
13351343
iter: T,
13361344
f: |A|: 'a -> Option<B>
@@ -1375,6 +1383,7 @@ for FilterMap<'a, A, B, T> {
13751383

13761384
/// An iterator which yields the current count and the element during iteration
13771385
#[deriving(Clone)]
1386+
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
13781387
pub struct Enumerate<T> {
13791388
iter: T,
13801389
count: uint
@@ -1429,6 +1438,7 @@ impl<A, T: RandomAccessIterator<A>> RandomAccessIterator<(uint, A)> for Enumerat
14291438
}
14301439

14311440
/// An iterator with a `peek()` that returns an optional reference to the next element.
1441+
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
14321442
pub struct Peekable<A, T> {
14331443
iter: T,
14341444
peeked: Option<A>,
@@ -1479,6 +1489,7 @@ impl<'a, A, T: Iterator<A>> Peekable<A, T> {
14791489
}
14801490

14811491
/// An iterator which rejects elements while `predicate` is true
1492+
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
14821493
pub struct SkipWhile<'a, A, T> {
14831494
iter: T,
14841495
flag: bool,
@@ -1517,6 +1528,7 @@ impl<'a, A, T: Iterator<A>> Iterator<A> for SkipWhile<'a, A, T> {
15171528
}
15181529

15191530
/// An iterator which only accepts elements while `predicate` is true
1531+
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
15201532
pub struct TakeWhile<'a, A, T> {
15211533
iter: T,
15221534
flag: bool,
@@ -1552,6 +1564,7 @@ impl<'a, A, T: Iterator<A>> Iterator<A> for TakeWhile<'a, A, T> {
15521564

15531565
/// An iterator which skips over `n` elements of `iter`.
15541566
#[deriving(Clone)]
1567+
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
15551568
pub struct Skip<T> {
15561569
iter: T,
15571570
n: uint
@@ -1616,6 +1629,7 @@ impl<A, T: RandomAccessIterator<A>> RandomAccessIterator<A> for Skip<T> {
16161629

16171630
/// An iterator which only iterates over the first `n` iterations of `iter`.
16181631
#[deriving(Clone)]
1632+
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
16191633
pub struct Take<T> {
16201634
iter: T,
16211635
n: uint
@@ -1665,6 +1679,7 @@ impl<A, T: RandomAccessIterator<A>> RandomAccessIterator<A> for Take<T> {
16651679

16661680

16671681
/// An iterator to maintain state while iterating another iterator
1682+
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
16681683
pub struct Scan<'a, A, B, T, St> {
16691684
iter: T,
16701685
f: |&mut St, A|: 'a -> Option<B>,
@@ -1689,6 +1704,7 @@ impl<'a, A, B, T: Iterator<A>, St> Iterator<B> for Scan<'a, A, B, T, St> {
16891704
/// An iterator that maps each element to an iterator,
16901705
/// and yields the elements of the produced iterators
16911706
///
1707+
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
16921708
pub struct FlatMap<'a, A, T, U> {
16931709
iter: T,
16941710
f: |A|: 'a -> U,
@@ -1748,6 +1764,7 @@ impl<'a,
17481764
/// An iterator that yields `None` forever after the underlying iterator
17491765
/// yields `None` once.
17501766
#[deriving(Clone)]
1767+
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
17511768
pub struct Fuse<T> {
17521769
iter: T,
17531770
done: bool
@@ -1820,6 +1837,7 @@ impl<T> Fuse<T> {
18201837

18211838
/// An iterator that calls a function with a reference to each
18221839
/// element before yielding it.
1840+
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
18231841
pub struct Inspect<'a, A, T> {
18241842
iter: T,
18251843
f: |&A|: 'a
@@ -2299,4 +2317,3 @@ pub mod order {
22992317
}
23002318
}
23012319
}
2302-

branches/snap-stage3/src/librustc/lint/builtin.rs

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -669,22 +669,13 @@ impl LintPass for UnusedResult {
669669
if ast_util::is_local(did) {
670670
match cx.tcx.map.get(did.node) {
671671
ast_map::NodeItem(it) => {
672-
if attr::contains_name(it.attrs.as_slice(),
673-
"must_use") {
674-
cx.span_lint(UNUSED_MUST_USE, s.span,
675-
"unused result which must be used");
676-
warned = true;
677-
}
672+
warned |= check_must_use(cx, it.attrs.as_slice(), s.span);
678673
}
679674
_ => {}
680675
}
681676
} else {
682677
csearch::get_item_attrs(&cx.sess().cstore, did, |attrs| {
683-
if attr::contains_name(attrs.as_slice(), "must_use") {
684-
cx.span_lint(UNUSED_MUST_USE, s.span,
685-
"unused result which must be used");
686-
warned = true;
687-
}
678+
warned |= check_must_use(cx, attrs.as_slice(), s.span);
688679
});
689680
}
690681
}
@@ -693,6 +684,25 @@ impl LintPass for UnusedResult {
693684
if !warned {
694685
cx.span_lint(UNUSED_RESULT, s.span, "unused result");
695686
}
687+
688+
fn check_must_use(cx: &Context, attrs: &[ast::Attribute], sp: Span) -> bool {
689+
for attr in attrs.iter() {
690+
if attr.check_name("must_use") {
691+
let mut msg = "unused result which must be used".to_string();
692+
// check for #[must_use="..."]
693+
match attr.value_str() {
694+
None => {}
695+
Some(s) => {
696+
msg.push_str(": ");
697+
msg.push_str(s.get());
698+
}
699+
}
700+
cx.span_lint(UNUSED_MUST_USE, sp, msg.as_slice());
701+
return true;
702+
}
703+
}
704+
false
705+
}
696706
}
697707
}
698708

branches/snap-stage3/src/librustc/middle/trans/base.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -862,9 +862,12 @@ pub fn trans_external_path(ccx: &CrateContext, did: ast::DefId, t: ty::t) -> Val
862862
ty::ty_bare_fn(ref fn_ty) => {
863863
match fn_ty.abi.for_target(ccx.sess().targ_cfg.os,
864864
ccx.sess().targ_cfg.arch) {
865-
Some(Rust) | Some(RustIntrinsic) => {
865+
Some(Rust) => {
866866
get_extern_rust_fn(ccx, t, name.as_slice(), did)
867867
}
868+
Some(RustIntrinsic) => {
869+
ccx.sess().bug("unexpected intrinsic in trans_external_path")
870+
}
868871
Some(..) | None => {
869872
foreign::register_foreign_item_fn(ccx, fn_ty.abi, t,
870873
name.as_slice(), None)
@@ -1781,9 +1784,9 @@ fn register_fn(ccx: &CrateContext,
17811784
-> ValueRef {
17821785
match ty::get(node_type).sty {
17831786
ty::ty_bare_fn(ref f) => {
1784-
assert!(f.abi == Rust || f.abi == RustIntrinsic);
1787+
assert!(f.abi == Rust);
17851788
}
1786-
_ => fail!("expected bare rust fn or an intrinsic")
1789+
_ => fail!("expected bare rust fn")
17871790
};
17881791

17891792
let llfn = decl_rust_fn(ccx, node_type, sym.as_slice());

branches/snap-stage3/src/librustc/middle/trans/callee.rs

Lines changed: 44 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
use arena::TypedArena;
2020
use back::abi;
2121
use back::link;
22-
use driver::session;
2322
use lib::llvm::ValueRef;
2423
use lib::llvm::llvm;
2524
use metadata::csearch;
@@ -40,6 +39,7 @@ use middle::trans::expr;
4039
use middle::trans::glue;
4140
use middle::trans::inline;
4241
use middle::trans::foreign;
42+
use middle::trans::intrinsic;
4343
use middle::trans::meth;
4444
use middle::trans::monomorphize;
4545
use middle::trans::type_::Type;
@@ -53,7 +53,6 @@ use util::ppaux::Repr;
5353
use std::gc::Gc;
5454
use syntax::ast;
5555
use synabi = syntax::abi;
56-
use syntax::ast_map;
5756

5857
pub struct MethodData {
5958
pub llfn: ValueRef,
@@ -68,6 +67,8 @@ pub enum CalleeData {
6867
// value (which is a pair).
6968
Fn(/* llfn */ ValueRef),
7069

70+
Intrinsic(ast::NodeId, subst::Substs),
71+
7172
TraitMethod(MethodData)
7273
}
7374

@@ -119,7 +120,21 @@ fn trans<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) -> Callee<'a> {
119120

120121
fn trans_def<'a>(bcx: &'a Block<'a>, def: def::Def, ref_expr: &ast::Expr)
121122
-> Callee<'a> {
123+
debug!("trans_def(def={}, ref_expr={})", def.repr(bcx.tcx()), ref_expr.repr(bcx.tcx()));
124+
let expr_ty = node_id_type(bcx, ref_expr.id);
122125
match def {
126+
def::DefFn(did, _) if match ty::get(expr_ty).sty {
127+
ty::ty_bare_fn(ref f) => f.abi == synabi::RustIntrinsic,
128+
_ => false
129+
} => {
130+
let substs = node_id_substs(bcx, ExprId(ref_expr.id));
131+
let def_id = if did.krate != ast::LOCAL_CRATE {
132+
inline::maybe_instantiate_inline(bcx.ccx(), did)
133+
} else {
134+
did
135+
};
136+
Callee { bcx: bcx, data: Intrinsic(def_id.node, substs) }
137+
}
123138
def::DefFn(did, _) |
124139
def::DefStaticMethod(did, def::FromImpl(_), _) => {
125140
fn_callee(bcx, trans_fn_ref(bcx, did, ExprId(ref_expr.id)))
@@ -460,27 +475,8 @@ pub fn trans_fn_ref_with_vtables(
460475
}
461476
};
462477

463-
// We must monomorphise if the fn has type parameters, is a rust
464-
// intrinsic, or is a default method. In particular, if we see an
465-
// intrinsic that is inlined from a different crate, we want to reemit the
466-
// intrinsic instead of trying to call it in the other crate.
467-
let must_monomorphise = if !substs.types.is_empty() || is_default {
468-
true
469-
} else if def_id.krate == ast::LOCAL_CRATE {
470-
let map_node = session::expect(
471-
ccx.sess(),
472-
tcx.map.find(def_id.node),
473-
|| "local item should be in ast map".to_string());
474-
475-
match map_node {
476-
ast_map::NodeForeignItem(_) => {
477-
tcx.map.get_foreign_abi(def_id.node) == synabi::RustIntrinsic
478-
}
479-
_ => false
480-
}
481-
} else {
482-
false
483-
};
478+
// We must monomorphise if the fn has type parameters or is a default method.
479+
let must_monomorphise = !substs.types.is_empty() || is_default;
484480

485481
// Create a monomorphic version of generic functions
486482
if must_monomorphise {
@@ -662,6 +658,12 @@ pub fn trans_call_inner<'a>(
662658
let callee = get_callee(bcx, cleanup::CustomScope(arg_cleanup_scope));
663659
let mut bcx = callee.bcx;
664660

661+
let (abi, ret_ty) = match ty::get(callee_ty).sty {
662+
ty::ty_bare_fn(ref f) => (f.abi, f.sig.output),
663+
ty::ty_closure(ref f) => (synabi::Rust, f.sig.output),
664+
_ => fail!("expected bare rust fn or closure in trans_call_inner")
665+
};
666+
665667
let (llfn, llenv, llself) = match callee.data {
666668
Fn(llfn) => {
667669
(llfn, None, None)
@@ -679,14 +681,19 @@ pub fn trans_call_inner<'a>(
679681
let llenv = Load(bcx, llenv);
680682
(llfn, Some(llenv), None)
681683
}
682-
};
684+
Intrinsic(node, substs) => {
685+
assert!(abi == synabi::RustIntrinsic);
686+
assert!(dest.is_some());
683687

684-
let (abi, ret_ty) = match ty::get(callee_ty).sty {
685-
ty::ty_bare_fn(ref f) => (f.abi, f.sig.output),
686-
ty::ty_closure(ref f) => (synabi::Rust, f.sig.output),
687-
_ => fail!("expected bare rust fn or closure in trans_call_inner")
688+
return intrinsic::trans_intrinsic_call(bcx, node, callee_ty,
689+
arg_cleanup_scope, args,
690+
dest.unwrap(), substs);
691+
}
688692
};
689-
let is_rust_fn = abi == synabi::Rust || abi == synabi::RustIntrinsic;
693+
694+
// Intrinsics should not become actual functions.
695+
// We trans them in place in `trans_intrinsic_call`
696+
assert!(abi != synabi::RustIntrinsic);
690697

691698
// Generate a location to store the result. If the user does
692699
// not care about the result, just make a stack slot.
@@ -716,7 +723,7 @@ pub fn trans_call_inner<'a>(
716723
// and done, either the return value of the function will have been
717724
// written in opt_llretslot (if it is Some) or `llresult` will be
718725
// set appropriately (otherwise).
719-
if is_rust_fn {
726+
if abi == synabi::Rust {
720727
let mut llargs = Vec::new();
721728

722729
// Push the out-pointer if we use an out-pointer for this
@@ -816,13 +823,13 @@ pub enum CallArgs<'a> {
816823
ArgOverloadedOp(Datum<Expr>, Option<(Datum<Expr>, ast::NodeId)>),
817824
}
818825

819-
fn trans_args<'a>(cx: &'a Block<'a>,
820-
args: CallArgs,
821-
fn_ty: ty::t,
822-
llargs: &mut Vec<ValueRef> ,
823-
arg_cleanup_scope: cleanup::ScopeId,
824-
ignore_self: bool)
825-
-> &'a Block<'a> {
826+
pub fn trans_args<'a>(cx: &'a Block<'a>,
827+
args: CallArgs,
828+
fn_ty: ty::t,
829+
llargs: &mut Vec<ValueRef> ,
830+
arg_cleanup_scope: cleanup::ScopeId,
831+
ignore_self: bool)
832+
-> &'a Block<'a> {
826833
let _icx = push_ctxt("trans_args");
827834
let arg_tys = ty::ty_fn_args(fn_ty);
828835
let variadic = ty::fn_is_variadic(fn_ty);

branches/snap-stage3/src/librustc/middle/trans/foreign.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ pub fn llvm_calling_convention(ccx: &CrateContext,
7676
abi.for_target(os, arch).map(|abi| {
7777
match abi {
7878
RustIntrinsic => {
79-
// Intrinsics are emitted by monomorphic fn
79+
// Intrinsics are emitted at the call site
8080
ccx.sess().bug("asked to register intrinsic fn");
8181
}
8282

0 commit comments

Comments
 (0)