From a32498d8464e0dfa4e2cb31967a66e076da40109 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 31 Jan 2013 17:12:29 -0800 Subject: [PATCH] Make ~fn non-copyable, make &fn copyable, split barefn/closure types, correct handling of moves for struct-record update. Part of #3678. Fixes #2828, #3904, #4719. --- src/compiletest/compiletest.rc | 15 +- src/libcore/at_vec.rs | 4 - src/libcore/bool.rs | 4 - src/libcore/cast.rs | 3 - src/libcore/char.rs | 4 - src/libcore/cleanup.rs | 4 - src/libcore/cmp.rs | 4 - src/libcore/container.rs | 3 - src/libcore/core.rc | 2 - src/libcore/dlist.rs | 4 - src/libcore/dvec.rs | 4 - src/libcore/either.rs | 4 - src/libcore/extfmt.rs | 4 - src/libcore/flate.rs | 4 - src/libcore/from_str.rs | 4 - src/libcore/gc.rs | 3 - src/libcore/hash.rs | 4 - src/libcore/hashmap.rs | 4 - src/libcore/io.rs | 3 - src/libcore/iter-trait.rs | 3 - src/libcore/iter.rs | 3 - src/libcore/libc.rs | 3 - src/libcore/logging.rs | 4 - src/libcore/managed.rs | 4 - src/libcore/mutable.rs | 2 - src/libcore/nil.rs | 4 - src/libcore/num/cmath.rs | 3 - src/libcore/num/f32.rs | 4 - src/libcore/num/f64.rs | 4 - src/libcore/num/float.rs | 4 - src/libcore/num/int-template.rs | 4 - src/libcore/num/uint-template.rs | 4 - src/libcore/ops.rs | 3 - src/libcore/option.rs | 3 - src/libcore/os.rs | 3 - src/libcore/owned.rs | 4 - src/libcore/path.rs | 4 - src/libcore/pipes.rs | 5 - src/libcore/prelude.rs | 2 +- src/libcore/private.rs | 5 - src/libcore/private/finally.rs | 22 + src/libcore/ptr.rs | 3 - src/libcore/rand.rs | 4 - src/libcore/reflect.rs | 3 - src/libcore/repr.rs | 3 - src/libcore/result.rs | 3 - src/libcore/rt.rs | 3 - src/libcore/run.rs | 3 - src/libcore/stackwalk.rs | 5 - src/libcore/str.rs | 18 +- src/libcore/sys.rs | 4 - src/libcore/task/mod.rs | 5 - src/libcore/task/spawn.rs | 1 - src/libcore/to_bytes.rs | 6 +- src/libcore/to_str.rs | 4 - src/libcore/tuple.rs | 4 - src/libcore/unicode.rs | 3 - src/libcore/util.rs | 4 - src/libcore/vec.rs | 104 +++- src/librustc/front/config.rs | 25 +- src/librustc/front/test.rs | 113 ++-- src/librustc/metadata/decoder.rs | 24 +- src/librustc/metadata/encoder.rs | 10 +- src/librustc/metadata/tydecode.rs | 79 ++- src/librustc/metadata/tyencode.rs | 54 +- src/librustc/middle/borrowck/check_loans.rs | 60 +- src/librustc/middle/check_const.rs | 2 +- src/librustc/middle/check_loop.rs | 4 +- src/librustc/middle/check_match.rs | 14 +- src/librustc/middle/freevars.rs | 6 +- src/librustc/middle/kind.rs | 58 +- src/librustc/middle/lint.rs | 17 +- src/librustc/middle/mem_categorization.rs | 99 ++-- src/librustc/middle/moves.rs | 34 +- src/librustc/middle/region.rs | 12 +- src/librustc/middle/trans/_match.rs | 2 +- src/librustc/middle/trans/base.rs | 32 +- src/librustc/middle/trans/callee.rs | 9 +- src/librustc/middle/trans/closure.rs | 116 ++-- src/librustc/middle/trans/controlflow.rs | 12 +- src/librustc/middle/trans/expr.rs | 71 +-- src/librustc/middle/trans/foreign.rs | 25 +- src/librustc/middle/trans/glue.rs | 15 +- src/librustc/middle/trans/inline.rs | 4 +- src/librustc/middle/trans/machine.rs | 7 +- src/librustc/middle/trans/meth.rs | 6 +- src/librustc/middle/trans/monomorphize.rs | 65 ++- src/librustc/middle/trans/reflect.rs | 93 +-- src/librustc/middle/trans/type_of.rs | 14 +- src/librustc/middle/trans/type_use.rs | 29 +- src/librustc/middle/ty.rs | 538 ++++++------------ src/librustc/middle/typeck/astconv.rs | 146 +++-- src/librustc/middle/typeck/check/method.rs | 8 +- src/librustc/middle/typeck/check/mod.rs | 531 ++++++++--------- src/librustc/middle/typeck/check/regionck.rs | 19 +- .../middle/typeck/check/regionmanip.rs | 17 - src/librustc/middle/typeck/check/vtable.rs | 2 +- src/librustc/middle/typeck/coherence.rs | 6 +- src/librustc/middle/typeck/collect.rs | 186 +++--- src/librustc/middle/typeck/infer/coercion.rs | 43 +- src/librustc/middle/typeck/infer/combine.rs | 78 ++- src/librustc/middle/typeck/infer/glb.rs | 18 +- src/librustc/middle/typeck/infer/lattice.rs | 17 - src/librustc/middle/typeck/infer/lub.rs | 18 +- src/librustc/middle/typeck/infer/mod.rs | 4 - .../middle/typeck/infer/region_inference.rs | 3 - src/librustc/middle/typeck/infer/sub.rs | 18 +- src/librustc/middle/typeck/infer/to_str.rs | 14 +- src/librustc/middle/typeck/mod.rs | 6 +- src/librustc/util/ppaux.rs | 159 +++--- src/librustdoc/astsrv.rs | 5 +- src/librustdoc/attr_parser.rs | 2 +- src/librustdoc/desc_to_brief_pass.rs | 4 +- src/librustdoc/doc.rs | 34 +- src/librustdoc/extract.rs | 2 +- src/librustdoc/fold.rs | 40 +- src/librustdoc/markdown_index_pass.rs | 8 +- src/librustdoc/markdown_pass.rs | 7 +- src/librustdoc/page_pass.rs | 4 +- src/librustdoc/pass.rs | 2 +- src/librustdoc/sectionalize_pass.rs | 4 +- src/librustdoc/sort_pass.rs | 6 +- src/librustdoc/text_pass.rs | 12 +- src/librustdoc/unindent_pass.rs | 2 +- src/libstd/arc.rs | 2 - src/libstd/arena.rs | 2 - src/libstd/base64.rs | 2 - src/libstd/bitv.rs | 2 - src/libstd/c_vec.rs | 1 - src/libstd/cell.rs | 2 - src/libstd/cmp.rs | 1 - src/libstd/comm.rs | 3 - src/libstd/dbg.rs | 1 - src/libstd/deque.rs | 1 - src/libstd/ebml.rs | 2 - src/libstd/fun_treemap.rs | 2 - src/libstd/getopts.rs | 1 - src/libstd/json.rs | 1 - src/libstd/list.rs | 1 - src/libstd/md4.rs | 2 - src/libstd/net_ip.rs | 1 - src/libstd/net_tcp.rs | 1 + src/libstd/net_url.rs | 3 +- src/libstd/oldmap.rs | 1 - src/libstd/par.rs | 51 +- src/libstd/prettyprint.rs | 2 - src/libstd/rl.rs | 4 +- src/libstd/rope.rs | 2 - src/libstd/serialize.rs | 1 - src/libstd/sha1.rs | 2 - src/libstd/smallintmap.rs | 1 - src/libstd/sort.rs | 14 +- src/libstd/std.rc | 4 - src/libstd/sync.rs | 2 - src/libstd/tempfile.rs | 2 - src/libstd/term.rs | 1 - src/libstd/test.rs | 209 ++++--- src/libstd/time.rs | 2 - src/libstd/timer.rs | 2 - src/libstd/treemap.rs | 2 - src/libstd/uv_global_loop.rs | 2 - src/libstd/uv_iotask.rs | 1 - src/libstd/workcache.rs | 2 + src/libsyntax/ast.rs | 82 ++- src/libsyntax/attr.rs | 6 +- src/libsyntax/codemap.rs | 4 +- src/libsyntax/ext/auto_encode.rs | 2 +- src/libsyntax/ext/build.rs | 2 +- src/libsyntax/fold.rs | 15 +- src/libsyntax/parse/classify.rs | 6 +- src/libsyntax/parse/parser.rs | 170 +++--- src/libsyntax/print/pprust.rs | 110 ++-- src/libsyntax/syntax.rc | 1 - src/libsyntax/visit.rs | 15 +- src/test/bench/graph500-bfs.rs | 44 +- src/test/bench/task-perf-alloc-unwind.rs | 9 +- .../bad-var-env-capture-in-block-arg.rs | 17 - ...ock-arg-used-as-lambda-with-illegal-cap.rs | 20 - .../compile-fail/functional-struct-update.rs | 31 - src/test/compile-fail/issue-3044.rs | 7 +- src/test/compile-fail/kindck-owned.rs | 4 +- .../compile-fail/moves-sru-moved-field.rs | 27 + src/test/run-pass/bounded-fn-type.rs | 17 - src/test/run-pass/morestack6.rs | 6 +- src/test/run-pass/newtype.rs | 1 + src/test/run-pass/sendfn-deep-copy.rs | 36 -- src/test/run-pass/test-ignore-cfg.rs | 12 +- 187 files changed, 2053 insertions(+), 2361 deletions(-) delete mode 100644 src/test/compile-fail/bad-var-env-capture-in-block-arg.rs delete mode 100644 src/test/compile-fail/block-arg-used-as-lambda-with-illegal-cap.rs delete mode 100644 src/test/compile-fail/functional-struct-update.rs create mode 100644 src/test/compile-fail/moves-sru-moved-field.rs delete mode 100644 src/test/run-pass/bounded-fn-type.rs delete mode 100644 src/test/run-pass/sendfn-deep-copy.rs diff --git a/src/compiletest/compiletest.rc b/src/compiletest/compiletest.rc index 8f5f9547c520e..b63ac5e75a270 100644 --- a/src/compiletest/compiletest.rc +++ b/src/compiletest/compiletest.rc @@ -159,7 +159,7 @@ pub fn test_opts(config: config) -> test::TestOpts { } } -pub fn make_tests(config: config) -> ~[test::TestDesc] { +pub fn make_tests(config: config) -> ~[test::TestDescAndFn] { debug!("making tests from %s", config.src_base.to_str()); let mut tests = ~[]; @@ -196,13 +196,14 @@ pub fn is_test(config: config, testfile: &Path) -> bool { return valid; } -pub fn make_test(config: config, testfile: &Path) -> - test::TestDesc { - test::TestDesc { - name: make_test_name(config, testfile), +pub fn make_test(config: config, testfile: &Path) -> test::TestDescAndFn { + test::TestDescAndFn { + desc: test::TestDesc { + name: make_test_name(config, testfile), + ignore: header::is_test_ignored(config, testfile), + should_fail: false + }, testfn: make_test_closure(config, testfile), - ignore: header::is_test_ignored(config, testfile), - should_fail: false } } diff --git a/src/libcore/at_vec.rs b/src/libcore/at_vec.rs index be95148e5540c..75db5359e2e31 100644 --- a/src/libcore/at_vec.rs +++ b/src/libcore/at_vec.rs @@ -10,10 +10,6 @@ //! Managed vectors -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use cast::transmute; use kinds::Copy; use iter; diff --git a/src/libcore/bool.rs b/src/libcore/bool.rs index 2f3a53ea504f4..1eebb716a5973 100644 --- a/src/libcore/bool.rs +++ b/src/libcore/bool.rs @@ -9,10 +9,6 @@ // except according to those terms. -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - //! Boolean logic use bool; diff --git a/src/libcore/cast.rs b/src/libcore/cast.rs index 950a753d73f0f..14cc79ceaffed 100644 --- a/src/libcore/cast.rs +++ b/src/libcore/cast.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Unsafe operations -#[forbid(deprecated_mode)] - #[abi = "rust-intrinsic"] extern mod rusti { fn forget(-x: T); diff --git a/src/libcore/char.rs b/src/libcore/char.rs index deecdc98ffa83..f7a369489d1ab 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -10,10 +10,6 @@ //! Utilities for manipulating the char type -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use char; use cmp::Eq; use option::{None, Option, Some}; diff --git a/src/libcore/cleanup.rs b/src/libcore/cleanup.rs index 1967f1771bea9..11a4cad5d1bbb 100644 --- a/src/libcore/cleanup.rs +++ b/src/libcore/cleanup.rs @@ -10,10 +10,6 @@ #[doc(hidden)]; -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use libc::{c_char, c_void, intptr_t, uintptr_t}; use ptr::{mut_null, null, to_unsafe_ptr}; use repr::BoxRepr; diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 038ea2ba6759b..e1ec8c7737c7d 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -20,10 +20,6 @@ and `Eq` to overload the `==` and `!=` operators. */ -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - /** * Trait for values that can be compared for equality * and inequality. diff --git a/src/libcore/container.rs b/src/libcore/container.rs index c8be690a38c8c..2a5ca7d8dfa6c 100644 --- a/src/libcore/container.rs +++ b/src/libcore/container.rs @@ -10,9 +10,6 @@ //! Container traits -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use option::Option; pub trait Container { diff --git a/src/libcore/core.rc b/src/libcore/core.rc index aece60652a21a..64b480818b1e7 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -48,8 +48,6 @@ Implicitly, all crates behave as if they included the following prologue: // Don't link to core. We are core. #[no_core]; -#[warn(deprecated_mode)]; -#[warn(deprecated_pattern)]; #[warn(vecs_implicitly_copyable)]; #[deny(non_camel_case_types)]; #[allow(deprecated_self)]; diff --git a/src/libcore/dlist.rs b/src/libcore/dlist.rs index d4216b283a9b3..ed67e010b4055 100644 --- a/src/libcore/dlist.rs +++ b/src/libcore/dlist.rs @@ -18,10 +18,6 @@ Do not use ==, !=, <, etc on doubly-linked lists -- it may not terminate. */ -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use kinds::Copy; use managed; use option::{None, Option, Some}; diff --git a/src/libcore/dvec.rs b/src/libcore/dvec.rs index 2fd7d71a7fc5d..fe36ed159603c 100644 --- a/src/libcore/dvec.rs +++ b/src/libcore/dvec.rs @@ -19,10 +19,6 @@ Note that recursive use is not permitted. */ -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use cast; use cast::reinterpret_cast; use prelude::*; diff --git a/src/libcore/either.rs b/src/libcore/either.rs index 5e9ccd841957f..7efde62c4ca6b 100644 --- a/src/libcore/either.rs +++ b/src/libcore/either.rs @@ -8,10 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - //! A type that represents one of two alternatives use cmp::Eq; diff --git a/src/libcore/extfmt.rs b/src/libcore/extfmt.rs index 259895da2a514..4d2a1b2afe08d 100644 --- a/src/libcore/extfmt.rs +++ b/src/libcore/extfmt.rs @@ -51,10 +51,6 @@ //! * s - str (any flavor) //! * ? - arbitrary type (does not use the to_str trait) -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - // Transitional #[allow(structural_records)]; // Macros -- needs a snapshot diff --git a/src/libcore/flate.rs b/src/libcore/flate.rs index 39a3aa890df97..6b5c083662b84 100644 --- a/src/libcore/flate.rs +++ b/src/libcore/flate.rs @@ -14,10 +14,6 @@ Simple compression */ -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use libc; use libc::{c_void, size_t, c_int}; use ptr; diff --git a/src/libcore/from_str.rs b/src/libcore/from_str.rs index c3fda7eb8bdd5..9322c7e7cb822 100644 --- a/src/libcore/from_str.rs +++ b/src/libcore/from_str.rs @@ -10,10 +10,6 @@ //! The trait for types that can be created from strings -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use option::Option; pub trait FromStr { diff --git a/src/libcore/gc.rs b/src/libcore/gc.rs index 8150bfbe0ee83..d0c40ccf19aa0 100644 --- a/src/libcore/gc.rs +++ b/src/libcore/gc.rs @@ -35,9 +35,6 @@ with destructors. */ -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; // Transitional #[allow(structural_records)]; diff --git a/src/libcore/hash.rs b/src/libcore/hash.rs index d676570e1e6cb..692cfee536581 100644 --- a/src/libcore/hash.rs +++ b/src/libcore/hash.rs @@ -8,10 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - /*! * Implementation of SipHash 2-4 * diff --git a/src/libcore/hashmap.rs b/src/libcore/hashmap.rs index 88981f514cff3..be785863f71ec 100644 --- a/src/libcore/hashmap.rs +++ b/src/libcore/hashmap.rs @@ -10,10 +10,6 @@ //! Sendable hash maps. -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use container::{Container, Mutable, Map, Set}; use cmp::Eq; use hash::Hash; diff --git a/src/libcore/io.rs b/src/libcore/io.rs index e7d568c54331c..721a6584c6506 100644 --- a/src/libcore/io.rs +++ b/src/libcore/io.rs @@ -14,9 +14,6 @@ Basic input/output */ -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use result::Result; use cmp::Eq; diff --git a/src/libcore/iter-trait.rs b/src/libcore/iter-trait.rs index 942db1c5f2926..df2aa6271d1f8 100644 --- a/src/libcore/iter-trait.rs +++ b/src/libcore/iter-trait.rs @@ -12,9 +12,6 @@ // workaround our lack of traits and lack of macros. See core.{rc,rs} for // how this file is used. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use cmp::{Eq, Ord}; use iter::BaseIter; use iter; diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 2ffa870226179..c414ab0f5f3e5 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -14,9 +14,6 @@ The iteration traits and common implementation */ -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use cmp::{Eq, Ord}; use kinds::Copy; use option::{None, Option, Some}; diff --git a/src/libcore/libc.rs b/src/libcore/libc.rs index a1107d49c0ec1..6976c83a6f407 100644 --- a/src/libcore/libc.rs +++ b/src/libcore/libc.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; /*! * Bindings for libc. * diff --git a/src/libcore/logging.rs b/src/libcore/logging.rs index 922995a5af79c..357a3415ac2da 100644 --- a/src/libcore/logging.rs +++ b/src/libcore/logging.rs @@ -10,10 +10,6 @@ //! Logging -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use cast::transmute; use io; use libc; diff --git a/src/libcore/managed.rs b/src/libcore/managed.rs index 32fc5f527b7cf..700feee983943 100644 --- a/src/libcore/managed.rs +++ b/src/libcore/managed.rs @@ -10,10 +10,6 @@ //! Operations on managed box types -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use cast::transmute; use cmp::{Eq, Ord}; use managed::raw::BoxRepr; diff --git a/src/libcore/mutable.rs b/src/libcore/mutable.rs index 4623a3f45431d..3c44c197f5ef6 100644 --- a/src/libcore/mutable.rs +++ b/src/libcore/mutable.rs @@ -18,8 +18,6 @@ dynamic checks: your program will fail if you attempt to perform mutation when the data structure should be immutable. */ -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; use util::with; use cast::transmute_immut; diff --git a/src/libcore/nil.rs b/src/libcore/nil.rs index f3eb62a3a3ad0..8f03a1b6e3498 100644 --- a/src/libcore/nil.rs +++ b/src/libcore/nil.rs @@ -14,10 +14,6 @@ Functions for the unit type. */ -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use cmp::{Eq, Ord}; #[cfg(notest)] diff --git a/src/libcore/num/cmath.rs b/src/libcore/num/cmath.rs index 6341481809e21..c030dfc589977 100644 --- a/src/libcore/num/cmath.rs +++ b/src/libcore/num/cmath.rs @@ -9,9 +9,6 @@ // except according to those terms. #[doc(hidden)]; // FIXME #3538 -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; use libc::c_int; use libc::c_float; diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index 24ad5c114af28..738445b5cd946 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -8,10 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - //! Operations and constants for `f32` use cmath; diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index 126a48cf28073..f09d874803c3d 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -8,10 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - //! Operations and constants for `f64` use cmath; diff --git a/src/libcore/num/float.rs b/src/libcore/num/float.rs index 32cda029cd182..f5ae05ebffb4e 100644 --- a/src/libcore/num/float.rs +++ b/src/libcore/num/float.rs @@ -8,10 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - //! Operations and constants for `float` // Even though this module exports everything defined in it, diff --git a/src/libcore/num/int-template.rs b/src/libcore/num/int-template.rs index 8b02f3a94c5ff..1856781b1d779 100644 --- a/src/libcore/num/int-template.rs +++ b/src/libcore/num/int-template.rs @@ -8,10 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use T = self::inst::T; use char; diff --git a/src/libcore/num/uint-template.rs b/src/libcore/num/uint-template.rs index 82c6e0170145f..f8bbb35204add 100644 --- a/src/libcore/num/uint-template.rs +++ b/src/libcore/num/uint-template.rs @@ -8,10 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use T = self::inst::T; use T_SIGNED = self::inst::T_SIGNED; diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 36293d6a1c0ce..aaa4ab3fecfee 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -10,9 +10,6 @@ // Core operators -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - #[lang="drop"] pub trait Drop { fn finalize(&self); // FIXME(#4332): Rename to "drop"? --pcwalton diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 9cb955ad352b9..e5d703eec4aef 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -41,9 +41,6 @@ let unwrapped_msg = match move msg { */ -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use cmp::Eq; use kinds::Copy; use option; diff --git a/src/libcore/os.rs b/src/libcore/os.rs index af484454ef466..a14abd23cc3ca 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; #[allow(structural_records)]; /*! diff --git a/src/libcore/owned.rs b/src/libcore/owned.rs index fb14820113e00..d841188501d96 100644 --- a/src/libcore/owned.rs +++ b/src/libcore/owned.rs @@ -10,10 +10,6 @@ //! Operations on unique pointer types -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use cmp::{Eq, Ord}; #[cfg(notest)] diff --git a/src/libcore/path.rs b/src/libcore/path.rs index 0b64df8c1124c..bf1f1c713a994 100644 --- a/src/libcore/path.rs +++ b/src/libcore/path.rs @@ -14,10 +14,6 @@ Cross-platform file path handling */ -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use cmp::Eq; use libc; use option::{None, Option, Some}; diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs index 5f9eed7086871..3f0aecb887d25 100644 --- a/src/libcore/pipes.rs +++ b/src/libcore/pipes.rs @@ -82,11 +82,6 @@ bounded and unbounded protocols allows for less code duplication. */ -// NB: transitionary, de-mode-ing. -// tjc: allowing deprecated modes due to function issue, -// re-forbid after snapshot -#[forbid(deprecated_pattern)]; - // Transitional -- needs snapshot #[allow(structural_records)]; diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index 4e6f209e79e7f..a798d8c866a3f 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -36,7 +36,7 @@ pub use path::PosixPath; pub use path::WindowsPath; pub use pipes::{GenericChan, GenericPort}; pub use ptr::Ptr; -pub use str::{StrSlice, Trimmable}; +pub use str::{StrSlice, Trimmable, OwnedStr}; pub use to_bytes::IterBytes; pub use to_str::ToStr; pub use tuple::{CopyableTuple, ImmutableTuple, ExtendedTupleOps}; diff --git a/src/libcore/private.rs b/src/libcore/private.rs index 40194713365bc..d4cf39ad2625e 100644 --- a/src/libcore/private.rs +++ b/src/libcore/private.rs @@ -8,11 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// NB: transitionary, de-mode-ing. -// tjc: Re-forbid deprecated modes once a snapshot fixes the -// function problem -#[forbid(deprecated_pattern)]; - #[doc(hidden)]; use cast; diff --git a/src/libcore/private/finally.rs b/src/libcore/private/finally.rs index 2c27b8ab3a2ca..50c5ea70cbb40 100644 --- a/src/libcore/private/finally.rs +++ b/src/libcore/private/finally.rs @@ -26,10 +26,19 @@ do || { use ops::Drop; use task::{spawn, failing}; +#[cfg(stage0)] pub trait Finally { fn finally(&self, +dtor: &fn()) -> T; } +#[cfg(stage1)] +#[cfg(stage2)] +#[cfg(stage3)] +pub trait Finally { + fn finally(&self, dtor: &fn()) -> T; +} + +#[cfg(stage0)] impl &fn() -> T: Finally { // FIXME #4518: Should not require a mode here fn finally(&self, +dtor: &fn()) -> T { @@ -41,6 +50,19 @@ impl &fn() -> T: Finally { } } +#[cfg(stage1)] +#[cfg(stage2)] +#[cfg(stage3)] +impl &fn() -> T: Finally { + fn finally(&self, dtor: &fn()) -> T { + let _d = Finallyalizer { + dtor: dtor + }; + + (*self)() + } +} + struct Finallyalizer { dtor: &fn() } diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index fb82c07da04cc..ad0bcb5cff8a2 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -10,9 +10,6 @@ //! Unsafe pointer utility functions -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use cast; use cmp::{Eq, Ord}; use libc; diff --git a/src/libcore/rand.rs b/src/libcore/rand.rs index 50232f99f85ab..452ab9452510b 100644 --- a/src/libcore/rand.rs +++ b/src/libcore/rand.rs @@ -10,10 +10,6 @@ //! Random number generation -// NB: transitional, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use int; use prelude::*; use str; diff --git a/src/libcore/reflect.rs b/src/libcore/reflect.rs index dcbb706767044..de94100d7a506 100644 --- a/src/libcore/reflect.rs +++ b/src/libcore/reflect.rs @@ -14,9 +14,6 @@ Runtime type reflection */ -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use intrinsic::{TyDesc, get_tydesc, visit_tydesc, TyVisitor}; use libc::c_void; use sys; diff --git a/src/libcore/repr.rs b/src/libcore/repr.rs index 1f04f9e77a9d3..a47bad008b872 100644 --- a/src/libcore/repr.rs +++ b/src/libcore/repr.rs @@ -14,9 +14,6 @@ More runtime type reflection */ -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use cast::transmute; use cast; use char; diff --git a/src/libcore/result.rs b/src/libcore/result.rs index d04667698fd27..7f1513173786b 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -12,9 +12,6 @@ // NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use cmp; use cmp::Eq; use either; diff --git a/src/libcore/rt.rs b/src/libcore/rt.rs index f9de0bc91fd5a..33d76cb3c6859 100644 --- a/src/libcore/rt.rs +++ b/src/libcore/rt.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; //! Runtime calls emitted by the compiler. use cast::transmute; diff --git a/src/libcore/run.rs b/src/libcore/run.rs index c10eacc7a0adc..e44bd2aab8172 100644 --- a/src/libcore/run.rs +++ b/src/libcore/run.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; #[allow(structural_records)]; //! Process spawning diff --git a/src/libcore/stackwalk.rs b/src/libcore/stackwalk.rs index 17921a1a1b065..2e24df86c7809 100644 --- a/src/libcore/stackwalk.rs +++ b/src/libcore/stackwalk.rs @@ -11,12 +11,7 @@ #[doc(hidden)]; // FIXME #3538 #[legacy_modes]; // tjc: remove after snapshot - -// NB: transitionary, de-mode-ing. -// FIXME #4425: Can't forbid this because frame_address needs a deprecated -// mode. #[allow(deprecated_mode)]; -#[forbid(deprecated_pattern)]; use cast::reinterpret_cast; use ptr::offset; diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 64695be21d515..9b25f92ede2a4 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -17,9 +17,6 @@ * some heavy-duty uses, try std::rope. */ -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use at_vec; use cast; use char; @@ -2314,6 +2311,21 @@ impl &str: StrSlice { pure fn char_at(i: uint) -> char { char_at(self, i) } } +pub trait OwnedStr { + fn push_str(&mut self, v: &str); + fn push_char(&mut self, c: char); +} + +pub impl ~str : OwnedStr { + fn push_str(&mut self, v: &str) { + push_str(self, v); + } + + fn push_char(&mut self, c: char) { + push_char(self, c); + } +} + #[cfg(test)] mod tests { use char; diff --git a/src/libcore/sys.rs b/src/libcore/sys.rs index 914eccd3d86c0..1571e64511784 100644 --- a/src/libcore/sys.rs +++ b/src/libcore/sys.rs @@ -10,10 +10,6 @@ //! Misc low level stuff -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use cast; use cmp::{Eq, Ord}; use gc; diff --git a/src/libcore/task/mod.rs b/src/libcore/task/mod.rs index d276f0c6ea9e2..9240a67c69a3d 100644 --- a/src/libcore/task/mod.rs +++ b/src/libcore/task/mod.rs @@ -8,11 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// NB: transitionary, de-mode-ing. -// tjc: Deprecated modes allowed because of function arg issue -// in task::spawn. Re-forbid after snapshot. -#[forbid(deprecated_pattern)]; - /*! * Task management. * diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs index c88587067c1eb..22a0c870de649 100644 --- a/src/libcore/task/spawn.rs +++ b/src/libcore/task/spawn.rs @@ -71,7 +71,6 @@ ****************************************************************************/ #[doc(hidden)]; // FIXME #3538 -#[warn(deprecated_mode)]; use cast; use container::Map; diff --git a/src/libcore/to_bytes.rs b/src/libcore/to_bytes.rs index 84e5140d8edbc..b4647d0c621a1 100644 --- a/src/libcore/to_bytes.rs +++ b/src/libcore/to_bytes.rs @@ -14,16 +14,12 @@ The `ToBytes` and `IterBytes` traits */ -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use io; use io::Writer; use option::{None, Option, Some}; use str; -pub type Cb = fn(buf: &[const u8]) -> bool; +pub type Cb = &fn(buf: &[const u8]) -> bool; /** * A trait to implement in order to make a type hashable; diff --git a/src/libcore/to_str.rs b/src/libcore/to_str.rs index 0e46b4fd004b3..d98e341eab8a3 100644 --- a/src/libcore/to_str.rs +++ b/src/libcore/to_str.rs @@ -14,10 +14,6 @@ The `ToStr` trait for converting to strings */ -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use kinds::Copy; use str; use vec; diff --git a/src/libcore/tuple.rs b/src/libcore/tuple.rs index c497a2f3c7f14..484fc1a5a2765 100644 --- a/src/libcore/tuple.rs +++ b/src/libcore/tuple.rs @@ -8,10 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - //! Operations on tuples use cmp::{Eq, Ord}; diff --git a/src/libcore/unicode.rs b/src/libcore/unicode.rs index dedd5d12c5528..ff3b908186a18 100644 --- a/src/libcore/unicode.rs +++ b/src/libcore/unicode.rs @@ -9,9 +9,6 @@ // except according to those terms. #[doc(hidden)]; // FIXME #3538 -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; pub mod general_category { pub pure fn Cc(c: char) -> bool { diff --git a/src/libcore/util.rs b/src/libcore/util.rs index 8dff492e634cc..3b6a134bc52cd 100644 --- a/src/libcore/util.rs +++ b/src/libcore/util.rs @@ -14,10 +14,6 @@ Miscellaneous helpers for common patterns. */ -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - use cmp::Eq; use prelude::*; diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 7846d3d030240..9ad5d9f32da36 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -10,8 +10,6 @@ //! Vectors -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; #[warn(non_camel_case_types)]; use container::{Container, Mutable}; @@ -841,14 +839,37 @@ pub pure fn map2(v0: &[T], v1: &[U], u } -/** - * Apply a function to each element of a vector and return the results - * - * If function `f` returns `none` then that element is excluded from - * the resulting vector. - */ -pub pure fn filter_map(v: &[T], f: fn(t: &T) -> Option) - -> ~[U] { +pub fn filter_map( + v: ~[T], + f: fn(t: T) -> Option) -> ~[U] +{ + /*! + * + * Apply a function to each element of a vector and return the results. + * Consumes the input vector. If function `f` returns `None` then that + * element is excluded from the resulting vector. + */ + + let mut result = ~[]; + do consume(v) |_, elem| { + match f(elem) { + None => {} + Some(result_elem) => { result.push(result_elem); } + } + } + result +} + +pub pure fn filter_mapped( + v: &[T], + f: fn(t: &T) -> Option) -> ~[U] +{ + /*! + * + * Like `filter_map()`, but operates on a borrowed slice + * and does not consume the input. + */ + let mut result = ~[]; for each(v) |elem| { match f(elem) { @@ -1695,7 +1716,7 @@ pub trait ImmutableVector { fn map_r(&self, f: fn(x: &T) -> U) -> ~[U]; pure fn alli(&self, f: fn(uint, t: &T) -> bool) -> bool; pure fn flat_map(&self, f: fn(t: &T) -> ~[U]) -> ~[U]; - pure fn filter_map(&self, f: fn(t: &T) -> Option) -> ~[U]; + pure fn filter_mapped(&self, f: fn(t: &T) -> Option) -> ~[U]; } /// Extension methods for vectors @@ -1758,8 +1779,8 @@ impl &[T]: ImmutableVector { * the resulting vector. */ #[inline] - pure fn filter_map(&self, f: fn(t: &T) -> Option) -> ~[U] { - filter_map(*self, f) + pure fn filter_mapped(&self, f: fn(t: &T) -> Option) -> ~[U] { + filter_mapped(*self, f) } } @@ -2439,10 +2460,14 @@ mod tests { pure fn is_equal(x: &uint, y:&uint) -> bool { return *x == *y; } - fn square_if_odd(n: &uint) -> Option { + fn square_if_odd_r(n: &uint) -> Option { return if *n % 2u == 1u { Some(*n * *n) } else { None }; } + fn square_if_odd_v(n: uint) -> Option { + return if n % 2u == 1u { Some(n * n) } else { None }; + } + fn add(x: uint, y: &uint) -> uint { return x + *y; } #[test] @@ -2775,17 +2800,17 @@ mod tests { } #[test] - fn test_filter_map() { + fn test_filter_mapped() { // Test on-stack filter-map. let mut v = ~[1u, 2u, 3u]; - let mut w = filter_map(v, square_if_odd); + let mut w = filter_mapped(v, square_if_odd_r); assert (len(w) == 2u); assert (w[0] == 1u); assert (w[1] == 9u); // Test on-heap filter-map. v = ~[1u, 2u, 3u, 4u, 5u]; - w = filter_map(v, square_if_odd); + w = filter_mapped(v, square_if_odd_r); assert (len(w) == 3u); assert (w[0] == 1u); assert (w[1] == 9u); @@ -2804,7 +2829,46 @@ mod tests { let all_odd2: ~[int] = ~[]; let mix: ~[int] = ~[9, 2, 6, 7, 1, 0, 0, 3]; let mix_dest: ~[int] = ~[1, 3, 0, 0]; - assert (filter_map(all_even, halve) == map(all_even, halve_for_sure)); + assert (filter_mapped(all_even, halve) == + map(all_even, halve_for_sure)); + assert (filter_mapped(all_odd1, halve) == ~[]); + assert (filter_mapped(all_odd2, halve) == ~[]); + assert (filter_mapped(mix, halve) == mix_dest); + } + + #[test] + fn test_filter_map() { + // Test on-stack filter-map. + let mut v = ~[1u, 2u, 3u]; + let mut w = filter_map(v, square_if_odd_v); + assert (len(w) == 2u); + assert (w[0] == 1u); + assert (w[1] == 9u); + + // Test on-heap filter-map. + v = ~[1u, 2u, 3u, 4u, 5u]; + w = filter_map(v, square_if_odd_v); + assert (len(w) == 3u); + assert (w[0] == 1u); + assert (w[1] == 9u); + assert (w[2] == 25u); + + fn halve(i: int) -> Option { + if i % 2 == 0 { + return option::Some::(i / 2); + } else { + return option::None::; + } + } + fn halve_for_sure(i: &int) -> int { return *i / 2; } + let all_even: ~[int] = ~[0, 2, 8, 6]; + let all_even0: ~[int] = copy all_even; + let all_odd1: ~[int] = ~[1, 7, 3]; + let all_odd2: ~[int] = ~[]; + let mix: ~[int] = ~[9, 2, 6, 7, 1, 0, 0, 3]; + let mix_dest: ~[int] = ~[1, 3, 0, 0]; + assert (filter_map(all_even, halve) == + map(all_even0, halve_for_sure)); assert (filter_map(all_odd1, halve) == ~[]); assert (filter_map(all_odd2, halve) == ~[]); assert (filter_map(mix, halve) == mix_dest); @@ -3664,10 +3728,10 @@ mod tests { #[ignore(windows)] #[should_fail] #[allow(non_implicitly_copyable_typarams)] - fn test_filter_map_fail() { + fn test_filter_mapped_fail() { let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; let mut i = 0; - do filter_map(v) |_elt| { + do filter_mapped(v) |_elt| { if i == 2 { die!() } diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs index a7c071919ffdb..cf75db3a90014 100644 --- a/src/librustc/front/config.rs +++ b/src/librustc/front/config.rs @@ -64,12 +64,13 @@ fn filter_view_item(cx: ctxt, &&view_item: @ast::view_item } fn fold_mod(cx: ctxt, m: ast::_mod, fld: fold::ast_fold) -> ast::_mod { - let filtered_items = vec::filter_map(m.items, |a| filter_item(cx, *a)); - let filtered_view_items = vec::filter_map(m.view_items, - |a| filter_view_item(cx, *a)); + let filtered_items = + m.items.filter_mapped(|a| filter_item(cx, *a)); + let filtered_view_items = + m.view_items.filter_mapped(|a| filter_view_item(cx, *a)); ast::_mod { view_items: filtered_view_items.map(|x| fld.fold_view_item(*x)), - items: filtered_items.filter_map(|x| fld.fold_item(*x)), + items: vec::filter_map(filtered_items, |x| fld.fold_item(x)) } } @@ -85,10 +86,10 @@ fn fold_foreign_mod( nm: ast::foreign_mod, fld: fold::ast_fold ) -> ast::foreign_mod { - let filtered_items = vec::filter_map(nm.items, - |a| filter_foreign_item(cx, *a)); - let filtered_view_items = vec::filter_map(nm.view_items, - |a| filter_view_item(cx, *a)); + let filtered_items = + nm.items.filter_mapped(|a| filter_foreign_item(cx, *a)); + let filtered_view_items = + nm.view_items.filter_mapped(|a| filter_view_item(cx, *a)); ast::foreign_mod { sort: nm.sort, abi: nm.abi, @@ -136,7 +137,8 @@ fn fold_block( b: ast::blk_, fld: fold::ast_fold ) -> ast::blk_ { - let filtered_stmts = vec::filter_map(b.stmts, |a| filter_stmt(cx, *a)); + let filtered_stmts = + b.stmts.filter_mapped(|a| filter_stmt(cx, *a)); ast::blk_ { view_items: /*bad*/copy b.view_items, stmts: vec::map(filtered_stmts, |x| fld.fold_stmt(*x)), @@ -183,8 +185,9 @@ pub fn metas_in_cfg(cfg: ast::crate_cfg, // Pull the inner meta_items from the #[cfg(meta_item, ...)] attributes, // so we can match against them. This is the list of configurations for // which the item is valid - let cfg_metas = vec::concat(vec::filter_map(cfg_metas, - |i| attr::get_meta_item_list(*i))); + let cfg_metas = + vec::concat( + vec::filter_map(cfg_metas, |i| attr::get_meta_item_list(i))); let has_cfg_metas = vec::len(cfg_metas) > 0u; if !has_cfg_metas { return true; } diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs index 91eb8148bb786..9fa1cea3e103f 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -168,9 +168,11 @@ fn is_test_fn(i: @ast::item) -> bool { fn is_ignored(cx: test_ctxt, i: @ast::item) -> bool { let ignoreattrs = attr::find_attrs_by_name(i.attrs, "ignore"); let ignoreitems = attr::attr_metas(ignoreattrs); - let cfg_metas = vec::concat(vec::filter_map(ignoreitems, - |i| attr::get_meta_item_list(*i))); return if !ignoreitems.is_empty() { + let cfg_metas = + vec::concat( + vec::filter_map(ignoreitems, + |i| attr::get_meta_item_list(i))); config::metas_in_cfg(/*bad*/copy cx.crate.node.config, cfg_metas) } else { false @@ -277,7 +279,7 @@ fn mk_std(cx: test_ctxt) -> @ast::view_item { } fn mk_tests(cx: test_ctxt) -> @ast::item { - let ret_ty = mk_test_desc_vec_ty(cx); + let ret_ty = mk_test_desc_and_fn_vec_ty(cx); let decl = ast::fn_decl { inputs: ~[], @@ -286,7 +288,7 @@ fn mk_tests(cx: test_ctxt) -> @ast::item { }; // The vector of test_descs for this crate - let test_descs = mk_test_desc_vec(cx); + let test_descs = mk_test_desc_and_fn_vec(cx); let body_: ast::blk_ = default_block(~[], option::Some(test_descs), cx.sess.next_node_id()); @@ -327,19 +329,21 @@ fn mk_path(cx: test_ctxt, +path: ~[ast::ident]) -> @ast::path { } } -// The ast::Ty of ~[std::test::test_desc] -fn mk_test_desc_vec_ty(cx: test_ctxt) -> @ast::Ty { - let test_desc_ty_path = +// The ast::Ty of ~[std::test::TestDescAndFn] +fn mk_test_desc_and_fn_vec_ty(cx: test_ctxt) -> @ast::Ty { + let test_desc_and_fn_ty_path = mk_path(cx, ~[cx.sess.ident_of(~"test"), - cx.sess.ident_of(~"TestDesc")]); + cx.sess.ident_of(~"TestDescAndFn")]); - let test_desc_ty = ast::Ty { + let test_desc_and_fn_ty = ast::Ty { id: cx.sess.next_node_id(), - node: ast::ty_path(test_desc_ty_path, cx.sess.next_node_id()), + node: ast::ty_path(test_desc_and_fn_ty_path, + cx.sess.next_node_id()), span: dummy_sp(), }; - let vec_mt = ast::mt {ty: @test_desc_ty, mutbl: ast::m_imm}; + let vec_mt = ast::mt {ty: @test_desc_and_fn_ty, + mutbl: ast::m_imm}; let inner_ty = @ast::Ty { id: cx.sess.next_node_id(), @@ -354,11 +358,11 @@ fn mk_test_desc_vec_ty(cx: test_ctxt) -> @ast::Ty { } } -fn mk_test_desc_vec(cx: test_ctxt) -> @ast::expr { +fn mk_test_desc_and_fn_vec(cx: test_ctxt) -> @ast::expr { debug!("building test vector from %u tests", cx.testfns.len()); let mut descs = ~[]; for cx.testfns.each |test| { - descs.push(mk_test_desc_rec(cx, *test)); + descs.push(mk_test_desc_and_fn_rec(cx, *test)); } let inner_expr = @ast::expr { @@ -376,7 +380,7 @@ fn mk_test_desc_vec(cx: test_ctxt) -> @ast::expr { } } -fn mk_test_desc_rec(cx: test_ctxt, test: test) -> @ast::expr { +fn mk_test_desc_and_fn_rec(cx: test_ctxt, test: test) -> @ast::expr { let span = test.span; let path = /*bad*/copy test.path; @@ -407,23 +411,6 @@ fn mk_test_desc_rec(cx: test_ctxt, test: test) -> @ast::expr { expr: @name_expr, }); - let fn_path = path_node_global(path); - - let fn_expr = ast::expr { - id: cx.sess.next_node_id(), - callee_id: cx.sess.next_node_id(), - node: ast::expr_path(fn_path), - span: span, - }; - - let fn_wrapper_expr = mk_test_wrapper(cx, fn_expr, span); - - let fn_field = nospan(ast::field_ { - mutbl: ast::m_imm, - ident: cx.sess.ident_of(~"testfn"), - expr: fn_wrapper_expr, - }); - let ignore_lit: ast::lit = nospan(ast::lit_bool(test.ignore)); let ignore_expr = ast::expr { @@ -460,62 +447,52 @@ fn mk_test_desc_rec(cx: test_ctxt, test: test) -> @ast::expr { let desc_rec_ = ast::expr_struct( test_desc_path, - ~[name_field, fn_field, ignore_field, fail_field], + ~[name_field, ignore_field, fail_field], option::None ); - let desc_rec = ast::expr { + let desc_rec = @ast::expr { id: cx.sess.next_node_id(), callee_id: cx.sess.next_node_id(), node: desc_rec_, span: span, }; - return @desc_rec; -} + let desc_field = nospan(ast::field_ { + mutbl: ast::m_imm, + ident: cx.sess.ident_of(~"desc"), + expr: desc_rec + }); -// Produces a bare function that wraps the test function + let fn_path = path_node_global(path); -// FIXME (#1281): This can go away once fn is the type of bare function. -fn mk_test_wrapper(cx: test_ctxt, - +fn_path_expr: ast::expr, - span: span) -> @ast::expr { - let call_expr = ast::expr { + let fn_expr = @ast::expr { id: cx.sess.next_node_id(), callee_id: cx.sess.next_node_id(), - node: ast::expr_call(@fn_path_expr, ~[], false), + node: ast::expr_path(fn_path), span: span, }; - let call_stmt: ast::stmt = nospan( - ast::stmt_semi(@call_expr, cx.sess.next_node_id())); - - let wrapper_decl = ast::fn_decl { - inputs: ~[], - output: @ast::Ty { - id: cx.sess.next_node_id(), - node: ast::ty_nil, - span: span, - }, - cf: ast::return_val - }; - - let wrapper_body = nospan(ast::blk_ { - view_items: ~[], - stmts: ~[@call_stmt], - expr: option::None, - id: cx.sess.next_node_id(), - rules: ast::default_blk + let fn_field = nospan(ast::field_ { + mutbl: ast::m_imm, + ident: cx.sess.ident_of(~"testfn"), + expr: fn_expr, }); - let wrapper_expr = ast::expr { + let test_desc_and_fn_path = + mk_path(cx, ~[cx.sess.ident_of(~"test"), + cx.sess.ident_of(~"TestDescAndFn")]); + + let desc_and_fn_rec = @ast::expr { id: cx.sess.next_node_id(), callee_id: cx.sess.next_node_id(), - node: ast::expr_fn(ast::ProtoBare, wrapper_decl, wrapper_body, @()), - span: span + node: ast::expr_struct(test_desc_and_fn_path, + ~[fn_field, desc_field], + option::None), + span: span, }; - return @wrapper_expr; + return desc_and_fn_rec; } fn mk_main(cx: test_ctxt) -> @ast::item { @@ -567,7 +544,7 @@ fn mk_test_main_call(cx: test_ctxt) -> @ast::expr { let args_call_expr = ast::expr { id: cx.sess.next_node_id(), callee_id: cx.sess.next_node_id(), - node: ast::expr_call(@args_path_expr, ~[], false), + node: ast::expr_call(@args_path_expr, ~[], ast::NoSugar), span: dummy_sp(), }; @@ -584,7 +561,7 @@ fn mk_test_main_call(cx: test_ctxt) -> @ast::expr { let test_call_expr = ast::expr { id: cx.sess.next_node_id(), callee_id: cx.sess.next_node_id(), - node: ast::expr_call(@test_path_expr, ~[], false), + node: ast::expr_call(@test_path_expr, ~[], ast::NoSugar), span: dummy_sp(), }; @@ -606,7 +583,7 @@ fn mk_test_main_call(cx: test_ctxt) -> @ast::expr { node: ast::expr_call( @test_main_path_expr, ~[@args_call_expr, @test_call_expr], - false + ast::NoSugar ), span: dummy_sp(), }; diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 9a6a2f7e95415..67498ad5aafe6 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -586,10 +586,8 @@ pub fn get_enum_variants(intr: @ident_interner, cdata: cmd, id: ast::node_id, item, tcx, cdata); let name = item_name(intr, item); let arg_tys = match ty::get(ctor_ty).sty { - ty::ty_fn(ref f) => (*f).sig.inputs.map(|a| a.ty), - - // Nullary enum variant. - _ => ~[], + ty::ty_bare_fn(ref f) => f.sig.inputs.map(|a| a.ty), + _ => ~[], // Nullary enum variant. }; match variant_disr_val(item) { Some(val) => { disr_val = val; } @@ -705,11 +703,12 @@ pub fn get_trait_methods(intr: @ident_interner, cdata: cmd, id: ast::node_id, let ty = doc_type(mth, tcx, cdata); let def_id = item_def_id(mth, cdata); let fty = match ty::get(ty).sty { - ty::ty_fn(ref f) => (/*bad*/copy *f), - _ => { - tcx.diag.handler().bug( - ~"get_trait_methods: id has non-function type"); - } }; + ty::ty_bare_fn(ref f) => copy *f, + _ => { + tcx.diag.handler().bug( + ~"get_trait_methods: id has non-function type"); + } + }; let self_ty = get_self_ty(mth); result.push({ident: name, tps: bounds, fty: fty, self_ty: self_ty, vis: ast::public, def_id: def_id}); @@ -734,14 +733,13 @@ pub fn get_provided_trait_methods(intr: @ident_interner, cdata: cmd, let name = item_name(intr, mth); let ty = doc_type(mth, tcx, cdata); - let fty; - match ty::get(ty).sty { - ty::ty_fn(ref f) => fty = (/*bad*/copy *f), + let fty = match ty::get(ty).sty { + ty::ty_bare_fn(ref f) => copy *f, _ => { tcx.diag.handler().bug(~"get_provided_trait_methods(): id \ has non-function type"); } - } + }; let self_ty = get_self_ty(mth); let ty_method = {ident: name, tps: bounds, fty: fty, self_ty: self_ty, diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 072b974d0422a..b0a424447b35e 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -768,8 +768,9 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder, encode_name(ecx, ebml_w, mty.ident); encode_type_param_bounds(ebml_w, ecx, (*ty_m).tps); - encode_type(ecx, ebml_w, ty::mk_fn(tcx, /*bad*/copy mty.fty)); - encode_family(ebml_w, purity_fn_family(mty.fty.meta.purity)); + encode_type(ecx, ebml_w, + ty::mk_bare_fn(tcx, copy mty.fty)); + encode_family(ebml_w, purity_fn_family(mty.fty.purity)); encode_self_type(ebml_w, mty.self_ty); encode_method_sort(ebml_w, 'r'); ebml_w.end_tag(); @@ -781,8 +782,9 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder, encode_def_id(ebml_w, local_def(m.id)); encode_name(ecx, ebml_w, mty.ident); encode_type_param_bounds(ebml_w, ecx, m.tps); - encode_type(ecx, ebml_w, ty::mk_fn(tcx, /*bad*/copy mty.fty)); - encode_family(ebml_w, purity_fn_family(mty.fty.meta.purity)); + encode_type(ecx, ebml_w, + ty::mk_bare_fn(tcx, copy mty.fty)); + encode_family(ebml_w, purity_fn_family(mty.fty.purity)); encode_self_type(ebml_w, mty.self_ty); encode_method_sort(ebml_w, 'p'); ebml_w.end_tag(); diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index ea13325ad4947..3f989339e275e 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -17,8 +17,6 @@ use core::prelude::*; use middle::ty; -use middle::ty::{FnTyBase, FnMeta, FnSig, arg, creader_cache_key, field}; -use middle::ty::{substs}; use core::io; use core::str; @@ -124,17 +122,12 @@ fn parse_path(st: @pstate) -> @ast::path { }; } -fn parse_ty_rust_fn(st: @pstate, conv: conv_did) -> ty::t { - return ty::mk_fn(st.tcx, parse_ty_fn(st, conv)); -} - -fn parse_proto(st: @pstate) -> ast::Proto { +fn parse_sigil(st: @pstate) -> ast::Sigil { match next(st) { - '_' => ast::ProtoBare, - '@' => ast::ProtoBox, - '~' => ast::ProtoUniq, - '&' => ast::ProtoBorrowed, - _ => die!(~"parse_proto(): bad input") + '@' => ast::ManagedSigil, + '~' => ast::OwnedSigil, + '&' => ast::BorrowedSigil, + c => st.tcx.sess.bug(fmt!("parse_sigil(): bad input '%c'", c)) } } @@ -152,7 +145,7 @@ fn parse_vstore(st: @pstate) -> ty::vstore { '~' => ty::vstore_uniq, '@' => ty::vstore_box, '&' => ty::vstore_slice(parse_region(st)), - _ => die!(~"parse_vstore: bad input") + c => st.tcx.sess.bug(fmt!("parse_vstore(): bad input '%c'", c)) } } @@ -166,7 +159,7 @@ fn parse_substs(st: @pstate, conv: conv_did) -> ty::substs { while peek(st) != ']' { params.push(parse_ty(st, conv)); } st.pos = st.pos + 1u; - return substs { + return ty::substs { self_r: self_r, self_ty: self_ty, tps: params @@ -316,19 +309,24 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t { return ty::mk_tup(st.tcx, params); } 'f' => { - parse_ty_rust_fn(st, conv) + return ty::mk_closure(st.tcx, parse_closure_ty(st, conv)); + } + 'F' => { + return ty::mk_bare_fn(st.tcx, parse_bare_fn_ty(st, conv)); } 'Y' => return ty::mk_type(st.tcx), 'C' => { - let proto = parse_proto(st); - return ty::mk_opaque_closure_ptr(st.tcx, proto); + let sigil = parse_sigil(st); + return ty::mk_opaque_closure_ptr(st.tcx, sigil); } '#' => { let pos = parse_hex(st); assert (next(st) == ':'); let len = parse_hex(st); assert (next(st) == '#'); - let key = creader_cache_key { cnum: st.crate, pos: pos, len: len }; + let key = ty::creader_cache_key {cnum: st.crate, + pos: pos, + len: len }; match st.tcx.rcache.find(&key) { Some(tt) => return tt, None => { @@ -408,6 +406,13 @@ fn parse_purity(c: char) -> purity { } } +fn parse_abi(c: char) -> Abi { + match c { + 'r' => ast::RustAbi, + _ => die!(fmt!("parse_abi: bad ABI '%c'", c)) + } +} + fn parse_onceness(c: char) -> ast::Onceness { match c { 'o' => ast::Once, @@ -430,12 +435,33 @@ fn parse_mode(st: @pstate) -> ast::mode { return m; } -fn parse_ty_fn(st: @pstate, conv: conv_did) -> ty::FnTy { - let proto = parse_proto(st); +fn parse_closure_ty(st: @pstate, conv: conv_did) -> ty::ClosureTy { + let sigil = parse_sigil(st); let purity = parse_purity(next(st)); let onceness = parse_onceness(next(st)); let region = parse_region(st); - let bounds = parse_bounds(st, conv); + let sig = parse_sig(st, conv); + ty::ClosureTy { + purity: purity, + sigil: sigil, + onceness: onceness, + region: region, + sig: sig + } +} + +fn parse_bare_fn_ty(st: @pstate, conv: conv_did) -> ty::BareFnTy { + let purity = parse_purity(next(st)); + let abi = parse_abi(next(st)); + let sig = parse_sig(st, conv); + ty::BareFnTy { + purity: purity, + abi: abi, + sig: sig + } +} + +fn parse_sig(st: @pstate, conv: conv_did) -> ty::FnSig { assert (next(st) == '['); let mut inputs: ~[ty::arg] = ~[]; while peek(st) != ']' { @@ -444,18 +470,9 @@ fn parse_ty_fn(st: @pstate, conv: conv_did) -> ty::FnTy { } st.pos += 1u; // eat the ']' let ret_ty = parse_ty(st, conv); - return FnTyBase { - meta: FnMeta {purity: purity, - proto: proto, - onceness: onceness, - bounds: bounds, - region: region}, - sig: FnSig {inputs: inputs, - output: ret_ty} - }; + ty::FnSig {inputs: inputs, output: ret_ty} } - // Rust metadata parsing pub fn parse_def_id(buf: &[u8]) -> ast::def_id { let mut colon_idx = 0u; diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 0d66862c79fe2..a87ce02d5a30a 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -288,8 +288,13 @@ fn enc_sty(w: io::Writer, cx: @ctxt, +st: ty::sty) { } w.write_char(']'); } - ty::ty_fn(ref f) => { - enc_ty_fn(w, cx, (*f)); + ty::ty_closure(ref f) => { + w.write_char('f'); + enc_closure_ty(w, cx, f); + } + ty::ty_bare_fn(ref f) => { + w.write_char('F'); + enc_bare_fn_ty(w, cx, f); } ty::ty_infer(_) => { cx.diag.handler().bug(~"Cannot encode inference variable types"); @@ -306,7 +311,7 @@ fn enc_sty(w: io::Writer, cx: @ctxt, +st: ty::sty) { ty::ty_type => w.write_char('Y'), ty::ty_opaque_closure_ptr(p) => { w.write_str(&"C&"); - enc_proto(w, p); + enc_sigil(w, p); } ty::ty_opaque_box => w.write_char('B'), ty::ty_struct(def, ref substs) => { @@ -325,13 +330,11 @@ fn enc_sty(w: io::Writer, cx: @ctxt, +st: ty::sty) { } } -fn enc_proto(w: io::Writer, proto: Proto) { - w.write_str(&"f"); - match proto { - ProtoBare => w.write_str(&"_"), - ProtoBox => w.write_str(&"@"), - ProtoUniq => w.write_str(&"~"), - ProtoBorrowed => w.write_str(&"&"), +fn enc_sigil(w: io::Writer, sigil: Sigil) { + match sigil { + ManagedSigil => w.write_str("@"), + OwnedSigil => w.write_str("~"), + BorrowedSigil => w.write_str("&"), } } @@ -357,6 +360,12 @@ fn enc_purity(w: io::Writer, p: purity) { } } +fn enc_abi(w: io::Writer, a: Abi) { + match a { + RustAbi => w.write_char('r'), + } +} + fn enc_onceness(w: io::Writer, o: Onceness) { match o { Once => w.write_char('o'), @@ -364,18 +373,27 @@ fn enc_onceness(w: io::Writer, o: Onceness) { } } -fn enc_ty_fn(w: io::Writer, cx: @ctxt, ft: ty::FnTy) { - enc_proto(w, ft.meta.proto); - enc_purity(w, ft.meta.purity); - enc_onceness(w, ft.meta.onceness); - enc_region(w, cx, ft.meta.region); - enc_bounds(w, cx, ft.meta.bounds); +fn enc_bare_fn_ty(w: io::Writer, cx: @ctxt, ft: &ty::BareFnTy) { + enc_purity(w, ft.purity); + enc_abi(w, ft.abi); + enc_fn_sig(w, cx, &ft.sig); +} + +fn enc_closure_ty(w: io::Writer, cx: @ctxt, ft: &ty::ClosureTy) { + enc_sigil(w, ft.sigil); + enc_purity(w, ft.purity); + enc_onceness(w, ft.onceness); + enc_region(w, cx, ft.region); + enc_fn_sig(w, cx, &ft.sig); +} + +fn enc_fn_sig(w: io::Writer, cx: @ctxt, fsig: &ty::FnSig) { w.write_char('['); - for ft.sig.inputs.each |arg| { + for fsig.inputs.each |arg| { enc_arg(w, cx, *arg); } w.write_char(']'); - enc_ty(w, cx, ft.sig.output); + enc_ty(w, cx, fsig.output); } pub fn enc_bounds(w: io::Writer, cx: @ctxt, bs: @~[ty::param_bound]) { diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index 9b2d51289adb1..dfc26000116a6 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -221,18 +221,19 @@ impl check_loan_ctxt { let callee_ty = ty::node_id_to_type(tcx, callee_id); match ty::get(callee_ty).sty { - ty::ty_fn(ref fn_ty) => { - match fn_ty.meta.purity { - ast::pure_fn => return, // case (c) above - ast::impure_fn | ast::unsafe_fn | ast::extern_fn => { - self.report_purity_error( - pc, callee_span, - fmt!("access to %s function", - fn_ty.meta.purity.to_str())); - } + ty::ty_bare_fn(ty::BareFnTy {purity: purity, _}) | + ty::ty_closure(ty::ClosureTy {purity: purity, _}) => { + match purity { + ast::pure_fn => return, // case (c) above + ast::impure_fn | ast::unsafe_fn | ast::extern_fn => { + self.report_purity_error( + pc, callee_span, + fmt!("access to %s function", + purity.to_str())); + } + } } - } - _ => return, // case (d) above + _ => return, // case (d) above } } @@ -240,8 +241,11 @@ impl check_loan_ctxt { // The expression must be an expr_fn(*) or expr_fn_block(*) fn is_stack_closure(id: ast::node_id) -> bool { let fn_ty = ty::node_id_to_type(self.tcx(), id); - let proto = ty::ty_fn_proto(fn_ty); - return proto == ast::ProtoBorrowed; + match ty::get(fn_ty).sty { + ty::ty_closure(ty::ClosureTy {sigil: ast::BorrowedSigil, + _}) => true, + _ => false + } } fn is_allowed_pure_arg(expr: @ast::expr) -> bool { @@ -564,17 +568,27 @@ fn check_loans_in_fn(fk: visit::fn_kind, decl: ast::fn_decl, body: ast::blk, { let is_stack_closure = self.is_stack_closure(id); let fty = ty::node_id_to_type(self.tcx(), id); - let fty_proto = ty::ty_fn_proto(fty); - check_moves_from_captured_variables(self, id, fty_proto); + let declared_purity; + match fk { + visit::fk_item_fn(*) | visit::fk_method(*) | + visit::fk_dtor(*) => { + declared_purity = ty::ty_fn_purity(fty); + } + + visit::fk_anon(*) | visit::fk_fn_block(*) => { + let fty_sigil = ty::ty_closure_sigil(fty); + check_moves_from_captured_variables(self, id, fty_sigil); + declared_purity = ty::determine_inherited_purity( + copy self.declared_purity, ty::ty_fn_purity(fty), + fty_sigil); + } + } debug!("purity on entry=%?", copy self.declared_purity); do save_and_restore(&mut(self.declared_purity)) { do save_and_restore(&mut(self.fn_args)) { - self.declared_purity = ty::determine_inherited_purity( - copy self.declared_purity, - ty::ty_fn_purity(fty), - fty_proto); + self.declared_purity = declared_purity; match fk { visit::fk_anon(*) | @@ -608,10 +622,10 @@ fn check_loans_in_fn(fk: visit::fn_kind, decl: ast::fn_decl, body: ast::blk, fn check_moves_from_captured_variables(&&self: check_loan_ctxt, id: ast::node_id, - fty_proto: ast::Proto) + fty_sigil: ast::Sigil) { - match fty_proto { - ast::ProtoBox | ast::ProtoUniq => { + match fty_sigil { + ast::ManagedSigil | ast::OwnedSigil => { let cap_vars = self.bccx.capture_map.get(&id); for cap_vars.each |cap_var| { match cap_var.mode { @@ -646,7 +660,7 @@ fn check_loans_in_fn(fk: visit::fn_kind, decl: ast::fn_decl, body: ast::blk, } } - ast::ProtoBorrowed | ast::ProtoBare => {} + ast::BorrowedSigil => {} } } } diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 69ace0d779738..ad46d3b6f4de0 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -150,7 +150,7 @@ pub fn check_expr(sess: Session, } } } - expr_call(callee, _, false) => { + expr_call(callee, _, NoSugar) => { match def_map.find(&callee.id) { Some(def_struct(*)) => {} // OK. Some(def_variant(*)) => {} // OK. diff --git a/src/librustc/middle/check_loop.rs b/src/librustc/middle/check_loop.rs index 11c557f02496c..38450de6b540c 100644 --- a/src/librustc/middle/check_loop.rs +++ b/src/librustc/middle/check_loop.rs @@ -39,8 +39,8 @@ pub fn check_crate(tcx: ty::ctxt, crate: @crate) { (v.visit_block)((*b), {in_loop: false, can_ret: false}, v); } expr_loop_body(@expr {node: expr_fn_block(_, ref b), _}) => { - let proto = ty::ty_fn_proto(ty::expr_ty(tcx, e)); - let blk = (proto == ProtoBorrowed); + let sigil = ty::ty_closure_sigil(ty::expr_ty(tcx, e)); + let blk = (sigil == BorrowedSigil); (v.visit_block)((*b), {in_loop: true, can_ret: blk}, v); } expr_break(_) => { diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 978aaacb18a91..6f9fe1edca5be 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -100,7 +100,7 @@ pub fn check_expr(cx: @MatchCheckCtxt, ex: @expr, &&s: (), v: visit::vt<()>) { } _ => { /* We assume only enum types can be uninhabited */ } } - let arms = vec::concat(vec::filter_map((*arms), unguarded_pat)); + let arms = vec::concat(arms.filter_mapped(unguarded_pat)); check_exhaustive(cx, ex.span, arms); } _ => () @@ -255,7 +255,8 @@ pub fn is_useful(cx: @MatchCheckCtxt, +m: matrix, +v: &[@pat]) -> useful { } } Some(ref ctor) => { - match is_useful(cx, vec::filter_map(m, |r| default(cx, copy *r)), + match is_useful(cx, + vec::filter_map(m, |r| default(cx, r)), vec::tail(v)) { useful_ => useful(left_ty, (/*bad*/copy *ctor)), ref u => (/*bad*/copy *u) @@ -277,8 +278,7 @@ pub fn is_useful_specialized(cx: @MatchCheckCtxt, arity: uint, lty: ty::t) -> useful { - let ms = vec::filter_map(m, |r| specialize(cx, *r, - ctor, arity, lty)); + let ms = m.filter_mapped(|r| specialize(cx, *r, ctor, arity, lty)); let could_be_useful = is_useful( cx, ms, specialize(cx, v, ctor, arity, lty).get()); match could_be_useful { @@ -387,9 +387,9 @@ pub fn missing_ctor(cx: @MatchCheckCtxt, ty::ty_unboxed_vec(*) | ty::ty_evec(*) => { // Find the lengths and tails of all vector patterns. - let vec_pat_lens = do m.filter_map |r| { - match /*bad*/copy r[0].node { - pat_vec(elems, tail) => { + let vec_pat_lens = do m.filter_mapped |r| { + match r[0].node { + pat_vec(ref elems, ref tail) => { Some((elems.len(), tail.is_some())) } _ => None diff --git a/src/librustc/middle/freevars.rs b/src/librustc/middle/freevars.rs index 5d65aba2a4d34..e609107721048 100644 --- a/src/librustc/middle/freevars.rs +++ b/src/librustc/middle/freevars.rs @@ -48,10 +48,8 @@ fn collect_freevars(def_map: resolve::DefMap, blk: ast::blk) let walk_expr = fn@(expr: @ast::expr, &&depth: int, v: visit::vt) { match expr.node { - ast::expr_fn(proto, _, _, _) => { - if proto != ast::ProtoBare { - visit::visit_expr(expr, depth + 1, v); - } + ast::expr_fn(_, _, _, _) => { + visit::visit_expr(expr, depth + 1, v); } ast::expr_fn_block(*) => { visit::visit_expr(expr, depth + 1, v); diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index 8abafe6b07961..35d5595fefd43 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -150,11 +150,23 @@ fn with_appropriate_checker(cx: ctx, id: node_id, b: fn(check_fn)) { } let fty = ty::node_id_to_type(cx.tcx, id); - match ty::ty_fn_proto(fty) { - ProtoUniq => b(check_for_uniq), - ProtoBox => b(check_for_box), - ProtoBare => b(check_for_bare), - ProtoBorrowed => b(check_for_block), + match ty::get(fty).sty { + ty::ty_closure(ty::ClosureTy {sigil: OwnedSigil, _}) => { + b(check_for_uniq) + } + ty::ty_closure(ty::ClosureTy {sigil: ManagedSigil, _}) => { + b(check_for_box) + } + ty::ty_closure(ty::ClosureTy {sigil: BorrowedSigil, _}) => { + b(check_for_block) + } + ty::ty_bare_fn(_) => { + b(check_for_bare) + } + ref s => { + cx.tcx.sess.bug( + fmt!("expect fn type in kind checker, not %?", s)); + } } } @@ -240,42 +252,6 @@ pub fn check_expr(e: @expr, cx: ctx, v: visit::vt) { expr.span, "explicit copy requires a copyable argument"); } - expr_rec(ref fields, def) | expr_struct(_, ref fields, def) => { - match def { - Some(ex) => { - // All noncopyable fields must be overridden - let t = ty::expr_ty(cx.tcx, ex); - let ty_fields = match ty::get(t).sty { - ty::ty_rec(ref f) => { - copy *f - } - ty::ty_struct(did, ref substs) => { - ty::struct_fields(cx.tcx, did, substs) - } - _ => { - cx.tcx.sess.span_bug( - ex.span, - ~"bad base expr type in record") - } - }; - for ty_fields.each |tf| { - // If this field would not be copied, ok. - if fields.any(|f| f.node.ident == tf.ident) { loop; } - - // If this field is copyable, ok. - let kind = ty::type_kind(cx.tcx, tf.mt.ty); - if ty::kind_can_be_copied(kind) { loop; } - - cx.tcx.sess.span_err( - e.span, - fmt!("cannot copy field `%s` of base expression, \ - which has a noncopyable type", - *cx.tcx.sess.intr().get(tf.ident))); - } - } - _ => {} - } - } expr_repeat(element, count_expr, _) => { let count = ty::eval_repeat_count(cx.tcx, count_expr, e.span); if count > 1 { diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 4601941f73a27..51bbdfdc19cc3 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -897,9 +897,10 @@ fn check_fn(tcx: ty::ctxt, fk: visit::fn_kind, decl: ast::fn_decl, fn check_fn_deprecated_modes(tcx: ty::ctxt, fn_ty: ty::t, decl: ast::fn_decl, span: span, id: ast::node_id) { match ty::get(fn_ty).sty { - ty::ty_fn(ref fn_ty) => { + ty::ty_closure(ty::ClosureTy {sig: ref sig, _}) | + ty::ty_bare_fn(ty::BareFnTy {sig: ref sig, _}) => { let mut counter = 0; - for vec::each2(fn_ty.sig.inputs, decl.inputs) |arg_ty, arg_ast| { + for vec::each2(sig.inputs, decl.inputs) |arg_ty, arg_ast| { counter += 1; debug!("arg %d, ty=%s, mode=%s", counter, @@ -938,13 +939,14 @@ fn check_fn_deprecated_modes(tcx: ty::ctxt, fn_ty: ty::t, decl: ast::fn_decl, } match ty::get(arg_ty.ty).sty { - ty::ty_fn(*) => { + ty::ty_closure(*) | ty::ty_bare_fn(*) => { let span = arg_ast.ty.span; // Recurse to check fn-type argument match arg_ast.ty.node { - ast::ty_fn(f) => { + ast::ty_closure(@ast::TyClosure{decl: ref d, _}) | + ast::ty_bare_fn(@ast::TyBareFn{decl: ref d, _})=>{ check_fn_deprecated_modes(tcx, arg_ty.ty, - f.decl, span, id); + *d, span, id); } ast::ty_path(*) => { // This is probably a typedef, so we can't @@ -976,10 +978,11 @@ fn check_item_deprecated_modes(tcx: ty::ctxt, it: @ast::item) { match it.node { ast::item_ty(ty, _) => { match ty.node { - ast::ty_fn(f) => { + ast::ty_closure(@ast::TyClosure {decl: ref decl, _}) | + ast::ty_bare_fn(@ast::TyBareFn {decl: ref decl, _}) => { let fn_ty = ty::node_id_to_type(tcx, it.id); check_fn_deprecated_modes( - tcx, fn_ty, f.decl, ty.span, it.id) + tcx, fn_ty, *decl, ty.span, it.id) } _ => () } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index abe8a64fea513..07de99870964f 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -146,63 +146,55 @@ pub enum deref_kind {deref_ptr(ptr_kind), deref_comp(comp_kind)} // pointer adjustment). pub fn opt_deref_kind(t: ty::t) -> Option { match ty::get(t).sty { - ty::ty_uniq(*) | - ty::ty_evec(_, ty::vstore_uniq) | - ty::ty_estr(ty::vstore_uniq) => { - Some(deref_ptr(uniq_ptr)) - } - - ty::ty_fn(ref f) if (*f).meta.proto == ast::ProtoUniq => { - Some(deref_ptr(uniq_ptr)) - } - - ty::ty_rptr(r, mt) | - ty::ty_evec(mt, ty::vstore_slice(r)) => { - Some(deref_ptr(region_ptr(mt.mutbl, r))) - } - - ty::ty_estr(ty::vstore_slice(r)) => { - Some(deref_ptr(region_ptr(ast::m_imm, r))) - } + ty::ty_uniq(*) | + ty::ty_evec(_, ty::vstore_uniq) | + ty::ty_estr(ty::vstore_uniq) | + ty::ty_closure(ty::ClosureTy {sigil: ast::OwnedSigil, _}) => { + Some(deref_ptr(uniq_ptr)) + } - ty::ty_fn(ref f) if (*f).meta.proto == ast::ProtoBorrowed => { - Some(deref_ptr(region_ptr(ast::m_imm, (*f).meta.region))) - } + ty::ty_rptr(r, mt) | + ty::ty_evec(mt, ty::vstore_slice(r)) => { + Some(deref_ptr(region_ptr(mt.mutbl, r))) + } - ty::ty_box(mt) | - ty::ty_evec(mt, ty::vstore_box) => { - Some(deref_ptr(gc_ptr(mt.mutbl))) - } + ty::ty_estr(ty::vstore_slice(r)) | + ty::ty_closure(ty::ClosureTy {sigil: ast::BorrowedSigil, + region: r, _}) => { + Some(deref_ptr(region_ptr(ast::m_imm, r))) + } - ty::ty_estr(ty::vstore_box) => { - Some(deref_ptr(gc_ptr(ast::m_imm))) - } + ty::ty_box(mt) | + ty::ty_evec(mt, ty::vstore_box) => { + Some(deref_ptr(gc_ptr(mt.mutbl))) + } - ty::ty_fn(ref f) if (*f).meta.proto == ast::ProtoBox => { - Some(deref_ptr(gc_ptr(ast::m_imm))) - } + ty::ty_estr(ty::vstore_box) | + ty::ty_closure(ty::ClosureTy {sigil: ast::ManagedSigil, _}) => { + Some(deref_ptr(gc_ptr(ast::m_imm))) + } - ty::ty_ptr(*) => { - Some(deref_ptr(unsafe_ptr)) - } + ty::ty_ptr(*) => { + Some(deref_ptr(unsafe_ptr)) + } - ty::ty_enum(did, _) => { - Some(deref_comp(comp_variant(did))) - } + ty::ty_enum(did, _) => { + Some(deref_comp(comp_variant(did))) + } - ty::ty_struct(_, _) => { - Some(deref_comp(comp_anon_field)) - } + ty::ty_struct(_, _) => { + Some(deref_comp(comp_anon_field)) + } - ty::ty_evec(mt, ty::vstore_fixed(_)) => { - Some(deref_comp(comp_index(t, mt.mutbl))) - } + ty::ty_evec(mt, ty::vstore_fixed(_)) => { + Some(deref_comp(comp_index(t, mt.mutbl))) + } - ty::ty_estr(ty::vstore_fixed(_)) => { - Some(deref_comp(comp_index(t, m_imm))) - } + ty::ty_estr(ty::vstore_fixed(_)) => { + Some(deref_comp(comp_index(t, m_imm))) + } - _ => None + _ => None } } @@ -473,9 +465,9 @@ pub impl &mem_categorization_ctxt { ast::def_upvar(_, inner, fn_node_id, _) => { let ty = ty::node_id_to_type(self.tcx, fn_node_id); - let proto = ty::ty_fn_proto(ty); - match proto { - ast::ProtoBorrowed => { + let sigil = ty::ty_closure_sigil(ty); + match sigil { + ast::BorrowedSigil => { let upcmt = self.cat_def(id, span, expr_ty, *inner); @cmt_ { id:id, @@ -486,7 +478,7 @@ pub impl &mem_categorization_ctxt { ty:upcmt.ty } } - ast::ProtoUniq | ast::ProtoBox => { + ast::OwnedSigil | ast::ManagedSigil => { // FIXME #2152 allow mutation of moved upvars @cmt_ { id:id, @@ -497,11 +489,6 @@ pub impl &mem_categorization_ctxt { ty:expr_ty } } - ast::ProtoBare => { - self.tcx.sess.span_bug( - span, - fmt!("Upvar in a bare closure?")); - } } } diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs index f7943d6edc09c..aaa3156e27c25 100644 --- a/src/librustc/middle/moves.rs +++ b/src/librustc/middle/moves.rs @@ -474,7 +474,35 @@ impl VisitContext { } for opt_with.each |with_expr| { - self.consume_expr(*with_expr, visitor); + // If there are any fields whose type is move-by-default, + // then `with` is consumed, otherwise it is only read + let with_ty = ty::expr_ty(self.tcx, *with_expr); + let with_fields = match ty::get(with_ty).sty { + ty::ty_rec(ref f) => copy *f, + ty::ty_struct(did, ref substs) => { + ty::struct_fields(self.tcx, did, substs) + } + ref r => { + self.tcx.sess.span_bug( + with_expr.span, + fmt!("bad base expr type in record: %?", r)) + } + }; + + // The `with` expr must be consumed if it contains + // any fields which (1) were not explicitly + // specified and (2) have a type that + // moves-by-default: + let consume_with = with_fields.any(|tf| { + !fields.any(|f| f.node.ident == tf.ident) && + ty::type_implicitly_moves(self.tcx, tf.mt.ty) + }); + + if consume_with { + self.consume_expr(*with_expr, visitor); + } else { + self.use_expr(*with_expr, Read, visitor); + } } } @@ -786,9 +814,9 @@ impl VisitContext { let _indenter = indenter(); let fn_ty = ty::node_id_to_type(self.tcx, fn_expr_id); - let proto = ty::ty_fn_proto(fn_ty); + let sigil = ty::ty_closure_sigil(fn_ty); let freevars = freevars::get_freevars(self.tcx, fn_expr_id); - if proto == ProtoBorrowed { + if sigil == BorrowedSigil { // &fn() captures everything by ref at_vec::from_fn(freevars.len(), |i| { let fvar = &freevars[i]; diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 867cc7c686fb8..68e41b329e366 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -657,7 +657,7 @@ pub fn determine_rp_in_ty(ty: @ast::Ty, } } - ast::ty_fn(f) => { + ast::ty_closure(ref f) => { debug!("referenced fn type: %s", pprust::ty_to_str(ty, cx.sess.intr())); match f.region { @@ -668,7 +668,7 @@ pub fn determine_rp_in_ty(ty: @ast::Ty, } } None => { - if f.proto == ast::ProtoBorrowed && cx.anon_implies_rp { + if f.sigil == ast::BorrowedSigil && cx.anon_implies_rp { cx.add_rp(cx.item_id, cx.add_variance(rv_contravariant)); } @@ -732,18 +732,18 @@ pub fn determine_rp_in_ty(ty: @ast::Ty, } } - ast::ty_fn(f) => { + ast::ty_closure(@ast::TyClosure {decl: ref decl, _}) | + ast::ty_bare_fn(@ast::TyBareFn {decl: ref decl, _}) => { // fn() binds the & region, so do not consider &T types that // appear *inside* a fn() type to affect the enclosing item: do cx.with(cx.item_id, false) { // parameters are contravariant do cx.with_ambient_variance(rv_contravariant) { - for f.decl.inputs.each |a| { + for decl.inputs.each |a| { (visitor.visit_ty)(a.ty, cx, visitor); } } - visit::visit_ty_param_bounds(f.bounds, cx, visitor); - (visitor.visit_ty)(f.decl.output, cx, visitor); + (visitor.visit_ty)(decl.output, cx, visitor); } } diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 99b5641ac6adc..ebd6d9f905642 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -1652,7 +1652,7 @@ pub fn trans_match_inner(scope_cx: block, // insert bindings into the lllocals map and add cleanups bcx = insert_lllocals(bcx, *arm_data, true); - bcx = controlflow::trans_block(bcx, arm_data.arm.body, dest); + bcx = controlflow::trans_block(bcx, &arm_data.arm.body, dest); bcx = trans_block_cleanups(bcx, block_cleanups(arm_data.bodycx)); arm_cxs.push(bcx); } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index a1f863332bddd..588e2916e47e3 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -613,7 +613,7 @@ pub fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t, let ccx = cx.ccx(); let mut cx = cx; match ty::get(fn_ty).sty { - ty::ty_fn(ref fn_ty) => { + ty::ty_bare_fn(ref fn_ty) => { let mut j = 0u; let v_id = variant.id; for vec::each(fn_ty.sig.inputs) |a| { @@ -777,10 +777,10 @@ pub fn trans_external_path(ccx: @crate_ctxt, did: ast::def_id, t: ty::t) -> ValueRef { let name = csearch::get_symbol(ccx.sess.cstore, did).to_managed(); // Sad match ty::get(t).sty { - ty::ty_fn(_) => { + ty::ty_bare_fn(_) | ty::ty_closure(_) => { let llty = type_of_fn_from_ty(ccx, t); return get_extern_fn(ccx.externs, ccx.llmod, name, - lib::llvm::CCallConv, llty); + lib::llvm::CCallConv, llty); } _ => { let llty = type_of(ccx, t); @@ -1363,7 +1363,7 @@ pub fn with_scope_datumblock(bcx: block, opt_node_info: Option, DatumBlock {bcx: leave_block(bcx, scope_cx), datum: datum} } -pub fn block_locals(b: ast::blk, it: fn(@ast::local)) { +pub fn block_locals(b: &ast::blk, it: fn(@ast::local)) { for vec::each(b.node.stmts) |s| { match s.node { ast::stmt_decl(d, _) => { @@ -1727,8 +1727,8 @@ pub enum self_arg { impl_self(ty::t), impl_owned_self(ty::t), no_self, } // returned. pub fn trans_closure(ccx: @crate_ctxt, +path: path, - decl: ast::fn_decl, - body: ast::blk, + decl: &ast::fn_decl, + body: &ast::blk, llfndecl: ValueRef, ty_self: self_arg, +param_substs: Option, @@ -1791,8 +1791,8 @@ pub fn trans_closure(ccx: @crate_ctxt, // function. pub fn trans_fn(ccx: @crate_ctxt, +path: path, - decl: ast::fn_decl, - body: ast::blk, + decl: &ast::fn_decl, + body: &ast::blk, llfndecl: ValueRef, ty_self: self_arg, +param_substs: Option, @@ -1935,7 +1935,7 @@ pub fn trans_tuple_struct(ccx: @crate_ctxt, pub fn trans_struct_dtor(ccx: @crate_ctxt, +path: path, - body: ast::blk, + body: &ast::blk, dtor_id: ast::node_id, +psubsts: Option, hash_id: Option, @@ -1966,8 +1966,9 @@ pub fn trans_struct_dtor(ccx: @crate_ctxt, ccx.monomorphized.insert(*h_id, lldecl); } /* Translate the dtor body */ - trans_fn(ccx, path, ast_util::dtor_dec(), - body, lldecl, impl_self(class_ty), psubsts, dtor_id, None); + let decl = ast_util::dtor_dec(); + trans_fn(ccx, path, &decl, body, lldecl, + impl_self(class_ty), psubsts, dtor_id, None); lldecl } @@ -2013,20 +2014,19 @@ pub fn trans_item(ccx: @crate_ctxt, item: ast::item) { _ => die!(~"trans_item"), }; match /*bad*/copy item.node { - // XXX: Bad copies. - ast::item_fn(copy decl, purity, copy tps, ref body) => { + ast::item_fn(ref decl, purity, ref tps, ref body) => { if purity == ast::extern_fn { let llfndecl = get_item_val(ccx, item.id); foreign::trans_foreign_fn(ccx, vec::append( /*bad*/copy *path, ~[path_name(item.ident)]), - decl, (*body), llfndecl, item.id); + decl, body, llfndecl, item.id); } else if tps.is_empty() { let llfndecl = get_item_val(ccx, item.id); trans_fn(ccx, vec::append(/*bad*/copy *path, ~[path_name(item.ident)]), - decl, (*body), llfndecl, no_self, None, item.id, None); + decl, body, llfndecl, no_self, None, item.id, None); } else { for vec::each((*body).node.stmts) |stmt| { match stmt.node { @@ -2078,7 +2078,7 @@ pub fn trans_struct_def(ccx: @crate_ctxt, struct_def: @ast::struct_def, id: ast::node_id) { // Translate the destructor. do option::iter(&struct_def.dtor) |dtor| { - trans_struct_dtor(ccx, /*bad*/copy *path, dtor.node.body, + trans_struct_dtor(ccx, /*bad*/copy *path, &dtor.node.body, dtor.node.id, None, None, local_def(id)); }; diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 4bd5ae969f206..4af74b3623f5a 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -627,18 +627,17 @@ pub fn trans_arg_expr(bcx: block, Some(_) => { match arg_expr.node { ast::expr_loop_body( - // XXX: Bad copy. - blk@@ast::expr { - node: ast::expr_fn_block(copy decl, ref body), + blk @ @ast::expr { + node: ast::expr_fn_block(ref decl, ref body), _ }) => { let scratch_ty = expr_ty(bcx, arg_expr); let scratch = alloc_ty(bcx, scratch_ty); let arg_ty = expr_ty(bcx, arg_expr); - let proto = ty::ty_fn_proto(arg_ty); + let sigil = ty::ty_closure_sigil(arg_ty); let bcx = closure::trans_expr_fn( - bcx, proto, decl, /*bad*/copy *body, arg_expr.id, + bcx, sigil, decl, body, arg_expr.id, blk.id, Some(ret_flag), expr::SaveIn(scratch)); DatumBlock {bcx: bcx, datum: Datum {val: scratch, diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index 62e00100d6cc1..c70425da9fa39 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -160,7 +160,7 @@ pub fn mk_closure_tys(tcx: ty::ctxt, return cdata_ty; } -pub fn allocate_cbox(bcx: block, proto: ast::Proto, cdata_ty: ty::t) +pub fn allocate_cbox(bcx: block, sigil: ast::Sigil, cdata_ty: ty::t) -> Result { let _icx = bcx.insn_ctxt("closure::allocate_cbox"); let ccx = bcx.ccx(), tcx = ccx.tcx; @@ -176,23 +176,19 @@ pub fn allocate_cbox(bcx: block, proto: ast::Proto, cdata_ty: ty::t) } // Allocate and initialize the box: - match proto { - ast::ProtoBox => { + match sigil { + ast::ManagedSigil => { malloc_raw(bcx, cdata_ty, heap_shared) } - ast::ProtoUniq => { + ast::OwnedSigil => { malloc_raw(bcx, cdata_ty, heap_exchange) } - ast::ProtoBorrowed => { + ast::BorrowedSigil => { let cbox_ty = tuplify_box_ty(tcx, cdata_ty); let llbox = base::alloc_ty(bcx, cbox_ty); nuke_ref_count(bcx, llbox); rslt(bcx, llbox) } - ast::ProtoBare => { - let cdata_llty = type_of(bcx.ccx(), cdata_ty); - rslt(bcx, C_null(cdata_llty)) - } } } @@ -208,7 +204,7 @@ pub type closure_result = { // Otherwise, it is stack allocated and copies pointers to the upvars. pub fn store_environment(bcx: block, bound_values: ~[EnvValue], - proto: ast::Proto) -> closure_result { + sigil: ast::Sigil) -> closure_result { let _icx = bcx.insn_ctxt("closure::store_environment"); let ccx = bcx.ccx(), tcx = ccx.tcx; @@ -217,7 +213,7 @@ pub fn store_environment(bcx: block, let cdata_ty = mk_closure_tys(tcx, copy bound_values); // allocate closure in the heap - let Result {bcx: bcx, val: llbox} = allocate_cbox(bcx, proto, cdata_ty); + let Result {bcx: bcx, val: llbox} = allocate_cbox(bcx, sigil, cdata_ty); let mut temp_cleanups = ~[]; // cbox_ty has the form of a tuple: (a, b, c) we want a ptr to a @@ -265,7 +261,7 @@ pub fn store_environment(bcx: block, // collects the upvars and packages them up for store_environment. pub fn build_closure(bcx0: block, cap_vars: &[moves::CaptureVar], - proto: ast::Proto, + sigil: ast::Sigil, include_ret_handle: Option) -> closure_result { let _icx = bcx0.insn_ctxt("closure::build_closure"); // If we need to, package up the iterator body to call @@ -279,7 +275,7 @@ pub fn build_closure(bcx0: block, let datum = expr::trans_local_var(bcx, cap_var.def); match cap_var.mode { moves::CapRef => { - assert proto == ast::ProtoBorrowed; + assert sigil == ast::BorrowedSigil; env_vals.push(EnvValue {action: EnvRef, datum: datum}); } @@ -316,7 +312,7 @@ pub fn build_closure(bcx0: block, datum: ret_datum}); } - return store_environment(bcx, env_vals, proto); + return store_environment(bcx, env_vals, sigil); } // Given an enclosing block context, a new function context, a closure type, @@ -326,7 +322,7 @@ pub fn load_environment(fcx: fn_ctxt, cdata_ty: ty::t, cap_vars: &[moves::CaptureVar], load_ret_handle: bool, - proto: ast::Proto) { + sigil: ast::Sigil) { let _icx = fcx.insn_ctxt("closure::load_environment"); let llloadenv = match fcx.llloadenv { @@ -352,9 +348,9 @@ pub fn load_environment(fcx: fn_ctxt, let mut i = 0u; for cap_vars.each |cap_var| { let mut upvarptr = GEPi(bcx, llcdata, [0u, i]); - match proto { - ast::ProtoBorrowed => { upvarptr = Load(bcx, upvarptr); } - ast::ProtoBox | ast::ProtoUniq | ast::ProtoBare => {} + match sigil { + ast::BorrowedSigil => { upvarptr = Load(bcx, upvarptr); } + ast::ManagedSigil | ast::OwnedSigil => {} } let def_id = ast_util::def_id_of_def(cap_var.def); fcx.llupvars.insert(def_id.node, upvarptr); @@ -369,9 +365,9 @@ pub fn load_environment(fcx: fn_ctxt, } pub fn trans_expr_fn(bcx: block, - proto: ast::Proto, - +decl: ast::fn_decl, - +body: ast::blk, + sigil: ast::Sigil, + decl: &ast::fn_decl, + body: &ast::blk, outer_id: ast::node_id, user_id: ast::node_id, is_loop_body: Option>, @@ -381,7 +377,7 @@ pub fn trans_expr_fn(bcx: block, * * Translates the body of a closure expression. * - * - `proto` + * - `sigil` * - `decl` * - `body` * - `outer_id`: The id of the closure expression with the correct @@ -417,18 +413,18 @@ pub fn trans_expr_fn(bcx: block, ~"expr_fn"); let llfn = decl_internal_cdecl_fn(ccx.llmod, s, llfnty); - let Result {bcx: bcx, val: closure} = match proto { - ast::ProtoBorrowed | ast::ProtoBox | ast::ProtoUniq => { + let Result {bcx: bcx, val: closure} = match sigil { + ast::BorrowedSigil | ast::ManagedSigil | ast::OwnedSigil => { let cap_vars = ccx.maps.capture_map.get(&user_id); let ret_handle = match is_loop_body {Some(x) => x, None => None}; - let {llbox, cdata_ty, bcx} = build_closure(bcx, cap_vars, proto, + let {llbox, cdata_ty, bcx} = build_closure(bcx, cap_vars, sigil, ret_handle); trans_closure(ccx, sub_path, decl, body, llfn, no_self, /*bad*/ copy bcx.fcx.param_substs, user_id, None, |fcx| load_environment(fcx, cdata_ty, cap_vars, - ret_handle.is_some(), proto), + ret_handle.is_some(), sigil), |bcx| { if is_loop_body.is_some() { Store(bcx, C_bool(true), bcx.fcx.llretptr); @@ -436,34 +432,30 @@ pub fn trans_expr_fn(bcx: block, }); rslt(bcx, llbox) } - ast::ProtoBare => { - trans_closure(ccx, sub_path, decl, body, llfn, no_self, None, - user_id, None, |_fcx| { }, |_bcx| { }); - rslt(bcx, C_null(T_opaque_box_ptr(ccx))) - } }; fill_fn_pair(bcx, dest_addr, llfn, closure); return bcx; } -pub fn make_fn_glue(cx: block, - v: ValueRef, - t: ty::t, - glue_fn: fn@(block, v: ValueRef, t: ty::t) -> block) - -> block { - let _icx = cx.insn_ctxt("closure::make_fn_glue"); +pub fn make_closure_glue( + cx: block, + v: ValueRef, + t: ty::t, + glue_fn: fn@(block, v: ValueRef, t: ty::t) -> block) -> block +{ + let _icx = cx.insn_ctxt("closure::make_closure_glue"); let bcx = cx; let tcx = cx.tcx(); - let proto = ty::ty_fn_proto(t); - match proto { - ast::ProtoBare | ast::ProtoBorrowed => bcx, - ast::ProtoUniq | ast::ProtoBox => { + let sigil = ty::ty_closure_sigil(t); + match sigil { + ast::BorrowedSigil => bcx, + ast::OwnedSigil | ast::ManagedSigil => { let box_cell_v = GEPi(cx, v, [0u, abi::fn_field_box]); let box_ptr_v = Load(cx, box_cell_v); do with_cond(cx, IsNotNull(cx, box_ptr_v)) |bcx| { - let closure_ty = ty::mk_opaque_closure_ptr(tcx, proto); + let closure_ty = ty::mk_opaque_closure_ptr(tcx, sigil); glue_fn(bcx, box_cell_v, closure_ty) } } @@ -472,20 +464,20 @@ pub fn make_fn_glue(cx: block, pub fn make_opaque_cbox_take_glue( bcx: block, - proto: ast::Proto, + sigil: ast::Sigil, cboxptr: ValueRef) // ptr to ptr to the opaque closure -> block { // Easy cases: let _icx = bcx.insn_ctxt("closure::make_opaque_cbox_take_glue"); - match proto { - ast::ProtoBare | ast::ProtoBorrowed => { + match sigil { + ast::BorrowedSigil => { return bcx; } - ast::ProtoBox => { + ast::ManagedSigil => { glue::incr_refcnt_of_boxed(bcx, Load(bcx, cboxptr)); return bcx; } - ast::ProtoUniq => { + ast::OwnedSigil => { /* hard case: fallthrough to code below */ } } @@ -531,36 +523,36 @@ pub fn make_opaque_cbox_take_glue( pub fn make_opaque_cbox_drop_glue( bcx: block, - proto: ast::Proto, + sigil: ast::Sigil, cboxptr: ValueRef) // ptr to the opaque closure -> block { let _icx = bcx.insn_ctxt("closure::make_opaque_cbox_drop_glue"); - match proto { - ast::ProtoBare | ast::ProtoBorrowed => bcx, - ast::ProtoBox => { + match sigil { + ast::BorrowedSigil => bcx, + ast::ManagedSigil => { glue::decr_refcnt_maybe_free( bcx, Load(bcx, cboxptr), - ty::mk_opaque_closure_ptr(bcx.tcx(), proto)) + ty::mk_opaque_closure_ptr(bcx.tcx(), sigil)) } - ast::ProtoUniq => { + ast::OwnedSigil => { glue::free_ty( bcx, cboxptr, - ty::mk_opaque_closure_ptr(bcx.tcx(), proto)) + ty::mk_opaque_closure_ptr(bcx.tcx(), sigil)) } } } pub fn make_opaque_cbox_free_glue( bcx: block, - proto: ast::Proto, + sigil: ast::Sigil, cbox: ValueRef) // ptr to ptr to the opaque closure -> block { let _icx = bcx.insn_ctxt("closure::make_opaque_cbox_free_glue"); - match proto { - ast::ProtoBare | ast::ProtoBorrowed => { + match sigil { + ast::BorrowedSigil => { return bcx; } - ast::ProtoBox | ast::ProtoUniq => { + ast::ManagedSigil | ast::OwnedSigil => { /* hard cases: fallthrough to code below */ } } @@ -580,10 +572,10 @@ pub fn make_opaque_cbox_free_glue( abi::tydesc_field_drop_glue, None); // Free the ty descr (if necc) and the box itself - match proto { - ast::ProtoBox => glue::trans_free(bcx, cbox), - ast::ProtoUniq => glue::trans_unique_free(bcx, cbox), - ast::ProtoBare | ast::ProtoBorrowed => { + match sigil { + ast::ManagedSigil => glue::trans_free(bcx, cbox), + ast::OwnedSigil => glue::trans_unique_free(bcx, cbox), + ast::BorrowedSigil => { bcx.sess().bug(~"impossible") } } diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs index a1505dd2f11c3..0933eedd5e4bb 100644 --- a/src/librustc/middle/trans/controlflow.rs +++ b/src/librustc/middle/trans/controlflow.rs @@ -23,7 +23,7 @@ pub fn macros() { include!("macros.rs"); } -pub fn trans_block(bcx: block, b: ast::blk, dest: expr::Dest) -> block { +pub fn trans_block(bcx: block, b: &ast::blk, dest: expr::Dest) -> block { let _icx = bcx.insn_ctxt("trans_block"); let mut bcx = bcx; do block_locals(b) |local| { @@ -47,7 +47,7 @@ pub fn trans_block(bcx: block, b: ast::blk, dest: expr::Dest) -> block { pub fn trans_if(bcx: block, cond: @ast::expr, - thn: ast::blk, + thn: &ast::blk, els: Option<@ast::expr>, dest: expr::Dest) -> block { @@ -82,10 +82,10 @@ pub fn trans_if(bcx: block, match elexpr.node { ast::expr_if(_, _, _) => { let elseif_blk = ast_util::block_from_expr(elexpr); - trans_block(else_bcx_in, elseif_blk, dest) + trans_block(else_bcx_in, &elseif_blk, dest) } ast::expr_block(ref blk) => { - trans_block(else_bcx_in, (*blk), dest) + trans_block(else_bcx_in, blk, dest) } // would be nice to have a constraint on ifs _ => bcx.tcx().sess.bug(~"strange alternative in if") @@ -114,7 +114,7 @@ pub fn join_blocks(parent_bcx: block, in_cxs: ~[block]) -> block { return out; } -pub fn trans_while(bcx: block, cond: @ast::expr, body: ast::blk) -> block { +pub fn trans_while(bcx: block, cond: @ast::expr, body: &ast::blk) -> block { let _icx = bcx.insn_ctxt("trans_while"); let next_bcx = sub_block(bcx, ~"while next"); @@ -154,7 +154,7 @@ pub fn trans_while(bcx: block, cond: @ast::expr, body: ast::blk) -> block { } pub fn trans_loop(bcx:block, - body: ast::blk, + body: &ast::blk, opt_label: Option) -> block { let _icx = bcx.insn_ctxt("trans_loop"); diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 56833d373c5cd..f2da47eb0ecca 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -475,10 +475,10 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block { return controlflow::trans_check_expr(bcx, expr, a, ~"Assertion"); } ast::expr_while(cond, ref body) => { - return controlflow::trans_while(bcx, cond, (*body)); + return controlflow::trans_while(bcx, cond, body); } ast::expr_loop(ref body, opt_label) => { - return controlflow::trans_loop(bcx, (*body), opt_label); + return controlflow::trans_loop(bcx, body, opt_label); } ast::expr_assign(dst, src) => { let src_datum = unpack_datum!( @@ -530,7 +530,7 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr, bcx.def(expr.id), dest); } ast::expr_if(cond, ref thn, els) => { - return controlflow::trans_if(bcx, cond, *thn, els, dest); + return controlflow::trans_if(bcx, cond, thn, els, dest); } ast::expr_match(discr, ref arms) => { return _match::trans_match(bcx, expr, discr, /*bad*/copy *arms, @@ -539,7 +539,7 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr, ast::expr_block(ref blk) => { return do base::with_scope(bcx, blk.info(), ~"block-expr body") |bcx| { - controlflow::trans_block(bcx, (*blk), dest) + controlflow::trans_block(bcx, blk, dest) }; } ast::expr_rec(ref fields, base) | @@ -562,58 +562,31 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr, ast::expr_vec(*) | ast::expr_repeat(*) => { return tvec::trans_fixed_vstore(bcx, expr, expr, dest); } - // XXX: Bad copy. - ast::expr_fn(proto, copy decl, ref body, _) => { - // Don't use this function for anything real. Use the one in - // astconv instead. - return closure::trans_expr_fn(bcx, proto, decl, - /*bad*/copy *body, - expr.id, expr.id, - None, dest); - } + ast::expr_fn(_, ref decl, ref body, _) | ast::expr_fn_block(ref decl, ref body) => { let expr_ty = expr_ty(bcx, expr); - match ty::get(expr_ty).sty { - ty::ty_fn(ref fn_ty) => { - debug!("translating fn_block %s with type %s", - expr_to_str(expr, tcx.sess.intr()), - ty_to_str(tcx, expr_ty)); - return closure::trans_expr_fn( - bcx, fn_ty.meta.proto, /*bad*/copy *decl, - /*bad*/copy *body, expr.id, expr.id, - None, dest); - } - _ => { - bcx.sess().impossible_case( - expr.span, "fn_block has body with a non-fn type"); - } - } + let sigil = ty::ty_closure_sigil(expr_ty); + debug!("translating fn_block %s with type %s", + expr_to_str(expr, tcx.sess.intr()), + ty_to_str(tcx, expr_ty)); + return closure::trans_expr_fn(bcx, sigil, decl, body, + expr.id, expr.id, + None, dest); } ast::expr_loop_body(blk) => { - match ty::get(expr_ty(bcx, expr)).sty { - ty::ty_fn(ref fn_ty) => { - match blk.node { - ast::expr_fn_block(copy decl, ref body) => { - return closure::trans_expr_fn( - bcx, - fn_ty.meta.proto, - decl, - /*bad*/copy *body, - expr.id, - blk.id, - Some(None), - dest); - } - _ => { - bcx.sess().impossible_case( - expr.span, - "loop_body has the wrong kind of contents") - } - } + let expr_ty = expr_ty(bcx, expr); + let sigil = ty::ty_closure_sigil(expr_ty); + match blk.node { + ast::expr_fn_block(ref decl, ref body) => { + return closure::trans_expr_fn(bcx, sigil, + decl, body, + expr.id, blk.id, + Some(None), dest); } _ => { bcx.sess().impossible_case( - expr.span, "loop_body has body with a non-fn type") + expr.span, + "loop_body has the wrong kind of contents") } } } diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index ae05ceb1ec570..bb14fce805354 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -31,7 +31,7 @@ use middle::trans::machine; use middle::trans::shape; use middle::trans::type_of::*; use middle::trans::type_of; -use middle::ty::{FnTyBase, FnMeta, FnSig, arg}; +use middle::ty::{FnSig, arg}; use util::ppaux::ty_to_str; use core::libc::c_uint; @@ -66,10 +66,8 @@ type c_stack_tys = { fn c_arg_and_ret_lltys(ccx: @crate_ctxt, id: ast::node_id) -> (~[TypeRef], TypeRef, ty::t) { match ty::get(ty::node_id_to_type(ccx.tcx, id)).sty { - ty::ty_fn(ref fn_ty) => { - let llargtys = type_of_explicit_args( - ccx, - fn_ty.sig.inputs); + ty::ty_bare_fn(ref fn_ty) => { + let llargtys = type_of_explicit_args(ccx, fn_ty.sig.inputs); let llretty = type_of::type_of(ccx, fn_ty.sig.output); (llargtys, llretty, fn_ty.sig.output) } @@ -541,12 +539,11 @@ pub fn trans_intrinsic(ccx: @crate_ctxt, let star_u8 = ty::mk_imm_ptr( bcx.tcx(), ty::mk_mach_uint(bcx.tcx(), ast::ty_u8)); - let fty = ty::mk_fn(bcx.tcx(), FnTyBase { - meta: FnMeta {purity: ast::impure_fn, - proto: ast::ProtoBorrowed, - onceness: ast::Many, - region: ty::re_bound(ty::br_anon(0)), - bounds: @~[]}, + let fty = ty::mk_closure(bcx.tcx(), ty::ClosureTy { + purity: ast::impure_fn, + sigil: ast::BorrowedSigil, + onceness: ast::Many, + region: ty::re_bound(ty::br_anon(0)), sig: FnSig {inputs: ~[arg {mode: ast::expl(ast::by_copy), ty: star_u8}], output: ty::mk_nil(bcx.tcx())} @@ -843,14 +840,14 @@ pub fn trans_intrinsic(ccx: @crate_ctxt, pub fn trans_foreign_fn(ccx: @crate_ctxt, +path: ast_map::path, - decl: ast::fn_decl, - body: ast::blk, + decl: &ast::fn_decl, + body: &ast::blk, llwrapfn: ValueRef, id: ast::node_id) { let _icx = ccx.insn_ctxt("foreign::build_foreign_fn"); fn build_rust_fn(ccx: @crate_ctxt, +path: ast_map::path, - decl: ast::fn_decl, body: ast::blk, + decl: &ast::fn_decl, body: &ast::blk, id: ast::node_id) -> ValueRef { let _icx = ccx.insn_ctxt("foreign::foreign::build_rust_fn"); let t = ty::node_id_to_type(ccx.tcx, id); diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 9909980fb7e98..564460fd88e9b 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -172,7 +172,8 @@ pub fn simplified_glue_type(tcx: ty::ctxt, field: uint, t: ty::t) -> ty::t { if field == abi::tydesc_field_free_glue { match ty::get(t).sty { - ty::ty_fn(*) | + ty::ty_bare_fn(*) | + ty::ty_closure(*) | ty::ty_box(*) | ty::ty_opaque_box | ty::ty_uniq(*) | @@ -419,8 +420,8 @@ pub fn make_free_glue(bcx: block, v: ValueRef, t: ty::t) { tvec::expand_boxed_vec_ty(bcx.tcx(), t)); return; } - ty::ty_fn(_) => { - closure::make_fn_glue(bcx, v, t, free_ty) + ty::ty_closure(_) => { + closure::make_closure_glue(bcx, v, t, free_ty) } ty::ty_opaque_closure_ptr(ck) => { closure::make_opaque_cbox_free_glue(bcx, ck, v) @@ -528,8 +529,8 @@ pub fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) { } } } - ty::ty_fn(_) => { - closure::make_fn_glue(bcx, v0, t, drop_ty) + ty::ty_closure(_) => { + closure::make_closure_glue(bcx, v0, t, drop_ty) } ty::ty_trait(_, _, ty::vstore_box) => { let llbox = Load(bcx, GEPi(bcx, v0, [0u, 1u])); @@ -594,8 +595,8 @@ pub fn make_take_glue(bcx: block, v: ValueRef, t: ty::t) { | ty::ty_estr(ty::vstore_slice(_)) => { bcx } - ty::ty_fn(_) => { - closure::make_fn_glue(bcx, v, t, take_ty) + ty::ty_closure(_) => { + closure::make_closure_glue(bcx, v, t, take_ty) } ty::ty_trait(_, _, ty::vstore_box) => { let llbox = Load(bcx, GEPi(bcx, v, [0u, 1u])); diff --git a/src/librustc/middle/trans/inline.rs b/src/librustc/middle/trans/inline.rs index 4466e4e1b288c..c094db4ecca1f 100644 --- a/src/librustc/middle/trans/inline.rs +++ b/src/librustc/middle/trans/inline.rs @@ -108,8 +108,8 @@ pub fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id, }; trans_fn(ccx, path, - mth.decl, - mth.body, + &mth.decl, + &mth.body, llfn, self_kind, None, diff --git a/src/librustc/middle/trans/machine.rs b/src/librustc/middle/trans/machine.rs index e76176218b79c..828b561939055 100644 --- a/src/librustc/middle/trans/machine.rs +++ b/src/librustc/middle/trans/machine.rs @@ -34,8 +34,11 @@ pub fn simplify_type(tcx: ty::ctxt, typ: ty::t) -> ty::t { ty::ty_box(_) | ty::ty_opaque_box | ty::ty_uniq(_) | ty::ty_evec(_, ty::vstore_uniq) | ty::ty_evec(_, ty::vstore_box) | ty::ty_estr(ty::vstore_uniq) | ty::ty_estr(ty::vstore_box) | - ty::ty_ptr(_) | ty::ty_rptr(_,_) => nilptr(tcx), - ty::ty_fn(_) => ty::mk_tup(tcx, ~[nilptr(tcx), nilptr(tcx)]), + ty::ty_ptr(_) | ty::ty_rptr(*) => nilptr(tcx), + + ty::ty_bare_fn(*) | // FIXME(#4804) Bare fn repr + ty::ty_closure(*) => ty::mk_tup(tcx, ~[nilptr(tcx), nilptr(tcx)]), + ty::ty_evec(_, ty::vstore_slice(_)) | ty::ty_estr(ty::vstore_slice(_)) => { ty::mk_tup(tcx, ~[nilptr(tcx), ty::mk_int(tcx)]) diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index d751b8f92085c..1d48d2dde6bc5 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -142,8 +142,8 @@ pub fn trans_method(ccx: @crate_ctxt, // generate the actual code trans_fn(ccx, path, - method.decl, - method.body, + &method.decl, + &method.body, llfn, self_arg, param_substs, @@ -822,7 +822,7 @@ pub fn make_impl_vtable(ccx: @crate_ctxt, let has_tps = (*ty::lookup_item_type(ccx.tcx, impl_id).bounds).len() > 0u; make_vtable(ccx, vec::map(*ty::trait_methods(tcx, trt_id), |im| { let fty = ty::subst_tps(tcx, substs, None, - ty::mk_fn(tcx, copy im.fty)); + ty::mk_bare_fn(tcx, copy im.fty)); if (*im.tps).len() > 0u || ty::type_has_self(fty) { debug!("(making impl vtable) method has self or type params: %s", tcx.sess.str_of(im.ident)); diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index 5873d0a76d946..b09a41f2b7f06 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -26,7 +26,7 @@ use middle::trans::shape; use middle::trans::type_of::type_of_fn_from_ty; use middle::trans::type_of; use middle::trans::type_use; -use middle::ty::{FnTyBase, FnMeta, FnSig}; +use middle::ty::{FnSig}; use middle::typeck; use core::option; @@ -166,12 +166,12 @@ pub fn monomorphic_fn(ccx: @crate_ctxt, let lldecl = match map_node { ast_map::node_item(i@@ast::item { // XXX: Bad copy. - node: ast::item_fn(copy decl, _, _, ref body), + node: ast::item_fn(ref decl, _, _, ref body), _ }, _) => { let d = mk_lldecl(); set_inline_hint_if_appr(/*bad*/copy i.attrs, d); - trans_fn(ccx, pt, decl, *body, d, no_self, psubsts, fn_id.node, None); + trans_fn(ccx, pt, decl, body, d, no_self, psubsts, fn_id.node, None); d } ast_map::node_item(*) => { @@ -224,7 +224,7 @@ pub fn monomorphic_fn(ccx: @crate_ctxt, None => ccx.sess.span_bug(dtor.span, ~"Bad self ty in \ dtor") }; - trans_struct_dtor(ccx, /*bad*/copy *pt, dtor.node.body, + trans_struct_dtor(ccx, /*bad*/copy *pt, &dtor.node.body, dtor.node.id, psubsts, Some(hash_id), parent_id) } ast_map::node_trait_method(@ast::provided(mth), _, pt) => { @@ -267,31 +267,34 @@ pub fn monomorphic_fn(ccx: @crate_ctxt, pub fn normalize_for_monomorphization(tcx: ty::ctxt, ty: ty::t) -> Option { // FIXME[mono] could do this recursively. is that worthwhile? (#2529) - match ty::get(ty).sty { + return match ty::get(ty).sty { ty::ty_box(*) => { Some(ty::mk_opaque_box(tcx)) } - ty::ty_fn(ref fty) => { - Some(ty::mk_fn( + ty::ty_bare_fn(_) => { + Some(ty::mk_bare_fn( tcx, - FnTyBase {meta: FnMeta {purity: ast::impure_fn, - proto: fty.meta.proto, - onceness: ast::Many, - region: ty::re_static, - bounds: @~[]}, - sig: FnSig {inputs: ~[], - output: ty::mk_nil(tcx)}})) + ty::BareFnTy { + purity: ast::impure_fn, + abi: ast::RustAbi, + sig: FnSig {inputs: ~[], + output: ty::mk_nil(tcx)}})) } - ty::ty_trait(_, _, _) => { - Some(ty::mk_fn( - tcx, - FnTyBase {meta: FnMeta {purity: ast::impure_fn, - proto: ast::ProtoBox, - onceness: ast::Many, - region: ty::re_static, - bounds: @~[]}, - sig: FnSig {inputs: ~[], - output: ty::mk_nil(tcx)}})) + ty::ty_closure(ref fty) => { + Some(normalized_closure_ty(tcx, fty.sigil)) + } + ty::ty_trait(_, _, ref vstore) => { + let sigil = match *vstore { + ty::vstore_uniq => ast::OwnedSigil, + ty::vstore_box => ast::ManagedSigil, + ty::vstore_slice(_) => ast::BorrowedSigil, + ty::vstore_fixed(*) => { + tcx.sess.bug(fmt!("ty_trait with vstore_fixed")); + } + }; + + // Traits have the same runtime representation as closures. + Some(normalized_closure_ty(tcx, sigil)) } ty::ty_ptr(_) => { Some(ty::mk_uint(tcx)) @@ -299,6 +302,20 @@ pub fn normalize_for_monomorphization(tcx: ty::ctxt, _ => { None } + }; + + fn normalized_closure_ty(tcx: ty::ctxt, + sigil: ast::Sigil) -> ty::t + { + ty::mk_closure( + tcx, + ty::ClosureTy { + purity: ast::impure_fn, + sigil: sigil, + onceness: ast::Many, + region: ty::re_static, + sig: ty::FnSig {inputs: ~[], + output: ty::mk_nil(tcx)}}) } } diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index 7380fa2e56269..9466099904c1a 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -86,9 +86,8 @@ pub impl reflector { tcx.sess.ident_of(~"visit_" + ty_name), *self.visitor_methods).expect(fmt!("Couldn't find visit method \ for %s", ty_name)); - let mth_ty = ty::mk_fn( - tcx, - /*bad*/copy self.visitor_methods[mth_idx].fty); + let mth_ty = + ty::mk_bare_fn(tcx, copy self.visitor_methods[mth_idx].fty); let v = self.visitor_val; debug!("passing %u args:", vec::len(args)); let bcx = self.bcx; @@ -211,39 +210,33 @@ pub impl reflector { } } + // FIXME (#2594): fetch constants out of intrinsic + // FIXME (#4809): visitor should break out bare fns from other fns + ty::ty_closure(ref fty) => { + let pureval = ast_purity_constant(fty.purity); + let sigilval = ast_sigil_constant(fty.sigil); + let retval = if ty::type_is_bot(fty.sig.output) {0u} else {1u}; + let extra = ~[self.c_uint(pureval), + self.c_uint(sigilval), + self.c_uint(vec::len(fty.sig.inputs)), + self.c_uint(retval)]; + self.visit(~"enter_fn", copy extra); // XXX: Bad copy. + self.visit_sig(retval, &fty.sig); + self.visit(~"leave_fn", extra); + } + // FIXME (#2594): fetch constants out of intrinsic:: for the // numbers. - ty::ty_fn(ref fty) => { - let pureval = match fty.meta.purity { - ast::pure_fn => 0u, - ast::unsafe_fn => 1u, - ast::impure_fn => 2u, - ast::extern_fn => 3u - }; - let protoval = ast_proto_constant(fty.meta.proto); + ty::ty_bare_fn(ref fty) => { + let pureval = ast_purity_constant(fty.purity); + let sigilval = 0u; let retval = if ty::type_is_bot(fty.sig.output) {0u} else {1u}; let extra = ~[self.c_uint(pureval), - self.c_uint(protoval), + self.c_uint(sigilval), self.c_uint(vec::len(fty.sig.inputs)), self.c_uint(retval)]; self.visit(~"enter_fn", copy extra); // XXX: Bad copy. - for fty.sig.inputs.eachi |i, arg| { - let modeval = match arg.mode { - ast::infer(_) => 0u, - ast::expl(e) => match e { - ast::by_ref => 1u, - ast::by_val => 2u, - ast::by_copy => 5u - } - }; - self.visit(~"fn_input", - ~[self.c_uint(i), - self.c_uint(modeval), - self.c_tydesc(arg.ty)]); - } - self.visit(~"fn_output", - ~[self.c_uint(retval), - self.c_tydesc(fty.sig.output)]); + self.visit_sig(retval, &fty.sig); self.visit(~"leave_fn", extra); } @@ -302,11 +295,31 @@ pub impl reflector { ty::ty_type => self.leaf(~"type"), ty::ty_opaque_box => self.leaf(~"opaque_box"), ty::ty_opaque_closure_ptr(ck) => { - let ckval = ast_proto_constant(ck); + let ckval = ast_sigil_constant(ck); self.visit(~"closure_ptr", ~[self.c_uint(ckval)]) } } } + + fn visit_sig(&self, retval: uint, sig: &ty::FnSig) { + for sig.inputs.eachi |i, arg| { + let modeval = match arg.mode { + ast::infer(_) => 0u, + ast::expl(e) => match e { + ast::by_ref => 1u, + ast::by_val => 2u, + ast::by_copy => 5u + } + }; + self.visit(~"fn_input", + ~[self.c_uint(i), + self.c_uint(modeval), + self.c_tydesc(arg.ty)]); + } + self.visit(~"fn_output", + ~[self.c_uint(retval), + self.c_tydesc(sig.output)]); + } } // Emit a sequence of calls to visit_ty::visit_foo @@ -332,12 +345,20 @@ pub fn emit_calls_to_trait_visit_ty(bcx: block, return final; } -pub fn ast_proto_constant(proto: ast::Proto) -> uint { - match proto { - ast::ProtoBare => 0u, - ast::ProtoUniq => 2u, - ast::ProtoBox => 3u, - ast::ProtoBorrowed => 4u, +pub fn ast_sigil_constant(sigil: ast::Sigil) -> uint { + match sigil { + ast::OwnedSigil => 2u, + ast::ManagedSigil => 3u, + ast::BorrowedSigil => 4u, + } +} + +pub fn ast_purity_constant(purity: ast::purity) -> uint { + match purity { + ast::pure_fn => 0u, + ast::unsafe_fn => 1u, + ast::impure_fn => 2u, + ast::extern_fn => 3u } } diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index 99c47997df04c..f727b5a2de074 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -59,7 +59,13 @@ pub fn type_of_fn(cx: @crate_ctxt, inputs: &[ty::arg], // Given a function type and a count of ty params, construct an llvm type pub fn type_of_fn_from_ty(cx: @crate_ctxt, fty: ty::t) -> TypeRef { - type_of_fn(cx, ty::ty_fn_args(fty), ty::ty_fn_ret(fty)) + match ty::get(fty).sty { + ty::ty_closure(ref f) => type_of_fn(cx, f.sig.inputs, f.sig.output), + ty::ty_bare_fn(ref f) => type_of_fn(cx, f.sig.inputs, f.sig.output), + _ => { + cx.sess.bug(~"type_of_fn_from_ty given non-closure, non-bare-fn") + } + } } pub fn type_of_non_gc_box(cx: @crate_ctxt, t: ty::t) -> TypeRef { @@ -170,7 +176,11 @@ pub fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef { // structs T_struct(~[T_struct(tys)]) } - ty::ty_fn(_) => T_fn_pair(cx, type_of_fn_from_ty(cx, t)), + + // FIXME(#4804) Bare fn repr + // ty::ty_bare_fn(_) => T_ptr(type_of_fn_from_ty(cx, t)), + ty::ty_bare_fn(_) => T_fn_pair(cx, type_of_fn_from_ty(cx, t)), + ty::ty_closure(_) => T_fn_pair(cx, type_of_fn_from_ty(cx, t)), ty::ty_trait(_, _, vstore) => T_opaque_trait(cx, vstore), ty::ty_type => T_ptr(cx.tydesc_type), ty::ty_tup(elts) => { diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index 6b0d4e17c74c4..3fd334c2d1508 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -69,8 +69,9 @@ pub fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint) let cx = {ccx: ccx, uses: vec::cast_to_mut(vec::from_elem(n_tps, 0u))}; match ty::get(ty::lookup_item_type(cx.ccx.tcx, fn_id).ty).sty { - ty::ty_fn(ref fn_ty) => { - for vec::each(fn_ty.sig.inputs) |arg| { + ty::ty_bare_fn(ty::BareFnTy {sig: ref sig, _}) | + ty::ty_closure(ty::ClosureTy {sig: ref sig, _}) => { + for vec::each(sig.inputs) |arg| { match ty::resolved_mode(ccx.tcx, arg.mode) { by_val | by_copy => { type_needs(cx, use_repr, arg.ty); @@ -197,8 +198,12 @@ pub fn type_needs_inner(cx: ctx, it, we depend on the drop glue for T (we have to write the right tydesc into the result) */ - ty::ty_fn(_) | ty::ty_ptr(_) | ty::ty_rptr(_, _) - | ty::ty_trait(_, _, _) => false, + ty::ty_closure(*) | + ty::ty_bare_fn(*) | + ty::ty_ptr(_) | + ty::ty_rptr(_, _) | + ty::ty_trait(_, _, _) => false, + ty::ty_enum(did, ref substs) => { if option::is_none(&list::find(enums_seen, |id| *id == did)) { let seen = @Cons(did, enums_seen); @@ -287,15 +292,15 @@ pub fn mark_for_expr(cx: ctx, e: @expr) { } } expr_fn(*) | expr_fn_block(*) => { - match ty::ty_fn_proto(ty::expr_ty(cx.ccx.tcx, e)) { - ast::ProtoBare | ast::ProtoUniq => {} - ast::ProtoBox | ast::ProtoBorrowed => { - for vec::each(*freevars::get_freevars(cx.ccx.tcx, e.id)) |fv| { - let node_id = ast_util::def_id_of_def(fv.def).node; - node_type_needs(cx, use_repr, node_id); - } + match ty::ty_closure_sigil(ty::expr_ty(cx.ccx.tcx, e)) { + ast::OwnedSigil => {} + ast::BorrowedSigil | ast::ManagedSigil => { + for freevars::get_freevars(cx.ccx.tcx, e.id).each |fv| { + let node_id = ast_util::def_id_of_def(fv.def).node; + node_type_needs(cx, use_repr, node_id); + } + } } - } } expr_assign(val, _) | expr_swap(val, _) | expr_assign_op(_, val, _) | expr_ret(Some(val)) => { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 9905701e058dd..ef62fb3caf18a 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[warn(deprecated_pattern)]; - use core::prelude::*; use driver::session; @@ -27,7 +25,7 @@ use middle; use session::Session; use util::ppaux::{note_and_explain_region, bound_region_to_str}; use util::ppaux::{region_to_str, explain_region, vstore_to_str}; -use util::ppaux::{ty_to_str, proto_ty_to_str, tys_to_str}; +use util::ppaux::{ty_to_str, tys_to_str}; use core::cast; use core::cmp; @@ -73,7 +71,7 @@ pub type param_bounds = @~[param_bound]; pub type method = { ident: ast::ident, tps: @~[param_bounds], - fty: FnTy, + fty: BareFnTy, self_ty: ast::self_ty_, vis: ast::visibility, def_id: ast::def_id @@ -344,22 +342,20 @@ pub pure fn type_contains_err(t: t) -> bool { pub pure fn type_def_id(t: t) -> Option { get(t).o_def_id } pub pure fn type_id(t: t) -> uint { get(t).id } -/** - * Meta information about a closure. - * - * - `purity` is the function's effect (pure, impure, unsafe). - * - `proto` is the protocol (fn@, fn~, etc). - * - `onceness` indicates whether the function can be called one time or many - * times. - * - `region` is the region bound on the function's upvars (often &static). - * - `bounds` is the parameter bounds on the function's upvars. */ #[deriving_eq] -pub struct FnMeta { +pub struct BareFnTy { + purity: ast::purity, + abi: Abi, + sig: FnSig +} + +#[deriving_eq] +pub struct ClosureTy { purity: ast::purity, - proto: ast::Proto, + sigil: ast::Sigil, onceness: ast::Onceness, region: Region, - bounds: @~[param_bound] + sig: FnSig } /** @@ -374,25 +370,19 @@ pub struct FnSig { output: t } -/** - * Function type: combines the meta information and the - * type signature. This particular type is parameterized - * by the meta information because, in some cases, the - * meta information is inferred. */ -#[deriving_eq] -pub struct FnTyBase { - meta: M, // Either FnMeta or FnVid - sig: FnSig // Types of arguments/return type +impl BareFnTy : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + to_bytes::iter_bytes_3(&self.purity, &self.abi, &self.sig, lsb0, f) + } } -impl FnTyBase : to_bytes::IterBytes { +impl ClosureTy : to_bytes::IterBytes { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { - to_bytes::iter_bytes_2(&self.meta, &self.sig, lsb0, f) + to_bytes::iter_bytes_5(&self.purity, &self.sigil, &self.onceness, + &self.region, &self.sig, lsb0, f) } } -pub type FnTy = FnTyBase; - #[deriving_eq] pub struct param_ty { idx: uint, @@ -491,6 +481,7 @@ pub struct substs { // NB: If you change this, you'll probably want to change the corresponding // AST structure in libsyntax/ast.rs as well. +#[deriving_eq] pub enum sty { ty_nil, ty_bot, @@ -506,7 +497,8 @@ pub enum sty { ty_ptr(mt), ty_rptr(Region, mt), ty_rec(~[field]), - ty_fn(FnTy), + ty_bare_fn(BareFnTy), + ty_closure(ClosureTy), ty_trait(def_id, substs, vstore), ty_struct(def_id, substs), ty_tup(~[t]), @@ -522,7 +514,7 @@ pub enum sty { // "Fake" types, used for trans purposes ty_type, // type_desc* ty_opaque_box, // used by monomorphizer to represent any @ box - ty_opaque_closure_ptr(ast::Proto), // ptr to env for fn, fn@, fn~ + ty_opaque_closure_ptr(Sigil), // ptr to env for fn, fn@, fn~ ty_unboxed_vec(mt), } @@ -546,8 +538,9 @@ pub enum type_err { terr_mismatch, terr_purity_mismatch(expected_found), terr_onceness_mismatch(expected_found), + terr_abi_mismatch(expected_found), terr_mutability, - terr_proto_mismatch(expected_found), + terr_sigil_mismatch(expected_found), terr_box_mutability, terr_ptr_mutability, terr_ref_mutability, @@ -744,6 +737,15 @@ pub impl RegionVid : to_bytes::IterBytes { } } +pub fn kind_to_param_bounds(kind: Kind) -> param_bounds { + let mut bounds = ~[]; + if kind_can_be_copied(kind) { bounds.push(bound_copy); } + if kind_can_be_sent(kind) { bounds.push(bound_owned); } + else if kind_is_durable(kind) { bounds.push(bound_durable); } + if kind_is_const(kind) { bounds.push(bound_const); } + return @bounds; +} + pub fn param_bounds_to_kind(bounds: param_bounds) -> Kind { let mut kind = kind_noncopyable(); for vec::each(*bounds) |bound| { @@ -925,8 +927,12 @@ fn mk_t_with_id(cx: ctxt, +st: sty, o_def_id: Option) -> t { } &ty_rec(ref flds) => for flds.each |f| { flags |= get(f.mt.ty).flags; }, &ty_tup(ref ts) => for ts.each |tt| { flags |= get(*tt).flags; }, - &ty_fn(ref f) => { - flags |= rflags(f.meta.region); + &ty_bare_fn(ref f) => { + for f.sig.inputs.each |a| { flags |= get(a.ty).flags; } + flags |= get(f.sig.output).flags; + } + &ty_closure(ref f) => { + flags |= rflags(f.region); for f.sig.inputs.each |a| { flags |= get(a.ty).flags; } flags |= get(f.sig.output).flags; } @@ -1044,8 +1050,25 @@ pub fn mk_rec(cx: ctxt, +fs: ~[field]) -> t { mk_t(cx, ty_rec(fs)) } pub fn mk_tup(cx: ctxt, +ts: ~[t]) -> t { mk_t(cx, ty_tup(ts)) } -// take a copy because we want to own the various vectors inside -pub fn mk_fn(cx: ctxt, +fty: FnTy) -> t { mk_t(cx, ty_fn(fty)) } +pub fn mk_closure(cx: ctxt, +fty: ClosureTy) -> t { + mk_t(cx, ty_closure(fty)) +} + +pub fn mk_bare_fn(cx: ctxt, +fty: BareFnTy) -> t { + mk_t(cx, ty_bare_fn(fty)) +} + +pub fn mk_ctor_fn(cx: ctxt, input_tys: &[ty::t], output: ty::t) -> t { + let input_args = input_tys.map(|t| arg {mode: ast::expl(ast::by_copy), + ty: *t}); + mk_bare_fn(cx, + BareFnTy { + purity: ast::pure_fn, + abi: ast::RustAbi, + sig: FnSig {inputs: input_args, + output: output}}) +} + pub fn mk_trait(cx: ctxt, did: ast::def_id, +substs: substs, vstore: vstore) -> t { @@ -1074,8 +1097,8 @@ pub fn mk_param(cx: ctxt, n: uint, k: def_id) -> t { pub fn mk_type(cx: ctxt) -> t { mk_t(cx, ty_type) } -pub fn mk_opaque_closure_ptr(cx: ctxt, proto: ast::Proto) -> t { - mk_t(cx, ty_opaque_closure_ptr(proto)) +pub fn mk_opaque_closure_ptr(cx: ctxt, sigil: ast::Sigil) -> t { + mk_t(cx, ty_opaque_closure_ptr(sigil)) } pub fn mk_opaque_box(cx: ctxt) -> t { mk_t(cx, ty_opaque_box) } @@ -1097,13 +1120,11 @@ pub pure fn mach_sty(cfg: @session::config, t: t) -> sty { pub fn default_arg_mode_for_ty(tcx: ctxt, ty: ty::t) -> ast::rmode { // FIXME(#2202) --- We retain by-ref for fn& things to workaround a // memory leak that otherwise results when @fn is upcast to &fn. - if type_is_fn(ty) { - match ty_fn_proto(ty) { - ast::ProtoBorrowed => { - return ast::by_ref; - } - _ => {} + match ty::get(ty).sty { + ty::ty_closure(ClosureTy {sigil: ast::BorrowedSigil, _}) => { + return ast::by_ref; } + _ => {} } return if tcx.legacy_modes { if type_is_borrowed(ty) { @@ -1119,13 +1140,6 @@ pub fn default_arg_mode_for_ty(tcx: ctxt, ty: ty::t) -> ast::rmode { ast::by_copy }; - fn type_is_fn(ty: t) -> bool { - match get(ty).sty { - ty_fn(*) => true, - _ => false - } - } - fn type_is_borrowed(ty: t) -> bool { match ty::get(ty).sty { ty::ty_rptr(*) => true, @@ -1171,7 +1185,11 @@ pub fn maybe_walk_ty(ty: t, f: fn(t) -> bool) { for fields.each |fl| { maybe_walk_ty(fl.mt.ty, f); } } ty_tup(ts) => { for ts.each |tt| { maybe_walk_ty(*tt, f); } } - ty_fn(ref ft) => { + ty_bare_fn(ref ft) => { + for ft.sig.inputs.each |a| { maybe_walk_ty(a.ty, f); } + maybe_walk_ty(ft.sig.output, f); + } + ty_closure(ref ft) => { for ft.sig.inputs.each |a| { maybe_walk_ty(a.ty, f); } maybe_walk_ty(ft.sig.output, f); } @@ -1235,9 +1253,13 @@ fn fold_sty(sty: &sty, fldop: fn(t) -> t) -> sty { let new_ts = vec::map(ts, |tt| fldop(*tt)); ty_tup(new_ts) } - ty_fn(ref f) => { + ty_bare_fn(ref f) => { + let sig = fold_sig(&f.sig, fldop); + ty_bare_fn(BareFnTy {sig: sig, abi: f.abi, purity: f.purity}) + } + ty_closure(ref f) => { let sig = fold_sig(&f.sig, fldop); - ty_fn(FnTyBase {meta: f.meta, sig: sig}) + ty_closure(ClosureTy {sig: sig, ..copy *f}) } ty_rptr(r, tm) => { ty_rptr(r, mt {ty: fldop(tm.ty), mutbl: tm.mutbl}) @@ -1318,10 +1340,14 @@ pub fn fold_regions_and_ty( ty_trait(def_id, ref substs, vst) => { ty::mk_trait(cx, def_id, fold_substs(substs, fldr, fldt), vst) } - ty_fn(ref f) => { - ty::mk_fn(cx, FnTyBase {meta: FnMeta {region: fldr(f.meta.region), - ..f.meta}, - sig: fold_sig(&f.sig, fldfnt)}) + ty_bare_fn(ref f) => { + ty::mk_bare_fn(cx, BareFnTy {sig: fold_sig(&f.sig, fldfnt), + ..copy *f}) + } + ty_closure(ref f) => { + ty::mk_closure(cx, ClosureTy {region: fldr(f.region), + sig: fold_sig(&f.sig, fldfnt), + ..copy *f}) } ref sty => { fold_sty_to_ty(cx, sty, |t| fldt(t)) @@ -1329,30 +1355,6 @@ pub fn fold_regions_and_ty( } } -/* A little utility: it often happens that I have a `fn_ty`, - * but I want to use some function like `fold_regions_and_ty()` - * that is defined over all types. This utility converts to - * a full type and back. It's not the best way to do this (somewhat - * inefficient to do the conversion), it would be better to refactor - * all this folding business. However, I've been waiting on that - * until trait support is improved. */ -pub fn apply_op_on_t_to_ty_fn( - cx: ctxt, - f: &FnTy, - t_op: fn(t) -> t) -> FnTy -{ - let t0 = ty::mk_fn(cx, /*bad*/copy *f); - let t1 = t_op(t0); - match ty::get(t1).sty { - ty::ty_fn(copy f) => { - move f - } - _ => { - cx.sess.bug(~"`t_op` did not return a function type"); - } - } -} - // n.b. this function is intended to eventually replace fold_region() below, // that is why its name is so similar. pub fn fold_regions( @@ -1372,41 +1374,6 @@ pub fn fold_regions( do_fold(cx, ty, false, fldr) } -pub fn fold_region(cx: ctxt, t0: t, fldop: fn(Region, bool) -> Region) -> t { - fn do_fold(cx: ctxt, t0: t, under_r: bool, - fldop: fn(Region, bool) -> Region) -> t { - let tb = get(t0); - if !tbox_has_flag(tb, has_regions) { return t0; } - match tb.sty { - ty_rptr(r, mt {ty: t1, mutbl: m}) => { - let m_r = fldop(r, under_r); - let m_t1 = do_fold(cx, t1, true, fldop); - ty::mk_rptr(cx, m_r, mt {ty: m_t1, mutbl: m}) - } - ty_estr(vstore_slice(r)) => { - let m_r = fldop(r, under_r); - ty::mk_estr(cx, vstore_slice(m_r)) - } - ty_evec(mt {ty: t1, mutbl: m}, vstore_slice(r)) => { - let m_r = fldop(r, under_r); - let m_t1 = do_fold(cx, t1, true, fldop); - ty::mk_evec(cx, mt {ty: m_t1, mutbl: m}, vstore_slice(m_r)) - } - ty_fn(_) => { - // do not recurse into functions, which introduce fresh bindings - t0 - } - ref sty => { - do fold_sty_to_ty(cx, sty) |t| { - do_fold(cx, t, under_r, fldop) - } - } - } - } - - do_fold(cx, t0, false, fldop) -} - // Substitute *only* type parameters. Used in trans where regions are erased. pub fn subst_tps(cx: ctxt, tps: &[t], self_ty_opt: Option, typ: t) -> t { if tps.len() == 0u && self_ty_opt.is_none() { return typ; } @@ -1529,7 +1496,9 @@ pub fn type_is_bool(ty: t) -> bool { get(ty).sty == ty_bool } pub fn type_is_structural(ty: t) -> bool { match get(ty).sty { - ty_rec(_) | ty_struct(*) | ty_tup(_) | ty_enum(*) | ty_fn(_) | + ty_rec(_) | ty_struct(*) | ty_tup(_) | ty_enum(*) | + ty_closure(_) | + ty_bare_fn(_) | // FIXME(#4804) Bare fn repr ty_trait(*) | ty_evec(_, vstore_fixed(_)) | ty_estr(vstore_fixed(_)) | ty_evec(_, vstore_slice(_)) | ty_estr(vstore_slice(_)) @@ -1715,10 +1684,11 @@ pub fn type_needs_drop(cx: ctxt, ty: t) -> bool { } accum } - ty_fn(ref fty) => { - match fty.meta.proto { - ast::ProtoBare | ast::ProtoBorrowed => false, - ast::ProtoBox | ast::ProtoUniq => true, + ty_bare_fn(*) => false, + ty_closure(ref fty) => { + match fty.sigil { + ast::BorrowedSigil => false, + ast::ManagedSigil | ast::OwnedSigil => true, } } }; @@ -1813,7 +1783,7 @@ pub enum Kind { kind_(u32) } const KIND_MASK_COPY : u32 = 0b000000000000000000000000001_u32; /// no shared box, borrowed ptr (must imply DURABLE) -const KIND_MASK_OWNED : u32 = 0b000000000000000000000000010_u32; +const KIND_MASK_OWNED : u32 = 0b000000000000000000000000010_u32; /// is durable (no borrowed ptrs) const KIND_MASK_DURABLE : u32 = 0b000000000000000000000000100_u32; @@ -1942,20 +1912,25 @@ pub pure fn kind_is_durable(k: Kind) -> bool { *k & KIND_MASK_DURABLE == KIND_MASK_DURABLE } -pub fn meta_kind(p: FnMeta) -> Kind { - match p.proto { // XXX consider the kind bounds! - ast::ProtoBare => { - kind_safe_for_default_mode_send() | kind_const() | kind_durable() - } - ast::ProtoBorrowed => { - kind_noncopyable() | kind_(KIND_MASK_DEFAULT_MODE) - } - ast::ProtoBox => { - kind_safe_for_default_mode() | kind_durable() - } - ast::ProtoUniq => { - kind_owned_copy() | kind_durable() - } +pure fn kind_is_const(k: Kind) -> bool { + *k & KIND_MASK_CONST == KIND_MASK_CONST +} + +fn closure_kind(cty: &ClosureTy) -> Kind { + let kind = match cty.sigil { + ast::BorrowedSigil => kind_implicitly_copyable(), + ast::ManagedSigil => kind_implicitly_copyable(), + ast::OwnedSigil => kind_owned_only() | kind_durable(), + }; + + let kind = match cty.region { + re_static => kind | kind_durable(), + _ => kind - kind_owned_only() - kind_durable() + }; + + match cty.onceness { + ast::Once => kind - kind_implicitly_copyable(), + ast::Many => kind } } @@ -2022,7 +1997,7 @@ pub fn type_kind_ext(cx: ctxt, ty: t, allow_ty_var: bool) -> Kind { let mut result = match /*bad*/copy get(ty).sty { // Scalar and unique types are sendable, constant, and owned ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) | - ty_ptr(_) => { + ty_bare_fn(_) | ty_ptr(_) => { kind_safe_for_default_mode_send() | kind_const() | kind_durable() } @@ -2035,8 +2010,9 @@ pub fn type_kind_ext(cx: ctxt, ty: t, allow_ty_var: bool) -> Kind { } } - // functions depend on the protocol - ty_fn(ref f) => meta_kind(f.meta), + ty_closure(ref c) => { + closure_kind(c) + } // Those with refcounts raise noncopyable to copyable, // lower sendable to copyable. Therefore just set result to copyable. @@ -2215,7 +2191,8 @@ fn type_size(cx: ctxt, ty: t) -> uint { ty_evec(_, vstore_slice(_)) | ty_estr(vstore_slice(_)) | - ty_fn(_) => { + ty_bare_fn(*) | + ty_closure(*) => { 2 } @@ -2297,7 +2274,8 @@ pub fn is_instantiable(cx: ctxt, r_ty: t) -> bool { ty_uint(_) | ty_float(_) | ty_estr(_) | - ty_fn(_) | + ty_bare_fn(_) | + ty_closure(_) | ty_infer(_) | ty_err | ty_param(_) | @@ -2472,9 +2450,9 @@ pub fn type_is_pod(cx: ctxt, ty: t) -> bool { match /*bad*/copy get(ty).sty { // Scalar types ty_nil | ty_bot | ty_bool | ty_int(_) | ty_float(_) | ty_uint(_) | - ty_type | ty_ptr(_) => result = true, + ty_type | ty_ptr(_) | ty_bare_fn(_) => result = true, // Boxed types - ty_box(_) | ty_uniq(_) | ty_fn(_) | + ty_box(_) | ty_uniq(_) | ty_closure(_) | ty_estr(vstore_uniq) | ty_estr(vstore_box) | ty_evec(_, vstore_uniq) | ty_evec(_, vstore_box) | ty_trait(_, _, _) | ty_rptr(_,_) | ty_opaque_box => result = false, @@ -2700,14 +2678,9 @@ impl arg : to_bytes::IterBytes { } } -impl FnMeta : to_bytes::IterBytes { +impl Kind : to_bytes::IterBytes { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { - to_bytes::iter_bytes_5(&self.purity, - &self.proto, - &self.onceness, - &self.region, - &self.bounds, - lsb0, f); + (**self).iter_bytes(lsb0, f) } } @@ -2755,7 +2728,7 @@ impl sty : to_bytes::IterBytes { ty_rec(ref fs) => to_bytes::iter_bytes_2(&11u8, fs, lsb0, f), - ty_fn(ref ft) => + ty_bare_fn(ref ft) => to_bytes::iter_bytes_2(&12u8, ft, lsb0, f), ty_self => 13u8.iter_bytes(lsb0, f), @@ -2789,7 +2762,10 @@ impl sty : to_bytes::IterBytes { ty_rptr(ref r, ref mt) => to_bytes::iter_bytes_3(&24u8, r, mt, lsb0, f), - ty_err => 25u8.iter_bytes(lsb0, f) + ty_err => 25u8.iter_bytes(lsb0, f), + + ty_closure(ref ct) => + to_bytes::iter_bytes_2(&26u8, ct, lsb0, f), } } } @@ -2823,36 +2799,48 @@ fn node_id_has_type_params(cx: ctxt, id: ast::node_id) -> bool { // Type accessors for substructures of types pub fn ty_fn_args(fty: t) -> ~[arg] { match get(fty).sty { - ty_fn(ref f) => /*bad*/copy f.sig.inputs, - _ => die!(~"ty_fn_args() called on non-fn type") + ty_bare_fn(ref f) => copy f.sig.inputs, + ty_closure(ref f) => copy f.sig.inputs, + ref s => { + die!(fmt!("ty_fn_args() called on non-fn type: %?", s)) + } } } -pub fn ty_fn_proto(fty: t) -> Proto { +pub fn ty_closure_sigil(fty: t) -> Sigil { match get(fty).sty { - ty_fn(ref f) => f.meta.proto, - _ => die!(~"ty_fn_proto() called on non-fn type") + ty_closure(ref f) => f.sigil, + ref s => { + die!(fmt!("ty_closure_sigil() called on non-closure type: %?", s)) + } } } pub fn ty_fn_purity(fty: t) -> ast::purity { match get(fty).sty { - ty_fn(ref f) => f.meta.purity, - _ => die!(~"ty_fn_purity() called on non-fn type") + ty_bare_fn(ref f) => f.purity, + ty_closure(ref f) => f.purity, + ref s => { + die!(fmt!("ty_fn_purity() called on non-fn type: %?", s)) + } } } pub pure fn ty_fn_ret(fty: t) -> t { match get(fty).sty { - ty_fn(ref f) => f.sig.output, - _ => die!(~"ty_fn_ret() called on non-fn type") + ty_bare_fn(ref f) => f.sig.output, + ty_closure(ref f) => f.sig.output, + ref s => { + die!(fmt!("ty_fn_ret() called on non-fn type: %?", s)) + } } } fn is_fn_ty(fty: t) -> bool { match get(fty).sty { - ty_fn(_) => true, - _ => false + ty_bare_fn(_) => true, + ty_closure(_) => true, + _ => false } } @@ -2874,17 +2862,17 @@ pub fn ty_region(ty: t) -> Region { } } -pub fn replace_fn_return_type(tcx: ctxt, fn_type: t, ret_type: t) -> t { +pub fn replace_closure_return_type(tcx: ctxt, fn_type: t, ret_type: t) -> t { /*! * * Returns a new function type based on `fn_type` but returning a value of * type `ret_type` instead. */ match ty::get(fn_type).sty { - ty::ty_fn(ref fty) => { - ty::mk_fn(tcx, FnTyBase { - meta: fty.meta, - sig: FnSig {output: ret_type, ..copy fty.sig} + ty::ty_closure(ref fty) => { + ty::mk_closure(tcx, ClosureTy { + sig: FnSig {output: ret_type, ..copy fty.sig}, + ..copy *fty }) } _ => { @@ -2900,12 +2888,6 @@ pub fn tys_in_fn_sig(sig: &FnSig) -> ~[t] { vec::append_one(sig.inputs.map(|a| a.ty), sig.output) } -// Just checks whether it's a fn that returns bool, -// not its purity. -pub fn is_pred_ty(fty: t) -> bool { - is_fn_ty(fty) && type_is_bool(ty_fn_ret(fty)) -} - // Type accessors for AST nodes pub fn block_ty(cx: ctxt, b: &ast::blk) -> t { return node_id_to_type(cx, b.node.id); @@ -3023,11 +3005,12 @@ pub fn expr_ty_adjusted(cx: ctxt, expr: @ast::expr) -> t { fn borrow_fn(cx: ctxt, expr: @ast::expr, autoref: &AutoRef, ty: ty::t) -> ty::t { match get(ty).sty { - ty_fn(ref fty) => { - ty::mk_fn(cx, FnTyBase {meta: FnMeta {proto: ProtoBorrowed, - region: autoref.region, - ..copy fty.meta}, - sig: copy fty.sig}) + ty_closure(ref fty) => { + ty::mk_closure(cx, ClosureTy { + sigil: BorrowedSigil, + region: autoref.region, + ..copy *fty + }) } ref s => { @@ -3417,7 +3400,8 @@ pub fn ty_sort_str(cx: ctxt, t: t) -> ~str { ty_ptr(_) => ~"*-ptr", ty_rptr(_, _) => ~"&-ptr", ty_rec(_) => ~"record", - ty_fn(_) => ~"fn", + ty_bare_fn(_) => ~"extern fn", + ty_closure(_) => ~"fn", ty_trait(id, _, _) => fmt!("trait %s", item_path_str(cx, id)), ty_struct(id, _) => fmt!("struct %s", item_path_str(cx, id)), ty_tup(_) => ~"tuple", @@ -3455,14 +3439,18 @@ pub fn type_err_to_str(cx: ctxt, err: &type_err) -> ~str { fmt!("expected %s fn but found %s fn", values.expected.to_str(), values.found.to_str()) } + terr_abi_mismatch(values) => { + fmt!("expected %s fn but found %s fn", + values.expected.to_str(), values.found.to_str()) + } terr_onceness_mismatch(values) => { fmt!("expected %s fn but found %s fn", values.expected.to_str(), values.found.to_str()) } - terr_proto_mismatch(values) => { + terr_sigil_mismatch(values) => { fmt!("expected %s closure, found %s closure", - proto_ty_to_str(cx, values.expected, false), - proto_ty_to_str(cx, values.found, false)) + values.expected.to_str(), + values.found.to_str()) } terr_mutability => ~"values differ in mutability", terr_box_mutability => ~"boxed values differ in mutability", @@ -4232,13 +4220,10 @@ pub fn normalize_ty(cx: ctxt, t: t) -> t { // This type has a region. Get rid of it mk_rptr(cx, re_static, normalize_mt(cx, mt)), - ty_fn(ref fn_ty) => { - mk_fn(cx, FnTyBase { - meta: FnMeta { - region: ty::re_static, - ..fn_ty.meta - }, - sig: /*bad*/copy fn_ty.sig + ty_closure(ref closure_ty) => { + mk_closure(cx, ClosureTy { + region: ty::re_static, + ..copy *closure_ty }) } @@ -4310,13 +4295,13 @@ pub fn eval_repeat_count(tcx: ctxt, // Determine what purity to check a nested function under pub pure fn determine_inherited_purity(parent_purity: ast::purity, child_purity: ast::purity, - child_proto: ast::Proto) + child_sigil: ast::Sigil) -> ast::purity { // If the closure is a stack closure and hasn't had some non-standard // purity inferred for it, then check it under its parent's purity. // Otherwise, use its own - match child_proto { - ast::ProtoBorrowed if child_purity == ast::impure_fn => parent_purity, + match child_sigil { + ast::BorrowedSigil if child_purity == ast::impure_fn => parent_purity, _ => child_purity } } @@ -4526,171 +4511,6 @@ impl bound_region : cmp::Eq { pure fn ne(&self, other: &bound_region) -> bool { !(*self).eq(other) } } -impl sty : cmp::Eq { - pure fn eq(&self, other: &sty) -> bool { - match (/*bad*/copy *self) { - ty_nil => { - match (*other) { - ty_nil => true, - _ => false - } - } - ty_bot => { - match (*other) { - ty_bot => true, - _ => false - } - } - ty_bool => { - match (*other) { - ty_bool => true, - _ => false - } - } - ty_int(e0a) => { - match (*other) { - ty_int(e0b) => e0a == e0b, - _ => false - } - } - ty_uint(e0a) => { - match (*other) { - ty_uint(e0b) => e0a == e0b, - _ => false - } - } - ty_float(e0a) => { - match (*other) { - ty_float(e0b) => e0a == e0b, - _ => false - } - } - ty_estr(e0a) => { - match (*other) { - ty_estr(e0b) => e0a == e0b, - _ => false - } - } - ty_enum(e0a, ref e1a) => { - match (*other) { - ty_enum(e0b, ref e1b) => e0a == e0b && (*e1a) == (*e1b), - _ => false - } - } - ty_box(e0a) => { - match (*other) { - ty_box(e0b) => e0a == e0b, - _ => false - } - } - ty_uniq(e0a) => { - match (*other) { - ty_uniq(e0b) => e0a == e0b, - _ => false - } - } - ty_evec(e0a, e1a) => { - match (*other) { - ty_evec(e0b, e1b) => e0a == e0b && e1a == e1b, - _ => false - } - } - ty_ptr(e0a) => { - match (*other) { - ty_ptr(e0b) => e0a == e0b, - _ => false - } - } - ty_rptr(e0a, e1a) => { - match (*other) { - ty_rptr(e0b, e1b) => e0a == e0b && e1a == e1b, - _ => false - } - } - ty_rec(e0a) => { - match (/*bad*/copy *other) { - ty_rec(e0b) => e0a == e0b, - _ => false - } - } - ty_fn(ref e0a) => { - match (*other) { - ty_fn(ref e0b) => (*e0a) == (*e0b), - _ => false - } - } - ty_trait(e0a, ref e1a, e2a) => { - match (*other) { - ty_trait(e0b, ref e1b, e2b) => - e0a == e0b && (*e1a) == (*e1b) && e2a == e2b, - _ => false - } - } - ty_struct(e0a, ref e1a) => { - match (*other) { - ty_struct(e0b, ref e1b) => e0a == e0b && (*e1a) == (*e1b), - _ => false - } - } - ty_tup(e0a) => { - match (/*bad*/copy *other) { - ty_tup(e0b) => e0a == e0b, - _ => false - } - } - ty_infer(ref e0a) => { - match (*other) { - ty_infer(ref e0b) => *e0a == *e0b, - _ => false - } - } - ty_err => { - match (*other) { - ty_err => true, - _ => false - } - } - ty_param(e0a) => { - match (*other) { - ty_param(e0b) => e0a == e0b, - _ => false - } - } - ty_self => { - match (*other) { - ty_self => true, - _ => false - } - } - ty_type => { - match (*other) { - ty_type => true, - _ => false - } - } - ty_opaque_box => { - match (*other) { - ty_opaque_box => true, - _ => false - } - } - ty_opaque_closure_ptr(e0a) => { - match (*other) { - ty_opaque_closure_ptr(e0b) => e0a == e0b, - _ => false - } - } - ty_unboxed_vec(e0a) => { - match (*other) { - ty_unboxed_vec(e0b) => e0a == e0b, - _ => false - } - } - } - } - pure fn ne(&self, other: &sty) -> bool { !(*self).eq(other) } -} - impl param_bound : cmp::Eq { pure fn eq(&self, other: ¶m_bound) -> bool { match (*self) { diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 070360ce32f29..0aafeac265aef 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -55,7 +55,7 @@ use core::prelude::*; use middle::pat_util::pat_id_map; -use middle::ty::{FnTyBase, FnMeta, FnSig, arg, field, substs}; +use middle::ty::{arg, field, substs}; use middle::ty::{ty_param_substs_and_ty}; use middle::ty; use middle::typeck::check::fn_ctxt; @@ -70,7 +70,7 @@ use core::vec; use syntax::ast; use syntax::codemap::span; use syntax::print::pprust::path_to_str; -use util::common::indent; +use util::common::indenter; pub trait ast_conv { fn tcx() -> ty::ctxt; @@ -321,13 +321,16 @@ pub fn ast_ty_to_ty( }; ty::mk_rec(tcx, flds) } - ast::ty_fn(f) => { - let bounds = collect::compute_bounds(self.ccx(), f.bounds); - let fn_decl = ty_of_fn_decl(self, rscope, f.proto, - f.purity, f.onceness, - bounds, f.region, f.decl, None, - ast_ty.span); - ty::mk_fn(tcx, fn_decl) + ast::ty_bare_fn(bf) => { + ty::mk_bare_fn(tcx, ty_of_bare_fn(self, rscope, bf.purity, + bf.abi, bf.decl)) + } + ast::ty_closure(f) => { + let fn_decl = ty_of_closure(self, rscope, f.sigil, + f.purity, f.onceness, + f.region, f.decl, None, + ast_ty.span); + ty::mk_closure(tcx, fn_decl) } ast::ty_path(path, id) => { let a_def = match tcx.def_map.find(&id) { @@ -452,71 +455,92 @@ pub fn ty_of_arg( arg {mode: mode, ty: ty} } -pub type expected_tys = Option<{inputs: ~[ty::arg], - output: ty::t}>; +pub fn ty_of_bare_fn( + self: AC, rscope: RS, + purity: ast::purity, + abi: ast::Abi, + decl: ast::fn_decl) -> ty::BareFnTy +{ + debug!("ty_of_fn_decl"); + + // new region names that appear inside of the fn decl are bound to + // that function type + let rb = in_binding_rscope(rscope); + + let input_tys = decl.inputs.map(|a| ty_of_arg(self, rb, *a, None)); + let output_ty = match decl.output.node { + ast::ty_infer => self.ty_infer(decl.output.span), + _ => ast_ty_to_ty(self, rb, decl.output) + }; + + ty::BareFnTy { + purity: purity, + abi: abi, + sig: ty::FnSig {inputs: input_tys, output: output_ty} + } +} -pub fn ty_of_fn_decl( +pub fn ty_of_closure( self: AC, rscope: RS, - ast_proto: ast::Proto, + sigil: ast::Sigil, purity: ast::purity, onceness: ast::Onceness, - bounds: @~[ty::param_bound], opt_region: Option<@ast::region>, decl: ast::fn_decl, - expected_tys: expected_tys, - span: span) -> ty::FnTy { + expected_tys: Option, + span: span) -> ty::ClosureTy +{ debug!("ty_of_fn_decl"); - do indent { - // resolve the function bound region in the original region - // scope `rscope`, not the scope of the function parameters - let bound_region = match opt_region { - Some(region) => { - ast_region_to_region(self, rscope, span, region) - } - None => { - match ast_proto { - ast::ProtoBare | ast::ProtoUniq | ast::ProtoBox => { - // @fn(), ~fn() default to static as the bound - // on their upvars: - ty::re_static - } - ast::ProtoBorrowed => { - // &fn() defaults to an anonymous region: - let r_result = rscope.anon_region(span); - get_region_reporting_err(self.tcx(), span, r_result) - } + let _i = indenter(); + + // resolve the function bound region in the original region + // scope `rscope`, not the scope of the function parameters + let bound_region = match opt_region { + Some(region) => { + ast_region_to_region(self, rscope, span, region) + } + None => { + match sigil { + ast::OwnedSigil | ast::ManagedSigil => { + // @fn(), ~fn() default to static as the bound + // on their upvars: + ty::re_static + } + ast::BorrowedSigil => { + // &fn() defaults to an anonymous region: + let r_result = rscope.anon_region(span); + get_region_reporting_err(self.tcx(), span, r_result) } } - }; + } + }; - // new region names that appear inside of the fn decl are bound to - // that function type - let rb = in_binding_rscope(rscope); - - let input_tys = do decl.inputs.mapi |i, a| { - let expected_arg_ty = do expected_tys.chain_ref |e| { - // no guarantee that the correct number of expected args - // were supplied - if i < e.inputs.len() {Some(e.inputs[i])} else {None} - }; - ty_of_arg(self, rb, *a, expected_arg_ty) - }; + // new region names that appear inside of the fn decl are bound to + // that function type + let rb = in_binding_rscope(rscope); - let expected_ret_ty = expected_tys.map(|e| e.output); - let output_ty = match decl.output.node { - ast::ty_infer if expected_ret_ty.is_some() => expected_ret_ty.get(), - ast::ty_infer => self.ty_infer(decl.output.span), - _ => ast_ty_to_ty(self, rb, decl.output) + let input_tys = do decl.inputs.mapi |i, a| { + let expected_arg_ty = do expected_tys.chain_ref |e| { + // no guarantee that the correct number of expected args + // were supplied + if i < e.inputs.len() {Some(e.inputs[i])} else {None} }; + ty_of_arg(self, rb, *a, expected_arg_ty) + }; - FnTyBase { - meta: FnMeta {purity: purity, - proto: ast_proto, - onceness: onceness, - region: bound_region, - bounds: bounds}, - sig: FnSig {inputs: input_tys, + let expected_ret_ty = expected_tys.map(|e| e.output); + let output_ty = match decl.output.node { + ast::ty_infer if expected_ret_ty.is_some() => expected_ret_ty.get(), + ast::ty_infer => self.ty_infer(decl.output.span), + _ => ast_ty_to_ty(self, rb, decl.output) + }; + + ty::ClosureTy { + purity: purity, + sigil: sigil, + onceness: onceness, + region: bound_region, + sig: ty::FnSig {inputs: input_tys, output: output_ty} - } } } diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index b86f8f26c252b..f5faa968791c5 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -883,7 +883,7 @@ pub impl LookupContext { }) } - ty_trait(*) | ty_fn(*) => { + ty_trait(*) | ty_closure(*) => { // NDM---eventually these should be some variant of autoref None } @@ -906,14 +906,14 @@ pub impl LookupContext { let tcx = self.tcx(); match ty::get(self_ty).sty { - ty_box(*) | ty_uniq(*) | ty_rptr(*) | + ty_bare_fn(*) | ty_box(*) | ty_uniq(*) | ty_rptr(*) | ty_infer(IntVar(_)) | ty_infer(FloatVar(_)) | ty_self | ty_param(*) | ty_nil | ty_bot | ty_bool | ty_int(*) | ty_uint(*) | ty_float(*) | ty_enum(*) | ty_ptr(*) | ty_rec(*) | ty_struct(*) | ty_tup(*) | ty_estr(*) | ty_evec(*) | - ty_trait(*) | ty_fn(*) => { + ty_trait(*) | ty_closure(*) => { self.search_for_some_kind_of_autorefd_method( AutoPtr, autoderefs, [m_const, m_imm, m_mutbl], |m,r| ty::mk_rptr(tcx, r, ty::mt {ty:self_ty, mutbl:m})) @@ -1212,7 +1212,7 @@ pub impl LookupContext { trait_did: def_id, method_num: uint) -> ty::t { let trait_methods = ty::trait_methods(tcx, trait_did); - ty::mk_fn(tcx, /*bad*/copy trait_methods[method_num].fty) + ty::mk_bare_fn(tcx, copy trait_methods[method_num].fty) } } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 1c0881b6ed5bb..074a0a565ae59 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -81,7 +81,7 @@ use core::prelude::*; use middle::const_eval; use middle::pat_util::pat_id_map; use middle::pat_util; -use middle::ty::{TyVid, Vid, FnTyBase, FnMeta, FnSig, VariantInfo_, field}; +use middle::ty::{TyVid, Vid, FnSig, VariantInfo_, field}; use middle::ty::{ty_param_bounds_and_ty, ty_param_substs_and_ty}; use middle::ty::{re_bound, br_cap_avoid, substs, arg, param_ty}; use middle::ty; @@ -90,7 +90,6 @@ use middle::typeck::astconv::{ast_region_to_region, ast_ty_to_ty}; use middle::typeck::astconv; use middle::typeck::check::_match::pat_ctxt; use middle::typeck::check::method::TransformTypeNormally; -use middle::typeck::check::regionmanip::replace_bound_regions_in_fn_ty; use middle::typeck::check::regionmanip::replace_bound_regions_in_fn_sig; use middle::typeck::check::vtable::{LocationInfo, VtableContext}; use middle::typeck::crate_ctxt; @@ -248,8 +247,9 @@ pub fn check_bare_fn(ccx: @crate_ctxt, self_info: Option) { let fty = ty::node_id_to_type(ccx.tcx, id); match ty::get(fty).sty { - ty::ty_fn(ref fn_ty) => { - check_fn(ccx, self_info, fn_ty, decl, body, Vanilla, None) + ty::ty_bare_fn(ref fn_ty) => { + check_fn(ccx, self_info, fn_ty.purity, None, + &fn_ty.sig, decl, body, Vanilla, None) } _ => ccx.tcx.sess.impossible_case(body.span, "check_bare_fn: function type expected") @@ -258,12 +258,14 @@ pub fn check_bare_fn(ccx: @crate_ctxt, pub fn check_fn(ccx: @crate_ctxt, self_info: Option, - fn_ty: &ty::FnTy, + purity: ast::purity, + sigil: Option, + fn_sig: &ty::FnSig, decl: &ast::fn_decl, body: ast::blk, fn_kind: FnKind, - old_fcx: Option<@fn_ctxt>) { - + old_fcx: Option<@fn_ctxt>) +{ let tcx = ccx.tcx; let indirect_ret = match fn_kind { ForLoop => true, _ => false @@ -277,7 +279,7 @@ pub fn check_fn(ccx: @crate_ctxt, let {isr, self_info, fn_sig} = { let old_isr = option::map_default(&old_fcx, @Nil, |fcx| fcx.in_scope_regions); - replace_bound_regions_in_fn_sig(tcx, old_isr, self_info, &fn_ty.sig, + replace_bound_regions_in_fn_sig(tcx, old_isr, self_info, fn_sig, |br| ty::re_free(body.node.id, br)) }; @@ -294,13 +296,10 @@ pub fn check_fn(ccx: @crate_ctxt, // in the case of function expressions, based on the outer context. let fcx: @fn_ctxt = { let (purity, inherited) = match old_fcx { - None => { - (fn_ty.meta.purity, - blank_inherited(ccx)) - } + None => (purity, blank_inherited(ccx)), Some(fcx) => { - (ty::determine_inherited_purity(fcx.purity, fn_ty.meta.purity, - fn_ty.meta.proto), + (ty::determine_inherited_purity(fcx.purity, purity, + sigil.get()), fcx.inh) } }; @@ -1092,8 +1091,9 @@ pub fn check_expr_with_unifier(fcx: @fn_ctxt, in_fty: ty::t, callee_expr: @ast::expr, args: ~[@ast::expr], - deref_args: DerefArgs) -> {fty: ty::t, bot: bool} { - + sugar: ast::CallSugar, + deref_args: DerefArgs) -> (ty::t, bool) + { let tcx = fcx.ccx.tcx; let mut bot = false; @@ -1103,62 +1103,72 @@ pub fn check_expr_with_unifier(fcx: @fn_ctxt, debug!("check_call_inner: before universal quant., in_fty=%s", fcx.infcx().ty_to_str(in_fty)); - let mut formal_tys; + let formal_tys; // This is subtle: we expect `fty` to be a function type, which // normally introduce a level of binding. In this case, we want to // process the types bound by the function but not by any nested // functions. Therefore, we match one level of structure. - let fty = - match structure_of(fcx, sp, in_fty) { - ty::ty_fn(ref fn_ty) => { - let fn_ty = - /*bad*/copy replace_bound_regions_in_fn_ty(tcx, @Nil, - None, fn_ty, |_br| fcx.infcx().next_region_var(sp, - call_expr_id)).fn_ty; - - let supplied_arg_count = args.len(); - - bot |= ty::type_is_bot(fn_ty.sig.output); - - // Grab the argument types, supplying fresh type variables - // if the wrong number of arguments were supplied - let expected_arg_count = fn_ty.sig.inputs.len(); - formal_tys = if expected_arg_count == supplied_arg_count { - fn_ty.sig.inputs.map(|a| a.ty) - } else { - tcx.sess.span_err( - sp, fmt!("this function takes %u parameter%s but \ - %u parameter%s supplied", + let ret_ty = match structure_of(fcx, sp, in_fty) { + ty::ty_bare_fn(ty::BareFnTy {sig: ref sig, _}) | + ty::ty_closure(ty::ClosureTy {sig: ref sig, _}) => { + let {fn_sig: sig, _} = + replace_bound_regions_in_fn_sig( + tcx, @Nil, None, sig, + |_br| fcx.infcx().next_region_var( + sp, call_expr_id)); + + let supplied_arg_count = args.len(); + + bot |= ty::type_is_bot(sig.output); + + // Grab the argument types, supplying fresh type variables + // if the wrong number of arguments were supplied + let expected_arg_count = sig.inputs.len(); + formal_tys = if expected_arg_count == supplied_arg_count { + sig.inputs.map(|a| a.ty) + } else { + let suffix = match sugar { + ast::NoSugar => "", + ast::DoSugar => " (including the closure passed by \ + the `do` keyword)", + ast::ForSugar => " (including the closure passed by \ + the `for` keyword)" + }; + let msg = fmt!("this function takes %u parameter%s but \ + %u parameter%s supplied%s", expected_arg_count, - if expected_arg_count == 1 { - ~"" - } else { - ~"s" - }, + if expected_arg_count == 1 {""} + else {"s"}, supplied_arg_count, - if supplied_arg_count == 1 { - ~" was" - } else { - ~"s were" - })); - fcx.infcx().next_ty_vars(supplied_arg_count) - }; - ty::mk_fn(tcx, fn_ty) - } - _ => { - fcx.type_error_message(sp, |actual| { - fmt!("expected function or foreign function but \ - found `%s`", actual) }, in_fty, None); - // check each arg against "error", in order to set up - // all the node type bindings - formal_tys = args.map(|_x| ty::mk_err(tcx)); - ty::mk_err(tcx) - } - }; + if supplied_arg_count == 1 {" was"} + else {"s were"}, + suffix); - debug!("check_call_inner: after universal quant., fty=%s", - fcx.infcx().ty_to_str(fty)); + tcx.sess.span_err(sp, msg); + + vec::from_fn(expected_arg_count, |_| ty::mk_err(tcx)) + }; + + sig.output + } + + _ => { + fcx.type_error_message(sp, |actual| { + fmt!("expected function or foreign function but \ + found `%s`", actual) }, in_fty, None); + + // check each arg against "error", in order to set up + // all the node type bindings + formal_tys = args.map(|_x| ty::mk_err(tcx)); + ty::mk_err(tcx) + } + }; + + debug!("check_call_inner: after universal quant., \ + formal_tys=%? ret_ty=%s", + formal_tys.map(|t| fcx.infcx().ty_to_str(*t)), + fcx.infcx().ty_to_str(ret_ty)); // Check the arguments. // We do this in a pretty awful way: first we typecheck any arguments @@ -1209,7 +1219,7 @@ pub fn check_expr_with_unifier(fcx: @fn_ctxt, } } - {fty: fty, bot: bot} + (ret_ty, bot) } // A generic function for checking assignment expressions @@ -1233,36 +1243,26 @@ pub fn check_expr_with_unifier(fcx: @fn_ctxt, fn_ty: ty::t, expr: @ast::expr, +args: ~[@ast::expr], - bot: bool) - -> bool { + bot: bool, + sugar: ast::CallSugar) -> bool + { let mut bot = bot; // Call the generic checker. - let fty = { - let r = check_call_inner(fcx, sp, call_expr_id, - fn_ty, expr, args, DontDerefArgs); - bot |= r.bot; - r.fty - }; + let (ret_ty, b) = check_call_inner(fcx, sp, call_expr_id, + fn_ty, expr, args, sugar, + DontDerefArgs); + bot |= b; // Pull the return type out of the type of the function. - match structure_of(fcx, sp, fty) { - ty::ty_fn(ref f) => { - fcx.write_ty(call_expr_id, f.sig.output); - return bot; - } - _ => { - fcx.write_ty(call_expr_id, ty::mk_err(fcx.ccx.tcx)); - fcx.type_error_message(sp, |_actual| { - ~"expected function"}, fty, None); - return bot; - } - } + fcx.write_ty(call_expr_id, ret_ty); + return bot; } // A generic function for doing all of the checking for call expressions fn check_call(fcx: @fn_ctxt, sp: span, call_expr_id: ast::node_id, - f: @ast::expr, +args: ~[@ast::expr]) -> bool { + f: @ast::expr, +args: ~[@ast::expr], + sugar: ast::CallSugar) -> bool { // Index expressions need to be handled separately, to inform them // that they appear in call position. let mut bot = match /*bad*/copy f.node { @@ -1278,7 +1278,8 @@ pub fn check_expr_with_unifier(fcx: @fn_ctxt, fcx.expr_ty(f), f, args, - bot) + bot, + sugar) } // Checks a method call. @@ -1287,7 +1288,8 @@ pub fn check_expr_with_unifier(fcx: @fn_ctxt, rcvr: @ast::expr, method_name: ast::ident, +args: ~[@ast::expr], - tps: ~[@ast::Ty]) + tps: ~[@ast::Ty], + sugar: ast::CallSugar) -> bool { let bot = check_expr(fcx, rcvr); let expr_t = structurally_resolved_type(fcx, @@ -1329,7 +1331,8 @@ pub fn check_expr_with_unifier(fcx: @fn_ctxt, fcx.node_ty(expr.callee_id), expr, args, - bot) + bot, + sugar) } // A generic function for checking for or for-each loops @@ -1378,13 +1381,11 @@ pub fn check_expr_with_unifier(fcx: @fn_ctxt, op_ex.callee_id, opname, self_t, ~[], deref_args) { Some(ref origin) => { - let {fty: method_ty, bot: bot} = { - let method_ty = fcx.node_ty(op_ex.callee_id); - check_call_inner(fcx, op_ex.span, op_ex.id, - method_ty, op_ex, args, deref_args) - }; - fcx.ccx.method_map.insert(op_ex.id, (*origin)); - Some((ty::ty_fn_ret(method_ty), bot)) + let method_ty = fcx.node_ty(op_ex.callee_id); + fcx.ccx.method_map.insert(op_ex.id, *origin); + Some(check_call_inner(fcx, op_ex.span, op_ex.id, + method_ty, op_ex, args, + ast::NoSugar, deref_args)) } _ => None } @@ -1472,13 +1473,14 @@ pub fn check_expr_with_unifier(fcx: @fn_ctxt, // If the or operator is used it might be that the user forgot to // supply the do keyword. Let's be more helpful in that situation. if op == ast::or { - match ty::get(lhs_resolved_t).sty { - ty::ty_fn(_) => { - tcx.sess.span_note( - ex.span, ~"did you forget the `do` keyword for the call?"); + match ty::get(lhs_resolved_t).sty { + ty::ty_bare_fn(_) | ty::ty_closure(_) => { + tcx.sess.span_note( + ex.span, ~"did you forget the `do` keyword \ + for the call?"); + } + _ => () } - _ => () - } } (lhs_resolved_t, false) @@ -1523,7 +1525,7 @@ pub fn check_expr_with_unifier(fcx: @fn_ctxt, fn check_expr_fn(fcx: @fn_ctxt, expr: @ast::expr, - ast_proto_opt: Option, + ast_sigil_opt: Option, decl: &ast::fn_decl, body: ast::blk, fn_kind: FnKind, @@ -1534,50 +1536,44 @@ pub fn check_expr_with_unifier(fcx: @fn_ctxt, // avoid capture of bound regions in the expected type. See // def'n of br_cap_avoid() for a more lengthy explanation of // what's going on here. - // Also try to pick up inferred purity and proto, defaulting + // Also try to pick up inferred purity and sigil, defaulting // to impure and block. Note that we only will use those for // block syntax lambdas; that is, lambdas without explicit - // protos. + // sigils. let expected_sty = unpack_expected(fcx, expected, |x| Some(copy *x)); let (expected_tys, expected_purity, - expected_proto, + expected_sigil, expected_onceness) = { match expected_sty { - Some(ty::ty_fn(ref fn_ty)) => { + Some(ty::ty_closure(ref cenv)) => { let id = expr.id; - let {fn_ty: fn_ty, _} = - replace_bound_regions_in_fn_ty( - tcx, @Nil, None, fn_ty, + let {fn_sig: sig, _} = + replace_bound_regions_in_fn_sig( + tcx, @Nil, None, &cenv.sig, |br| ty::re_bound(ty::br_cap_avoid(id, @br))); - (Some({inputs: /*bad*/copy fn_ty.sig.inputs, - output: fn_ty.sig.output}), - fn_ty.meta.purity, - fn_ty.meta.proto, - fn_ty.meta.onceness) + (Some(sig), cenv.purity, cenv.sigil, cenv.onceness) } _ => { - (None, ast::impure_fn, ast::ProtoBorrowed, ast::Many) + (None, ast::impure_fn, ast::BorrowedSigil, ast::Many) } } }; // If the proto is specified, use that, otherwise select a // proto based on inference. - let (proto, purity) = match ast_proto_opt { + let (sigil, purity) = match ast_sigil_opt { Some(p) => (p, ast::impure_fn), - None => (expected_proto, expected_purity) + None => (expected_sigil, expected_purity) }; // construct the function type - let mut fn_ty = astconv::ty_of_fn_decl( + let mut fn_ty = astconv::ty_of_closure( fcx, fcx, - proto, purity, expected_onceness, - /*bounds:*/ @~[], /*opt_region:*/ None, - *decl, expected_tys, expr.span); + sigil, purity, expected_onceness, + None, *decl, expected_tys, expr.span); - // XXX: Bad copy. - let fty = ty::mk_fn(tcx, copy fn_ty); + let fty = ty::mk_closure(tcx, copy fn_ty); debug!("check_expr_fn_with_unifier %s fty=%s", fcx.expr_to_str(expr), @@ -1587,8 +1583,8 @@ pub fn check_expr_with_unifier(fcx: @fn_ctxt, // We inherit the same self info as the enclosing scope, // since the function we're checking might capture `self` - check_fn(fcx.ccx, fcx.self_info, &fn_ty, decl, body, - fn_kind, Some(fcx)); + check_fn(fcx.ccx, fcx.self_info, fn_ty.purity, Some(fn_ty.sigil), + &fn_ty.sig, decl, body, fn_kind, Some(fcx)); } @@ -1913,6 +1909,119 @@ pub fn check_expr_with_unifier(fcx: @fn_ctxt, return bot; } + fn check_loop_body(fcx: @fn_ctxt, + expr: @ast::expr, + expected: Option, + loop_body: @ast::expr) + { + // a loop body is the special argument to a `for` loop. We know that + // there will be an expected type in this context because it can only + // appear in the context of a call, so we get the expected type of the + // parameter. The catch here is that we need to validate two things: + // 1. a closure that returns a bool is expected + // 2. the closure that was given returns unit + let tcx = fcx.tcx(); + let mut err_happened = false; + let expected_sty = unpack_expected(fcx, expected, |x| Some(copy *x)); + let inner_ty = match expected_sty { + Some(ty::ty_closure(ref fty)) => { + match fcx.mk_subty(false, expr.span, + fty.sig.output, ty::mk_bool(tcx)) { + result::Ok(_) => { + ty::mk_closure(tcx, ty::ClosureTy { + sig: FnSig {output: ty::mk_nil(tcx), + ..copy fty.sig}, + ..copy *fty + }) + } + result::Err(_) => { + fcx.type_error_message( + expr.span, + |actual| { + let did_you_mean = { + if ty::type_is_nil(fty.sig.output) { + "\nDid you mean to use \ + `do` instead of `for`?" + } else { + "" + } + }; + fmt!("A `for` loop iterator should expect a \ + closure that returns `bool`. This \ + iterator expects a closure that \ + returns `%s`.%s", + actual, did_you_mean) + }, + fty.sig.output, + None); + err_happened = true; + + // Kind of a hack: create a function type with + // the result replaced with ty_err, to + // suppress derived errors. + let t = ty::replace_closure_return_type( + tcx, ty::mk_closure(tcx, copy *fty), + ty::mk_err(tcx)); + fcx.write_ty(expr.id, ty::mk_err(tcx)); + t + } + } + } + _ => { + match expected { + Some(expected_t) => { + fcx.type_error_message( + expr.span, + |actual| { + fmt!("last argument in `for` call \ + has non-closure type: %s", + actual) + }, + expected_t, None); + let err_ty = ty::mk_err(tcx); + fcx.write_ty(expr.id, err_ty); + err_happened = true; + err_ty + } + None => fcx.tcx().sess.impossible_case( + expr.span, + ~"loop body must have an expected type") + } + } + }; + + match loop_body.node { + ast::expr_fn_block(ref decl, ref body) => { + // If an error occurred, we pretend this isn't a for + // loop, so as to assign types to all nodes while also + // propagating ty_err throughout so as to suppress + // derived errors. If we passed in ForLoop in the + // error case, we'd potentially emit a spurious error + // message because of the indirect_ret_ty. + let fn_kind = if err_happened {Vanilla} else {ForLoop}; + check_expr_fn(fcx, loop_body, None, + decl, *body, fn_kind, Some(inner_ty)); + demand::suptype(fcx, loop_body.span, + inner_ty, fcx.expr_ty(loop_body)); + } + ref n => { + die!(fmt!( + "check_loop_body expected expr_fn_block, not %?", n)) + } + } + + let block_ty = structurally_resolved_type( + fcx, expr.span, fcx.node_ty(loop_body.id)); + if err_happened { + fcx.write_ty(expr.id, ty::mk_err(fcx.tcx())); + } else { + let loop_body_ty = + ty::replace_closure_return_type( + tcx, block_ty, ty::mk_bool(tcx)); + fcx.write_ty(expr.id, loop_body_ty); + } + } + let tcx = fcx.ccx.tcx; let id = expr.id; let mut bot = false; @@ -2153,121 +2262,38 @@ pub fn check_expr_with_unifier(fcx: @fn_ctxt, ast::expr_match(discrim, ref arms) => { bot = _match::check_match(fcx, expr, discrim, (/*bad*/copy *arms)); } - ast::expr_fn(proto, ref decl, ref body, _) => { - check_expr_fn(fcx, expr, Some(proto), + ast::expr_fn(sigil, ref decl, ref body, _) => { + check_expr_fn(fcx, expr, Some(sigil), decl, (*body), Vanilla, expected); } ast::expr_fn_block(ref decl, ref body) => { check_expr_fn(fcx, expr, None, decl, (*body), Vanilla, expected); } - ast::expr_loop_body(b) => { - // a loop body is the special argument to a `for` loop. We know that - // there will be an expected type in this context because it can only - // appear in the context of a call, so we get the expected type of the - // parameter. The catch here is that we need to validate two things: - // 1. a closure that returns a bool is expected - // 2. the closure that was given returns unit - let mut err_happened = false; - let expected_sty = unpack_expected(fcx, expected, |x| Some(copy *x)); - let inner_ty = match expected_sty { - Some(ty::ty_fn(ref fty)) => { - match fcx.mk_subty(false, expr.span, - (*fty).sig.output, ty::mk_bool(tcx)) { - result::Ok(_) => - ty::mk_fn(tcx, FnTyBase { - meta: (*fty).meta, - sig: FnSig {output: ty::mk_nil(tcx), - ../*bad*/copy (*fty).sig} - }), - result::Err(_) => { - fcx.type_error_message(expr.span, - |actual| { - fmt!("A `for` loop iterator should expect a \ - closure that returns `bool`. This iterator \ - expects a closure that returns `%s`. %s", - actual, if ty::type_is_nil((*fty).sig.output) { - "\nDid you mean to use `do` instead of \ - `for`?" } else { "" } ) - }, - (*fty).sig.output, None); - err_happened = true; - // Kind of a hack: create a function type with the result - // replaced with ty_err, to suppress derived errors. - let t = ty::replace_fn_return_type(tcx, ty::mk_fn(tcx, - copy *fty), - ty::mk_err(tcx)); - fcx.write_ty(id, ty::mk_err(tcx)); - t - } - } - } - _ => - match expected { - Some(expected_t) => { - fcx.type_error_message(expr.span, |actual| { - fmt!("a `loop` function's last \ - argument should be of function \ - type, not `%s`", - actual) - }, - expected_t, None); - let err_ty = ty::mk_err(tcx); - fcx.write_ty(id, err_ty); - err_happened = true; - err_ty - } - None => fcx.tcx().sess.impossible_case(expr.span, - ~"loop body must have an expected type") - } - }; - match b.node { - ast::expr_fn_block(ref decl, ref body) => { - // If an error occurred, we pretend this isn't a for - // loop, so as to assign types to all nodes while also - // propagating ty_err throughout so as to suppress - // derived errors. If we passed in ForLoop in the - // error case, we'd potentially emit a spurious error - // message because of the indirect_ret_ty. - let fn_kind = if err_happened { Vanilla } - else { ForLoop }; - check_expr_fn(fcx, b, None, - decl, *body, fn_kind, Some(inner_ty)); - demand::suptype(fcx, b.span, inner_ty, fcx.expr_ty(b)); - } - // argh - _ => die!(~"expr_fn_block") - } - let block_ty = structurally_resolved_type( - fcx, expr.span, fcx.node_ty(b.id)); - if err_happened { - fcx.write_ty(expr.id, ty::mk_err(fcx.tcx())); - } else { - let loop_body_ty = ty::replace_fn_return_type(tcx, block_ty, - ty::mk_bool(tcx)); - fcx.write_ty(expr.id, loop_body_ty); - } + ast::expr_loop_body(loop_body) => { + check_loop_body(fcx, expr, expected, loop_body); } ast::expr_do_body(b) => { let expected_sty = unpack_expected(fcx, expected, |x| Some(copy *x)); let inner_ty = match expected_sty { - Some(ty::ty_fn(ref fty)) => { - ty::mk_fn(tcx, (/*bad*/copy *fty)) - } - _ => match expected { - Some(expected_t) => { - fcx.type_error_message(expr.span, |_actual| { - ~"Non-function passed to a `do` \ - function as its last argument, or wrong number \ - of arguments passed to a `do` function" - }, expected_t, None); - let err_ty = ty::mk_err(tcx); - fcx.write_ty(id, err_ty); - err_ty - } - None => fcx.tcx().sess.impossible_case(expr.span, - ~"do body must have expected type") - } + Some(ty::ty_closure(_)) => expected.get(), + _ => match expected { + Some(expected_t) => { + fcx.type_error_message(expr.span, |actual| { + fmt!("last argument in `do` call \ + has non-closure type: %s", + actual) + }, expected_t, None); + let err_ty = ty::mk_err(tcx); + fcx.write_ty(id, err_ty); + err_ty + } + None => { + fcx.tcx().sess.impossible_case( + expr.span, + ~"do body must have expected type") + } + } }; match b.node { ast::expr_fn_block(ref decl, ref body) => { @@ -2290,11 +2316,11 @@ pub fn check_expr_with_unifier(fcx: @fn_ctxt, }; fcx.write_ty(id, typ); } - ast::expr_call(f, args, _) => { - bot = check_call(fcx, expr.span, expr.id, f, args); + ast::expr_call(f, args, sugar) => { + bot = check_call(fcx, expr.span, expr.id, f, args, sugar); } - ast::expr_method_call(rcvr, ident, tps, args, _) => { - bot = check_method_call(fcx, expr, rcvr, ident, args, tps); + ast::expr_method_call(rcvr, ident, tps, args, sugar) => { + bot = check_method_call(fcx, expr, rcvr, ident, args, tps, sugar); } ast::expr_cast(e, t) => { bot = check_expr(fcx, e); @@ -3088,20 +3114,18 @@ pub fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) { arg(ast::by_ref, visitor_trait)], ty::mk_nil(tcx)) } ~"frame_address" => { - let fty = ty::mk_fn(ccx.tcx, FnTyBase { - meta: FnMeta {purity: ast::impure_fn, - proto: ast::ProtoBorrowed, - onceness: ast::Once, - region: ty::re_bound(ty::br_anon(0)), - bounds: @~[]}, - sig: FnSig { - inputs: ~[arg { - mode: ast::expl(ast::by_val), - ty: ty::mk_imm_ptr( - ccx.tcx, - ty::mk_mach_uint(ccx.tcx, ast::ty_u8)) - }], - output: ty::mk_nil(ccx.tcx)} + let fty = ty::mk_closure(ccx.tcx, ty::ClosureTy { + purity: ast::impure_fn, + sigil: ast::BorrowedSigil, + onceness: ast::Once, + region: ty::re_bound(ty::br_anon(0)), + sig: ty::FnSig { + inputs: ~[arg {mode: ast::expl(ast::by_val), + ty: ty::mk_imm_ptr( + ccx.tcx, + ty::mk_mach_uint(ccx.tcx, ast::ty_u8))}], + output: ty::mk_nil(ccx.tcx) + } }); (0u, ~[arg(ast::by_ref, fty)], ty::mk_nil(tcx)) } @@ -3324,12 +3348,9 @@ pub fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) { return; } }; - let fty = ty::mk_fn(tcx, FnTyBase { - meta: FnMeta {purity: ast::unsafe_fn, - proto: ast::ProtoBare, - onceness: ast::Many, - region: ty::re_static, - bounds: @~[]}, + let fty = ty::mk_bare_fn(tcx, ty::BareFnTy { + purity: ast::unsafe_fn, + abi: ast::RustAbi, sig: FnSig {inputs: inputs, output: output} }); diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index 952c1a9fcd887..9dfaaeebc8fd9 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -32,7 +32,7 @@ use core::prelude::*; use middle::freevars::get_freevars; use middle::pat_util::{pat_bindings, pat_is_binding}; use middle::ty::{encl_region, re_scope}; -use middle::ty::{ty_fn_proto, vstore_box, vstore_fixed, vstore_slice}; +use middle::ty::{vstore_box, vstore_fixed, vstore_slice}; use middle::ty::{vstore_uniq}; use middle::ty; use middle::typeck::check::fn_ctxt; @@ -42,7 +42,7 @@ use middle::typeck::infer::{resolve_type}; use util::ppaux::{note_and_explain_region, ty_to_str}; use core::result; -use syntax::ast::{ProtoBare, ProtoBox, ProtoUniq, ProtoBorrowed}; +use syntax::ast::{ManagedSigil, OwnedSigil, BorrowedSigil}; use syntax::ast::{def_arg, def_binding, def_local, def_self, def_upvar}; use syntax::ast; use syntax::codemap::span; @@ -59,10 +59,9 @@ pub fn encl_region_of_def(fcx: @fn_ctxt, def: ast::def) -> ty::Region { def_self(node_id, _) | def_binding(node_id, _) => return encl_region(tcx, node_id), def_upvar(_, subdef, closure_id, body_id) => { - match ty_fn_proto(fcx.node_ty(closure_id)) { - ProtoBare => tcx.sess.bug(~"ProtoBare with upvars?!"), - ProtoBorrowed => encl_region_of_def(fcx, *subdef), - ProtoBox | ProtoUniq => re_scope(body_id) + match ty::ty_closure_sigil(fcx.node_ty(closure_id)) { + BorrowedSigil => encl_region_of_def(fcx, *subdef), + ManagedSigil | OwnedSigil => re_scope(body_id) } } _ => { @@ -278,11 +277,9 @@ pub fn visit_expr(expr: @ast::expr, &&rcx: @rcx, v: rvt) { ast::expr_fn(*) | ast::expr_fn_block(*) => { let function_type = rcx.resolve_node_type(expr.id); match ty::get(function_type).sty { - ty::ty_fn(ref fn_ty) => { - if fn_ty.meta.proto == ast::ProtoBorrowed { - constrain_free_variables( - rcx, fn_ty.meta.region, expr); - } + ty::ty_closure(ty::ClosureTy {sigil: ast::BorrowedSigil, + region: region, _}) => { + constrain_free_variables(rcx, region, expr); } _ => () } diff --git a/src/librustc/middle/typeck/check/regionmanip.rs b/src/librustc/middle/typeck/check/regionmanip.rs index 8ea35824e32a1..f0956df545c41 100644 --- a/src/librustc/middle/typeck/check/regionmanip.rs +++ b/src/librustc/middle/typeck/check/regionmanip.rs @@ -12,7 +12,6 @@ use core::prelude::*; -use middle::ty::{FnTyBase}; use middle::ty; use middle::typeck::check::self_info; use middle::typeck::isr_alist; @@ -27,22 +26,6 @@ use syntax::print::pprust::{expr_to_str}; // Helper functions related to manipulating region types. -pub fn replace_bound_regions_in_fn_ty( - tcx: ty::ctxt, - isr: isr_alist, - self_info: Option, - fn_ty: &ty::FnTy, - mapf: fn(ty::bound_region) -> ty::Region) -> - {isr: isr_alist, self_info: Option, fn_ty: ty::FnTy} { - let {isr, self_info, fn_sig} = - replace_bound_regions_in_fn_sig( - tcx, isr, self_info, &fn_ty.sig, mapf); - {isr: isr, - self_info: self_info, - fn_ty: FnTyBase {meta: fn_ty.meta, - sig: fn_sig}} -} - pub fn replace_bound_regions_in_fn_sig( tcx: ty::ctxt, isr: isr_alist, diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs index 9f2af3ec003cd..abd4697eb31a8 100644 --- a/src/librustc/middle/typeck/check/vtable.rs +++ b/src/librustc/middle/typeck/check/vtable.rs @@ -233,7 +233,7 @@ pub fn lookup_vtable(vcx: &VtableContext, relate_trait_tys(vcx, location_info, trait_ty, ty); if !allow_unsafe && !is_early { for vec::each(*ty::trait_methods(tcx, did)) |m| { - if ty::type_has_self(ty::mk_fn(tcx, /*bad*/copy m.fty)) { + if ty::type_has_self(ty::mk_bare_fn(tcx, copy m.fty)) { tcx.sess.span_err( location_info.span, ~"a boxed trait with self types may not be \ diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index 324cdcc261fec..8fc8c4f6cbb8d 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -26,10 +26,10 @@ use middle::resolve::{Impl, MethodInfo}; use middle::ty::{ProvidedMethodSource, ProvidedMethodInfo, bound_copy, get}; use middle::ty::{kind_can_be_copied, lookup_item_type, param_bounds, subst}; use middle::ty::{substs, t, ty_bool, ty_bot, ty_box, ty_enum, ty_err}; -use middle::ty::{ty_estr, ty_evec, ty_float, ty_fn, ty_infer, ty_int, ty_nil}; +use middle::ty::{ty_estr, ty_evec, ty_float, ty_infer, ty_int, ty_nil}; use middle::ty::{ty_opaque_box, ty_param, ty_param_bounds_and_ty, ty_ptr}; use middle::ty::{ty_rec, ty_rptr, ty_self, ty_struct, ty_trait, ty_tup}; -use middle::ty::{ty_type, ty_uint, ty_uniq}; +use middle::ty::{ty_type, ty_uint, ty_uniq, ty_bare_fn, ty_closure}; use middle::ty::{ty_opaque_closure_ptr, ty_unboxed_vec, type_kind_ext}; use middle::ty::{type_is_ty_var}; use middle::ty; @@ -108,7 +108,7 @@ pub fn get_base_type(inference_context: @InferCtxt, ty_nil | ty_bot | ty_bool | ty_int(*) | ty_uint(*) | ty_float(*) | ty_estr(*) | ty_evec(*) | ty_rec(*) | - ty_fn(*) | ty_tup(*) | ty_infer(*) | + ty_bare_fn(*) | ty_closure(*) | ty_tup(*) | ty_infer(*) | ty_param(*) | ty_self | ty_type | ty_opaque_box | ty_opaque_closure_ptr(*) | ty_unboxed_vec(*) | ty_err => { debug!("(getting base type) no base type; found %?", diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index b7b7899883b76..120fd89e5ebdf 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -33,10 +33,10 @@ are represented as `ty_param()` instances. use core::prelude::*; use metadata::csearch; -use middle::ty::{FnMeta, FnSig, FnTyBase, InstantiatedTraitRef, arg}; +use middle::ty::{InstantiatedTraitRef, arg}; use middle::ty::{substs, ty_param_substs_and_ty}; use middle::ty; -use middle::typeck::astconv::{ast_conv, ty_of_fn_decl, ty_of_arg}; +use middle::typeck::astconv::{ast_conv, ty_of_arg}; use middle::typeck::astconv::{ast_ty_to_ty}; use middle::typeck::astconv; use middle::typeck::infer; @@ -153,9 +153,10 @@ pub impl @crate_ctxt: ast_conv { pub fn get_enum_variant_types(ccx: @crate_ctxt, enum_ty: ty::t, - variants: ~[ast::variant], - ty_params: ~[ast::ty_param], - rp: Option) { + variants: &[ast::variant], + ty_params: &[ast::ty_param], + rp: Option) +{ let tcx = ccx.tcx; // Create a set of parameter types shared among all the variants. @@ -166,58 +167,35 @@ pub fn get_enum_variant_types(ccx: @crate_ctxt, match variant.node.kind { ast::tuple_variant_kind(ref args) if args.len() > 0 => { let rs = type_rscope(rp); - let args = args.map(|va| { - let arg_ty = ccx.to_ty(rs, va.ty); - arg { mode: ast::expl(ast::by_copy), ty: arg_ty } - }); - result_ty = Some(ty::mk_fn(tcx, FnTyBase { - meta: FnMeta {purity: ast::pure_fn, - proto: ast::ProtoBare, - onceness: ast::Many, - bounds: @~[], - region: ty::re_static}, - sig: FnSig {inputs: args, - output: enum_ty} - })); + let input_tys = args.map(|va| ccx.to_ty(rs, va.ty)); + result_ty = Some(ty::mk_ctor_fn(tcx, input_tys, enum_ty)); } + ast::tuple_variant_kind(_) => { result_ty = Some(enum_ty); } + ast::struct_variant_kind(struct_def) => { - // XXX: Merge with computation of the the same value below? - let tpt = { - bounds: ty_param_bounds(ccx, /*bad*/copy ty_params), - region_param: rp, - ty: enum_ty - }; - convert_struct( - ccx, - rp, - struct_def, - /*bad*/copy ty_params, - tpt, - variant.node.id); - // Compute the ctor arg types from the struct fields - let struct_fields = do struct_def.fields.map |struct_field| { - arg { - mode: ast::expl(ast::by_val), - ty: ty::node_id_to_type(ccx.tcx, struct_field.node.id) - } - }; - result_ty = Some(ty::mk_fn(tcx, FnTyBase { - meta: FnMeta {purity: ast::pure_fn, - proto: ast::ProtoBare, - onceness: ast::Many, - bounds: @~[], - region: ty::re_static}, - sig: FnSig {inputs: struct_fields, output: enum_ty }})); + let tpt = {bounds: ty_param_bounds(ccx, ty_params), + region_param: rp, + ty: enum_ty}; + + convert_struct(ccx, + rp, + struct_def, + ty_params.to_vec(), + tpt, + variant.node.id); + + let input_tys = struct_def.fields.map( + |f| ty::node_id_to_type(ccx.tcx, f.node.id)); + result_ty = Some(ty::mk_ctor_fn(tcx, input_tys, enum_ty)); } + ast::enum_variant_kind(ref enum_definition) => { - get_enum_variant_types(ccx, - enum_ty, - /*bad*/copy enum_definition.variants, - /*bad*/copy ty_params, - rp); + get_enum_variant_types(ccx, enum_ty, + enum_definition.variants, + ty_params, rp); result_ty = None; } }; @@ -225,11 +203,9 @@ pub fn get_enum_variant_types(ccx: @crate_ctxt, match result_ty { None => {} Some(result_ty) => { - let tpt = { - bounds: ty_param_bounds(ccx, /*bad*/copy ty_params), - region_param: rp, - ty: result_ty - }; + let tpt = {bounds: ty_param_bounds(ccx, ty_params), + region_param: rp, + ty: result_ty}; tcx.tcache.insert(local_def(variant.node.id), tpt); write_ty_to_tcx(tcx, variant.node.id, result_ty); } @@ -279,7 +255,7 @@ pub fn ensure_trait_methods(ccx: @crate_ctxt, }; let ty = ty::subst(ccx.tcx, &substs, - ty::mk_fn(ccx.tcx, /*bad*/copy m.fty)); + ty::mk_bare_fn(ccx.tcx, copy m.fty)); let bounds = @(*trait_bounds + ~[@~[ty::bound_trait(trait_ty)]] + *m.tps); ccx.tcx.tcache.insert(local_def(am.id), @@ -305,7 +281,7 @@ pub fn ensure_trait_methods(ccx: @crate_ctxt, ast::provided(method) => def_id = local_def(method.id) } - let trait_bounds = ty_param_bounds(ccx, copy *params); + let trait_bounds = ty_param_bounds(ccx, *params); let ty_m = trait_method_to_ty_method(*m); let method_ty = ty_of_ty_method(ccx, ty_m, region_paramd, def_id); if ty_m.self_ty.node == ast::sty_static { @@ -458,7 +434,7 @@ pub fn compare_impl_method(tcx: ty::ctxt, // that correspond to the parameters we will find on the impl // - replace self region with a fresh, dummy region let impl_fty = { - let impl_fty = ty::mk_fn(tcx, /*bad*/copy impl_m.fty); + let impl_fty = ty::mk_bare_fn(tcx, copy impl_m.fty); debug!("impl_fty (pre-subst): %s", ppaux::ty_to_str(tcx, impl_fty)); replace_bound_self(tcx, impl_fty, dummy_self_r) }; @@ -476,7 +452,7 @@ pub fn compare_impl_method(tcx: ty::ctxt, self_ty: Some(self_ty), tps: vec::append(trait_tps, dummy_tps) }; - let trait_fty = ty::mk_fn(tcx, /*bad*/copy trait_m.fty); + let trait_fty = ty::mk_bare_fn(tcx, copy trait_m.fty); debug!("trait_fty (pre-subst): %s", ppaux::ty_to_str(tcx, trait_fty)); ty::subst(tcx, &substs, trait_fty) }; @@ -583,9 +559,9 @@ pub fn convert_methods(ccx: @crate_ctxt, let tcx = ccx.tcx; do vec::map(ms) |m| { - let bounds = ty_param_bounds(ccx, /*bad*/copy m.tps); + let bounds = ty_param_bounds(ccx, m.tps); let mty = ty_of_method(ccx, *m, rp); - let fty = ty::mk_fn(tcx, /*bad*/copy mty.fty); + let fty = ty::mk_bare_fn(tcx, copy mty.fty); tcx.tcache.insert( local_def(m.id), @@ -626,13 +602,11 @@ pub fn convert(ccx: @crate_ctxt, it: @ast::item) { ensure_no_ty_param_bounds(ccx, it.span, *ty_params, "enumeration"); let tpt = ty_of_item(ccx, it); write_ty_to_tcx(tcx, it.id, tpt.ty); - get_enum_variant_types(ccx, - tpt.ty, - /*bad*/copy (*enum_definition).variants, - /*bad*/copy *ty_params, rp); + get_enum_variant_types(ccx, tpt.ty, enum_definition.variants, + *ty_params, rp); } ast::item_impl(ref tps, trait_ref, selfty, ref ms) => { - let i_bounds = ty_param_bounds(ccx, /*bad*/copy *tps); + let i_bounds = ty_param_bounds(ccx, *tps); let selfty = ccx.to_ty(type_rscope(rp), selfty); write_ty_to_tcx(tcx, it.id, selfty); tcx.tcache.insert(local_def(it.id), @@ -695,13 +669,12 @@ pub fn convert_struct(ccx: @crate_ctxt, do option::iter(&struct_def.dtor) |dtor| { // Write the dtor type - let t_dtor = ty::mk_fn( + let t_dtor = ty::mk_bare_fn( tcx, - ty_of_fn_decl( - ccx, type_rscope(rp), ast::ProtoBare, - ast::impure_fn, ast::Many, - /*bounds:*/ @~[], /*opt_region:*/ None, - ast_util::dtor_dec(), None, dtor.span)); + astconv::ty_of_bare_fn( + ccx, type_rscope(rp), + ast::impure_fn, ast::RustAbi, + ast_util::dtor_dec())); write_ty_to_tcx(tcx, dtor.node.id, t_dtor); tcx.tcache.insert(local_def(dtor.node.id), {bounds: tpt.bounds, @@ -727,25 +700,11 @@ pub fn convert_struct(ccx: @crate_ctxt, tcx.tcache.insert(local_def(ctor_id), tpt); } else if struct_def.fields[0].node.kind == ast::unnamed_field { // Tuple-like. - let ctor_fn_ty = ty::mk_fn(tcx, FnTyBase { - meta: FnMeta { - purity: ast::pure_fn, - proto: ast::ProtoBare, - onceness: ast::Many, - bounds: @~[], - region: ty::re_static - }, - sig: FnSig { - inputs: do struct_def.fields.map |field| { - arg { - mode: ast::expl(ast::by_copy), - ty: ccx.tcx.tcache.get - (&local_def(field.node.id)).ty - } - }, - output: selfty - } - }); + let inputs = + struct_def.fields.map( + |field| ccx.tcx.tcache.get( + &local_def(field.node.id)).ty); + let ctor_fn_ty = ty::mk_ctor_fn(tcx, inputs, selfty); write_ty_to_tcx(tcx, ctor_id, ctor_fn_ty); tcx.tcache.insert(local_def(ctor_id), { bounds: tpt.bounds, @@ -770,11 +729,9 @@ pub fn ty_of_method(ccx: @crate_ctxt, m: @ast::method, rp: Option) -> ty::method { {ident: m.ident, - tps: ty_param_bounds(ccx, /*bad*/copy m.tps), - fty: ty_of_fn_decl(ccx, type_rscope(rp), ast::ProtoBare, - m.purity, ast::Many, - /*bounds:*/ @~[], /*opt_region:*/ None, - m.decl, None, m.span), + tps: ty_param_bounds(ccx, m.tps), + fty: astconv::ty_of_bare_fn(ccx, type_rscope(rp), m.purity, + ast::RustAbi, m.decl), self_ty: m.self_ty.node, vis: m.vis, def_id: local_def(m.id)} @@ -785,11 +742,9 @@ pub fn ty_of_ty_method(self: @crate_ctxt, rp: Option, id: ast::def_id) -> ty::method { {ident: m.ident, - tps: ty_param_bounds(self, /*bad*/copy m.tps), - fty: ty_of_fn_decl(self, type_rscope(rp), ast::ProtoBare, - m.purity, ast::Many, - /*bounds:*/ @~[], /*opt_region:*/ None, - m.decl, None, m.span), + tps: ty_param_bounds(self, m.tps), + fty: astconv::ty_of_bare_fn(self, type_rscope(rp), m.purity, + ast::RustAbi, m.decl), // assume public, because this is only invoked on trait methods self_ty: m.self_ty.node, vis: ast::public, @@ -844,13 +799,11 @@ pub fn ty_of_item(ccx: @crate_ctxt, it: @ast::item) } ast::item_fn(decl, purity, tps, _) => { let bounds = ty_param_bounds(ccx, tps); - let tofd = ty_of_fn_decl(ccx, empty_rscope, - ast::ProtoBare, purity, ast::Many, - /*bounds:*/ @~[], /*opt_region:*/ None, - decl, None, it.span); + let tofd = astconv::ty_of_bare_fn(ccx, empty_rscope, purity, + ast::RustAbi, decl); let tpt = {bounds: bounds, region_param: None, - ty: ty::mk_fn(ccx.tcx, tofd)}; + ty: ty::mk_bare_fn(ccx.tcx, tofd)}; debug!("type of %s (id %d) is %s", tcx.sess.str_of(it.ident), it.id, @@ -976,7 +929,7 @@ pub fn compute_bounds(ccx: @crate_ctxt, } pub fn ty_param_bounds(ccx: @crate_ctxt, - params: ~[ast::ty_param]) -> @~[ty::param_bounds] { + params: &[ast::ty_param]) -> @~[ty::param_bounds] { @do params.map |param| { match ccx.tcx.ty_param_bounds.find(¶m.id) { Some(bs) => bs, @@ -999,15 +952,13 @@ pub fn ty_of_foreign_fn_decl(ccx: @crate_ctxt, let input_tys = decl.inputs.map(|a| ty_of_arg(ccx, rb, *a, None) ); let output_ty = ast_ty_to_ty(ccx, rb, decl.output); - let t_fn = ty::mk_fn(ccx.tcx, FnTyBase { - meta: FnMeta {purity: ast::unsafe_fn, - onceness: ast::Many, - proto: ast::ProtoBare, - bounds: @~[], - region: ty::re_static}, - sig: FnSig {inputs: input_tys, - output: output_ty} - }); + let t_fn = ty::mk_bare_fn( + ccx.tcx, + ty::BareFnTy { + abi: ast::RustAbi, + purity: ast::unsafe_fn, + sig: ty::FnSig {inputs: input_tys, output: output_ty} + }); let tpt = {bounds: bounds, region_param: None, ty: t_fn}; ccx.tcx.tcache.insert(def_id, tpt); return tpt; @@ -1017,8 +968,7 @@ pub fn mk_ty_params(ccx: @crate_ctxt, atps: ~[ast::ty_param]) -> {bounds: @~[ty::param_bounds], params: ~[ty::t]} { let mut i = 0u; - // XXX: Bad copy. - let bounds = ty_param_bounds(ccx, copy atps); + let bounds = ty_param_bounds(ccx, atps); {bounds: bounds, params: vec::map(atps, |atp| { let t = ty::mk_param(ccx.tcx, i, local_def(atp.id)); diff --git a/src/librustc/middle/typeck/infer/coercion.rs b/src/librustc/middle/typeck/infer/coercion.rs index f0fe2deffdfa8..5d291fdde77b3 100644 --- a/src/librustc/middle/typeck/infer/coercion.rs +++ b/src/librustc/middle/typeck/infer/coercion.rs @@ -69,7 +69,7 @@ use core::prelude::*; use middle::ty::{TyVar, AutoPtr, AutoBorrowVec, AutoBorrowFn}; use middle::ty::{AutoAdjustment, AutoRef}; use middle::ty::{vstore_slice, vstore_box, vstore_uniq, vstore_fixed}; -use middle::ty::{FnMeta, FnTyBase, mt}; +use middle::ty::{mt}; use middle::ty; use middle::typeck::infer::{CoerceResult, resolve_type}; use middle::typeck::infer::combine::CombineFields; @@ -117,7 +117,7 @@ impl Coerce { }; } - ty::ty_fn(ref b_f) if b_f.meta.proto == ast::ProtoBorrowed => { + ty::ty_closure(ty::ClosureTy {sigil: ast::BorrowedSigil, _}) => { return do self.unpack_actual_value(a) |sty_a| { self.coerce_borrowed_fn(a, sty_a, b) }; @@ -134,7 +134,7 @@ impl Coerce { do self.unpack_actual_value(a) |sty_a| { match *sty_a { - ty::ty_fn(ref a_f) if a_f.meta.proto == ast::ProtoBare => { + ty::ty_bare_fn(ref a_f) => { // Bare functions are coercable to any closure type. // // FIXME(#3320) this should go away and be @@ -289,9 +289,9 @@ impl Coerce { b.inf_str(self.infcx)); let fn_ty = match *sty_a { - ty::ty_fn(ref f) if f.meta.proto == ast::ProtoBox => {f} - ty::ty_fn(ref f) if f.meta.proto == ast::ProtoUniq => {f} - ty::ty_fn(ref f) if f.meta.proto == ast::ProtoBare => { + ty::ty_closure(ref f) if f.sigil == ast::ManagedSigil => copy *f, + ty::ty_closure(ref f) if f.sigil == ast::OwnedSigil => copy *f, + ty::ty_bare_fn(ref f) => { return self.coerce_from_bare_fn(a, f, b); } _ => { @@ -300,12 +300,13 @@ impl Coerce { }; let r_borrow = self.infcx.next_region_var_nb(self.span); - let meta = FnMeta {proto: ast::ProtoBorrowed, - region: r_borrow, - ..fn_ty.meta}; - let a_borrowed = ty::mk_fn(self.infcx.tcx, - FnTyBase {meta: meta, - sig: copy fn_ty.sig}); + let a_borrowed = ty::mk_closure( + self.infcx.tcx, + ty::ClosureTy { + sigil: ast::BorrowedSigil, + region: r_borrow, + ..fn_ty + }); if_ok!(self.subtype(a_borrowed, b)); Ok(Some(@AutoAdjustment { @@ -320,7 +321,7 @@ impl Coerce { fn coerce_from_bare_fn(&self, a: ty::t, - fn_ty_a: &ty::FnTy, + fn_ty_a: &ty::BareFnTy, b: ty::t) -> CoerceResult { do self.unpack_actual_value(b) |sty_b| { @@ -330,7 +331,7 @@ impl Coerce { fn coerce_from_bare_fn_post_unpack(&self, a: ty::t, - fn_ty_a: &ty::FnTy, + fn_ty_a: &ty::BareFnTy, b: ty::t, sty_b: &ty::sty) -> CoerceResult { @@ -338,18 +339,18 @@ impl Coerce { a.inf_str(self.infcx), b.inf_str(self.infcx)); let fn_ty_b = match *sty_b { - ty::ty_fn(ref f) if f.meta.proto != ast::ProtoBare => {f} + ty::ty_closure(ref f) => {copy *f} _ => { return self.subtype(a, b); } }; - // for now, bare fn and closures have the same - // representation - let a_adapted = ty::mk_fn(self.infcx.tcx, - FnTyBase {meta: copy fn_ty_b.meta, - sig: copy fn_ty_a.sig}); - self.subtype(a_adapted, b) + // for now, bare fn and closures have the same + // representation + let a_closure = ty::mk_closure( + self.infcx.tcx, + ty::ClosureTy {sig: copy fn_ty_a.sig, ..fn_ty_b}); + self.subtype(a_closure, b) } fn coerce_unsafe_ptr(&self, diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs index 819348e744ecf..7737327bc0c52 100644 --- a/src/librustc/middle/typeck/infer/combine.rs +++ b/src/librustc/middle/typeck/infer/combine.rs @@ -56,7 +56,7 @@ use core::prelude::*; -use middle::ty::{FloatVar, FnTyBase, FnMeta, FnSig, IntVar, TyVar}; +use middle::ty::{FloatVar, FnSig, IntVar, TyVar}; use middle::ty::{IntType, UintType, arg, substs}; use middle::ty; use middle::typeck::infer::glb::Glb; @@ -94,14 +94,17 @@ pub trait Combine { fn self_tys(a: Option, b: Option) -> cres>; fn substs(did: ast::def_id, as_: &ty::substs, bs: &ty::substs) -> cres; - fn fns(a: &ty::FnTy, b: &ty::FnTy) -> cres; + fn bare_fn_tys(a: &ty::BareFnTy, + b: &ty::BareFnTy) -> cres; + fn closure_tys(a: &ty::ClosureTy, + b: &ty::ClosureTy) -> cres; fn fn_sigs(a: &ty::FnSig, b: &ty::FnSig) -> cres; - fn fn_metas(a: &ty::FnMeta, b: &ty::FnMeta) -> cres; fn flds(a: ty::field, b: ty::field) -> cres; fn modes(a: ast::mode, b: ast::mode) -> cres; fn args(a: ty::arg, b: ty::arg) -> cres; - fn protos(p1: ast::Proto, p2: ast::Proto) -> cres; + fn sigils(p1: ast::Sigil, p2: ast::Sigil) -> cres; fn purities(a: purity, b: purity) -> cres; + fn abis(a: ast::Abi, b: ast::Abi) -> cres; fn oncenesses(a: Onceness, b: Onceness) -> cres; fn contraregions(a: ty::Region, b: ty::Region) -> cres; fn regions(a: ty::Region, b: ty::Region) -> cres; @@ -287,12 +290,12 @@ pub fn super_self_tys( } } -pub fn super_protos( - self: &C, p1: ast::Proto, p2: ast::Proto) -> cres { +pub fn super_sigils( + self: &C, p1: ast::Sigil, p2: ast::Sigil) -> cres { if p1 == p2 { Ok(p1) } else { - Err(ty::terr_proto_mismatch(expected_found(self, p1, p2))) + Err(ty::terr_sigil_mismatch(expected_found(self, p1, p2))) } } @@ -350,21 +353,45 @@ pub fn super_vstores( } } -pub fn super_fn_metas( - self: &C, a_f: &ty::FnMeta, b_f: &ty::FnMeta) -> cres { - let p = if_ok!(self.protos(a_f.proto, b_f.proto)); +pub fn super_closure_tys( + self: &C, a_f: &ty::ClosureTy, b_f: &ty::ClosureTy) -> cres +{ + let p = if_ok!(self.sigils(a_f.sigil, b_f.sigil)); let r = if_ok!(self.contraregions(a_f.region, b_f.region)); let purity = if_ok!(self.purities(a_f.purity, b_f.purity)); let onceness = if_ok!(self.oncenesses(a_f.onceness, b_f.onceness)); - Ok(FnMeta {purity: purity, - proto: p, - onceness: onceness, - region: r, - bounds: a_f.bounds}) // XXX: This is wrong! + let sig = if_ok!(self.fn_sigs(&a_f.sig, &b_f.sig)); + Ok(ty::ClosureTy {purity: purity, + sigil: p, + onceness: onceness, + region: r, + sig: sig}) +} + +pub fn super_abis( + self: &C, a: ast::Abi, b: ast::Abi) -> cres +{ + if a == b { + Ok(a) + } else { + Err(ty::terr_abi_mismatch(expected_found(self, a, b))) + } +} + +pub fn super_bare_fn_tys( + self: &C, a_f: &ty::BareFnTy, b_f: &ty::BareFnTy) -> cres +{ + let purity = if_ok!(self.purities(a_f.purity, b_f.purity)); + let abi = if_ok!(self.abis(a_f.abi, b_f.abi)); + let sig = if_ok!(self.fn_sigs(&a_f.sig, &b_f.sig)); + Ok(ty::BareFnTy {purity: purity, + abi: abi, + sig: sig}) } pub fn super_fn_sigs( - self: &C, a_f: &ty::FnSig, b_f: &ty::FnSig) -> cres { + self: &C, a_f: &ty::FnSig, b_f: &ty::FnSig) -> cres +{ fn argvecs(self: &C, +a_args: ~[ty::arg], +b_args: ~[ty::arg]) -> cres<~[ty::arg]> @@ -384,13 +411,6 @@ pub fn super_fn_sigs( } } -pub fn super_fns( - self: &C, a_f: &ty::FnTy, b_f: &ty::FnTy) -> cres { - let m = if_ok!(self.fn_metas(&a_f.meta, &b_f.meta)); - let s = if_ok!(self.fn_sigs(&a_f.sig, &b_f.sig)); - Ok(FnTyBase {meta: m, sig: s}) -} - pub fn super_tys( self: &C, a: ty::t, b: ty::t) -> cres { let tcx = self.infcx().tcx; @@ -551,9 +571,15 @@ pub fn super_tys( } } - (ty::ty_fn(ref a_fty), ty::ty_fn(ref b_fty)) => { - do self.fns(a_fty, b_fty).chain |fty| { - Ok(ty::mk_fn(tcx, fty)) + (ty::ty_bare_fn(ref a_fty), ty::ty_bare_fn(ref b_fty)) => { + do self.bare_fn_tys(a_fty, b_fty).chain |fty| { + Ok(ty::mk_bare_fn(tcx, fty)) + } + } + + (ty::ty_closure(ref a_fty), ty::ty_closure(ref b_fty)) => { + do self.closure_tys(a_fty, b_fty).chain |fty| { + Ok(ty::mk_closure(tcx, fty)) } } diff --git a/src/librustc/middle/typeck/infer/glb.rs b/src/librustc/middle/typeck/infer/glb.rs index 58d9f1019aebe..382d5f24cc74b 100644 --- a/src/librustc/middle/typeck/infer/glb.rs +++ b/src/librustc/middle/typeck/infer/glb.rs @@ -267,16 +267,22 @@ pub impl Glb: Combine { } } - fn protos(p1: ast::Proto, p2: ast::Proto) -> cres { - super_protos(&self, p1, p2) + fn sigils(p1: ast::Sigil, p2: ast::Sigil) -> cres { + super_sigils(&self, p1, p2) } - fn fns(a: &ty::FnTy, b: &ty::FnTy) -> cres { - super_fns(&self, a, b) + fn abis(p1: ast::Abi, p2: ast::Abi) -> cres { + super_abis(&self, p1, p2) } - fn fn_metas(a: &ty::FnMeta, b: &ty::FnMeta) -> cres { - super_fn_metas(&self, a, b) + fn bare_fn_tys(a: &ty::BareFnTy, + b: &ty::BareFnTy) -> cres { + super_bare_fn_tys(&self, a, b) + } + + fn closure_tys(a: &ty::ClosureTy, + b: &ty::ClosureTy) -> cres { + super_closure_tys(&self, a, b) } fn substs(did: ast::def_id, diff --git a/src/librustc/middle/typeck/infer/lattice.rs b/src/librustc/middle/typeck/infer/lattice.rs index 4f7bedd814978..4bf8a0bae8623 100644 --- a/src/librustc/middle/typeck/infer/lattice.rs +++ b/src/librustc/middle/typeck/infer/lattice.rs @@ -71,23 +71,6 @@ pub impl ty::t: LatticeValue { } } -pub impl FnMeta: LatticeValue { - static fn sub(cf: &CombineFields, - a: &FnMeta, b: &FnMeta) -> ures { - Sub(*cf).fn_metas(a, b).to_ures() - } - - static fn lub(cf: &CombineFields, - a: &FnMeta, b: &FnMeta) -> cres { - Lub(*cf).fn_metas(a, b) - } - - static fn glb(cf: &CombineFields, - a: &FnMeta, b: &FnMeta) -> cres { - Glb(*cf).fn_metas(a, b) - } -} - pub impl CombineFields { fn var_sub_var>>( diff --git a/src/librustc/middle/typeck/infer/lub.rs b/src/librustc/middle/typeck/infer/lub.rs index f24d245db58ed..44ad367c9dcf9 100644 --- a/src/librustc/middle/typeck/infer/lub.rs +++ b/src/librustc/middle/typeck/infer/lub.rs @@ -191,18 +191,24 @@ pub impl Lub: Combine { } } - fn fns(a: &ty::FnTy, b: &ty::FnTy) -> cres { - super_fns(&self, a, b) + fn bare_fn_tys(a: &ty::BareFnTy, + b: &ty::BareFnTy) -> cres { + super_bare_fn_tys(&self, a, b) } - fn fn_metas(a: &ty::FnMeta, b: &ty::FnMeta) -> cres { - super_fn_metas(&self, a, b) + fn closure_tys(a: &ty::ClosureTy, + b: &ty::ClosureTy) -> cres { + super_closure_tys(&self, a, b) } // Traits please (FIXME: #2794): - fn protos(p1: ast::Proto, p2: ast::Proto) -> cres { - super_protos(&self, p1, p2) + fn sigils(p1: ast::Sigil, p2: ast::Sigil) -> cres { + super_sigils(&self, p1, p2) + } + + fn abis(p1: ast::Abi, p2: ast::Abi) -> cres { + super_abis(&self, p1, p2) } fn tys(a: ty::t, b: ty::t) -> cres { diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs index 6140390a24e12..d6ecf11ef26fa 100644 --- a/src/librustc/middle/typeck/infer/mod.rs +++ b/src/librustc/middle/typeck/infer/mod.rs @@ -242,9 +242,6 @@ section on "Type Combining" below for details. */ -#[warn(deprecated_mode)]; -#[warn(deprecated_pattern)]; - use core::prelude::*; pub use middle::ty::IntVarValue; @@ -257,7 +254,6 @@ pub use middle::typeck::infer::resolve::{resolve_nested_tvar}; pub use middle::typeck::infer::resolve::{resolve_rvar}; use middle::ty::{TyVid, IntVid, FloatVid, RegionVid, Vid}; -use middle::ty::{mk_fn, type_is_bot}; use middle::ty::{ty_int, ty_uint, get, terr_fn, TyVar, IntVar, FloatVar}; use middle::ty; use middle::typeck::check::regionmanip::{replace_bound_regions_in_fn_sig}; diff --git a/src/librustc/middle/typeck/infer/region_inference.rs b/src/librustc/middle/typeck/infer/region_inference.rs index 0d4e520122fc3..afb18888cd905 100644 --- a/src/librustc/middle/typeck/infer/region_inference.rs +++ b/src/librustc/middle/typeck/infer/region_inference.rs @@ -536,9 +536,6 @@ more convincing in the future. */ -#[warn(deprecated_mode)]; -#[warn(deprecated_pattern)]; - use core::prelude::*; use middle::region::is_subregion_of; diff --git a/src/librustc/middle/typeck/infer/sub.rs b/src/librustc/middle/typeck/infer/sub.rs index 2e30bdc58883f..bc834ef028996 100644 --- a/src/librustc/middle/typeck/infer/sub.rs +++ b/src/librustc/middle/typeck/infer/sub.rs @@ -212,20 +212,26 @@ pub impl Sub: Combine { // Traits please (FIXME: #2794): - fn protos(p1: ast::Proto, p2: ast::Proto) -> cres { - super_protos(&self, p1, p2) + fn sigils(p1: ast::Sigil, p2: ast::Sigil) -> cres { + super_sigils(&self, p1, p2) + } + + fn abis(p1: ast::Abi, p2: ast::Abi) -> cres { + super_abis(&self, p1, p2) } fn flds(a: ty::field, b: ty::field) -> cres { super_flds(&self, a, b) } - fn fns(a: &ty::FnTy, b: &ty::FnTy) -> cres { - super_fns(&self, a, b) + fn bare_fn_tys(a: &ty::BareFnTy, + b: &ty::BareFnTy) -> cres { + super_bare_fn_tys(&self, a, b) } - fn fn_metas(a: &ty::FnMeta, b: &ty::FnMeta) -> cres { - super_fn_metas(&self, a, b) + fn closure_tys(a: &ty::ClosureTy, + b: &ty::ClosureTy) -> cres { + super_closure_tys(&self, a, b) } fn vstores(vk: ty::terr_vstore_kind, diff --git a/src/librustc/middle/typeck/infer/to_str.rs b/src/librustc/middle/typeck/infer/to_str.rs index 57e05926173d1..bade7639e4baf 100644 --- a/src/librustc/middle/typeck/infer/to_str.rs +++ b/src/librustc/middle/typeck/infer/to_str.rs @@ -10,7 +10,7 @@ use core::prelude::*; -use middle::ty::{FnMeta, FnTyBase, FnSig, Vid}; +use middle::ty::{FnSig, Vid}; use middle::ty::{IntVarValue, IntType, UintType}; use middle::ty; use middle::typeck::infer::{Bound, Bounds}; @@ -34,12 +34,6 @@ pub impl ty::t : InferStr { } } -pub impl FnMeta : InferStr { - fn inf_str(&self, _cx: &InferCtxt) -> ~str { - fmt!("%?", *self) - } -} - pub impl FnSig : InferStr { fn inf_str(&self, cx: &InferCtxt) -> ~str { fmt!("(%s) -> %s", @@ -48,12 +42,6 @@ pub impl FnSig : InferStr { } } -pub impl FnTyBase : InferStr { - fn inf_str(&self, cx: &InferCtxt) -> ~str { - fmt!("%s%s", self.meta.inf_str(cx), self.sig.inf_str(cx)) - } -} - pub impl ty::mt : InferStr { fn inf_str(&self, cx: &InferCtxt) -> ~str { mt_to_str(cx.tcx, *self) diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs index 742646618bd26..3d9e2e7b86ab2 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -324,7 +324,7 @@ fn check_main_fn_ty(ccx: @crate_ctxt, let tcx = ccx.tcx; let main_t = ty::node_id_to_type(tcx, main_id); match ty::get(main_t).sty { - ty::ty_fn(ref fn_ty) => { + ty::ty_bare_fn(ref fn_ty) => { match tcx.items.find(&main_id) { Some(ast_map::node_item(it,_)) => { match it.node { @@ -341,8 +341,8 @@ fn check_main_fn_ty(ccx: @crate_ctxt, } _ => () } - let mut ok = ty::type_is_nil((*fn_ty).sig.output); - let num_args = vec::len((*fn_ty).sig.inputs); + let mut ok = ty::type_is_nil(fn_ty.sig.output); + let num_args = vec::len(fn_ty.sig.inputs); ok &= num_args == 0u; if !ok { tcx.sess.span_err( diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 9e70a6ab1306a..43d12c95c4df6 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -21,7 +21,8 @@ use middle::ty::{mt, t, param_bound, param_ty}; use middle::ty::{re_bound, re_free, re_scope, re_infer, re_static, Region}; use middle::ty::{ReSkolemized, ReVar}; use middle::ty::{ty_bool, ty_bot, ty_box, ty_struct, ty_enum}; -use middle::ty::{ty_err, ty_estr, ty_evec, ty_float, ty_fn, ty_trait, ty_int}; +use middle::ty::{ty_err, ty_estr, ty_evec, ty_float, ty_bare_fn, ty_closure}; +use middle::ty::{ty_trait, ty_int}; use middle::ty::{ty_nil, ty_opaque_box, ty_opaque_closure_ptr, ty_param}; use middle::ty::{ty_ptr, ty_rec, ty_rptr, ty_self, ty_tup}; use middle::ty::{ty_type, ty_uniq, ty_uint, ty_infer}; @@ -30,7 +31,7 @@ use metadata::encoder; use syntax::codemap; use syntax::codemap::span; use syntax::print::pprust; -use syntax::print::pprust::{path_to_str, proto_to_str, mode_to_str}; +use syntax::print::pprust::{path_to_str, mode_to_str}; use syntax::{ast, ast_util}; use syntax::ast_map; @@ -252,17 +253,6 @@ pub fn vstore_ty_to_str(cx: ctxt, ty: ~str, vs: ty::vstore) -> ~str { } } -pub fn proto_ty_to_str(_cx: ctxt, proto: ast::Proto, - followed_by_word: bool) -> &static/str { - match proto { - ast::ProtoBare if followed_by_word => "extern ", - ast::ProtoBare => "extern", - ast::ProtoBox => "@", - ast::ProtoBorrowed => "&", - ast::ProtoUniq => "~", - } -} - pub fn expr_repr(cx: ctxt, expr: @ast::expr) -> ~str { fmt!("expr(%d: %s)", expr.id, @@ -306,69 +296,95 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str { }; fmt!("%s%s", modestr, ty_to_str(cx, ty)) } - fn fn_to_str(cx: ctxt, - proto: ast::Proto, - region: ty::Region, - purity: ast::purity, - onceness: ast::Onceness, - ident: Option, - inputs: &[arg], - output: t) -> ~str { - let mut s; - - s = match purity { - ast::impure_fn => ~"", - _ => purity.to_str() + ~" " - }; + fn bare_fn_to_str(cx: ctxt, + purity: ast::purity, + abi: ast::Abi, + ident: Option, + sig: &ty::FnSig) -> ~str + { + let mut s = ~"extern "; - s += match onceness { - ast::Many => ~"", - ast::Once => onceness.to_str() + ~" " + match abi { + ast::RustAbi => {} + } + + match purity { + ast::impure_fn => {} + _ => { + s.push_str(purity.to_str()); + s.push_char(' '); + } }; - s += proto_ty_to_str(cx, proto, true); + s.push_str("fn"); - match (proto, region) { - (ast::ProtoBox, ty::re_static) | - (ast::ProtoUniq, ty::re_static) | - (ast::ProtoBare, ty::re_static) => { - } + match ident { + Some(i) => { + s.push_char(' '); + s.push_str(cx.sess.str_of(i)); + } + _ => { } + } + + push_sig_to_str(cx, &mut s, sig); + + return s; + } + fn closure_to_str(cx: ctxt, cty: &ty::ClosureTy) -> ~str + { + let mut s = cty.sigil.to_str(); + + match (cty.sigil, cty.region) { + (ast::ManagedSigil, ty::re_static) | + (ast::OwnedSigil, ty::re_static) => {} (_, region) => { - s += region_to_str_adorned(cx, ~"", region, ~"/"); + s.push_str(region_to_str_adorned(cx, "", region, "/")); } } - s += ~"fn"; + match cty.purity { + ast::impure_fn => {} + _ => { + s.push_str(cty.purity.to_str()); + s.push_char(' '); + } + }; - match ident { - Some(i) => { s += ~" "; s += cx.sess.str_of(i); } - _ => { } - } - s += ~"("; - let strs = inputs.map(|a| fn_input_to_str(cx, *a)); - s += str::connect(strs, ~", "); - s += ~")"; - if ty::get(output).sty != ty_nil { - s += ~" -> "; - if ty::type_is_bot(output) { - s += ~"!"; + match cty.onceness { + ast::Many => {} + ast::Once => { + s.push_str(cty.onceness.to_str()); + s.push_char(' '); + } + }; + + s.push_str("fn"); + + push_sig_to_str(cx, &mut s, &cty.sig); + + return s; + } + fn push_sig_to_str(cx: ctxt, s: &mut ~str, sig: &ty::FnSig) { + s.push_char('('); + let strs = sig.inputs.map(|a| fn_input_to_str(cx, *a)); + s.push_str(str::connect(strs, ", ")); + s.push_char(')'); + if ty::get(sig.output).sty != ty_nil { + s.push_str(" -> "); + if ty::type_is_bot(sig.output) { + s.push_char('!'); } else { - s += ty_to_str(cx, output); + s.push_str(ty_to_str(cx, sig.output)); } } - return s; } fn method_to_str(cx: ctxt, m: method) -> ~str { - return fn_to_str( - cx, - m.fty.meta.proto, - m.fty.meta.region, - m.fty.meta.purity, - m.fty.meta.onceness, - Some(m.ident), - m.fty.sig.inputs, - m.fty.sig.output) + ~";"; + bare_fn_to_str(cx, + m.fty.purity, + m.fty.abi, + Some(m.ident), + &m.fty.sig) + ~";" } fn field_to_str(cx: ctxt, f: field) -> ~str { return cx.sess.str_of(f.ident) + ~": " + mt_to_str(cx, f.mt); @@ -409,15 +425,11 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str { let strs = elems.map(|elem| ty_to_str(cx, *elem)); ~"(" + str::connect(strs, ~",") + ~")" } - ty_fn(ref f) => { - fn_to_str(cx, - f.meta.proto, - f.meta.region, - f.meta.purity, - f.meta.onceness, - None, - f.sig.inputs, - f.sig.output) + ty_closure(ref f) => { + closure_to_str(cx, f) + } + ty_bare_fn(ref f) => { + bare_fn_to_str(cx, f.purity, f.abi, None, &f.sig) } ty_infer(infer_ty) => infer_ty.to_str(), ty_err => ~"[type error]", @@ -448,10 +460,9 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str { } ty_estr(vs) => vstore_ty_to_str(cx, ~"str", vs), ty_opaque_box => ~"@?", - ty_opaque_closure_ptr(ast::ProtoBorrowed) => ~"closure&", - ty_opaque_closure_ptr(ast::ProtoBox) => ~"closure@", - ty_opaque_closure_ptr(ast::ProtoUniq) => ~"closure~", - ty_opaque_closure_ptr(ast::ProtoBare) => ~"closure" + ty_opaque_closure_ptr(ast::BorrowedSigil) => ~"closure&", + ty_opaque_closure_ptr(ast::ManagedSigil) => ~"closure@", + ty_opaque_closure_ptr(ast::OwnedSigil) => ~"closure~", } } diff --git a/src/librustdoc/astsrv.rs b/src/librustdoc/astsrv.rs index dd6e889008f3b..1d629467a42e9 100644 --- a/src/librustdoc/astsrv.rs +++ b/src/librustdoc/astsrv.rs @@ -21,6 +21,7 @@ use core::prelude::*; use parse; use util; +use std::cell::Cell; use core::pipes::{stream, Chan, SharedChan, Port}; use core::vec; @@ -78,8 +79,10 @@ fn run(owner: SrvOwner, source: ~str, parse: Parser) -> T { let (po, ch) = stream(); + let source = Cell(source); + let parse = Cell(parse); do task::spawn { - act(&po, copy source, copy parse); + act(&po, source.take(), parse.take()); } let srv_ = Srv { diff --git a/src/librustdoc/attr_parser.rs b/src/librustdoc/attr_parser.rs index afbb10f2cbbc2..0beb651afc4ed 100644 --- a/src/librustdoc/attr_parser.rs +++ b/src/librustdoc/attr_parser.rs @@ -96,7 +96,7 @@ fn should_not_extract_crate_name_if_no_name_value_in_link_attribute() { } pub fn parse_desc(attrs: ~[ast::attribute]) -> Option<~str> { - let doc_strs = do doc_metas(attrs).filter_map |meta| { + let doc_strs = do doc_metas(attrs).filter_mapped |meta| { attr::get_meta_item_value_str(*meta) }; if doc_strs.is_empty() { diff --git a/src/librustdoc/desc_to_brief_pass.rs b/src/librustdoc/desc_to_brief_pass.rs index 225b62f72cb83..2d0969562a05c 100644 --- a/src/librustdoc/desc_to_brief_pass.rs +++ b/src/librustdoc/desc_to_brief_pass.rs @@ -62,7 +62,7 @@ fn fold_trait(fold: &fold::Fold<()>, doc: doc::TraitDoc) -> doc::TraitDoc { let doc =fold::default_seq_fold_trait(fold, doc); doc::TraitDoc { - methods: par::map(doc.methods, |doc| doc::MethodDoc { + methods: doc.methods.map(|doc| doc::MethodDoc { brief: extract(copy doc.desc), .. copy *doc }), @@ -74,7 +74,7 @@ fn fold_impl(fold: &fold::Fold<()>, doc: doc::ImplDoc) -> doc::ImplDoc { let doc =fold::default_seq_fold_impl(fold, doc); doc::ImplDoc { - methods: par::map(doc.methods, |doc| doc::MethodDoc { + methods: doc.methods.map(|doc| doc::MethodDoc { brief: extract(copy doc.desc), .. copy *doc }), diff --git a/src/librustdoc/doc.rs b/src/librustdoc/doc.rs index e51c8106f3d41..2eb4ed9787132 100644 --- a/src/librustdoc/doc.rs +++ b/src/librustdoc/doc.rs @@ -192,7 +192,7 @@ impl Doc { /// Some helper methods on ModDoc, mostly for testing impl ModDoc { fn mods(&self) -> ~[ModDoc] { - do vec::filter_map(self.items) |itemtag| { + do vec::filter_mapped(self.items) |itemtag| { match copy *itemtag { ModTag(ModDoc) => Some(ModDoc), _ => None @@ -201,7 +201,7 @@ impl ModDoc { } fn nmods(&self) -> ~[NmodDoc] { - do vec::filter_map(self.items) |itemtag| { + do vec::filter_mapped(self.items) |itemtag| { match copy *itemtag { NmodTag(nModDoc) => Some(nModDoc), _ => None @@ -210,7 +210,7 @@ impl ModDoc { } fn fns(&self) -> ~[FnDoc] { - do vec::filter_map(self.items) |itemtag| { + do vec::filter_mapped(self.items) |itemtag| { match copy *itemtag { FnTag(FnDoc) => Some(FnDoc), _ => None @@ -219,7 +219,7 @@ impl ModDoc { } fn consts(&self) -> ~[ConstDoc] { - do vec::filter_map(self.items) |itemtag| { + do vec::filter_mapped(self.items) |itemtag| { match copy *itemtag { ConstTag(ConstDoc) => Some(ConstDoc), _ => None @@ -228,7 +228,7 @@ impl ModDoc { } fn enums(&self) -> ~[EnumDoc] { - do vec::filter_map(self.items) |itemtag| { + do vec::filter_mapped(self.items) |itemtag| { match copy *itemtag { EnumTag(EnumDoc) => Some(EnumDoc), _ => None @@ -237,7 +237,7 @@ impl ModDoc { } fn traits(&self) -> ~[TraitDoc] { - do vec::filter_map(self.items) |itemtag| { + do vec::filter_mapped(self.items) |itemtag| { match copy *itemtag { TraitTag(TraitDoc) => Some(TraitDoc), _ => None @@ -246,7 +246,7 @@ impl ModDoc { } fn impls(&self) -> ~[ImplDoc] { - do vec::filter_map(self.items) |itemtag| { + do vec::filter_mapped(self.items) |itemtag| { match copy *itemtag { ImplTag(ImplDoc) => Some(ImplDoc), _ => None @@ -255,7 +255,7 @@ impl ModDoc { } fn types(&self) -> ~[TyDoc] { - do vec::filter_map(self.items) |itemtag| { + do vec::filter_mapped(self.items) |itemtag| { match copy *itemtag { TyTag(TyDoc) => Some(TyDoc), _ => None @@ -264,7 +264,7 @@ impl ModDoc { } fn structs(&self) -> ~[StructDoc] { - do vec::filter_map(self.items) |itemtag| { + do vec::filter_mapped(self.items) |itemtag| { match copy *itemtag { StructTag(StructDoc) => Some(StructDoc), _ => None @@ -287,7 +287,7 @@ pub trait PageUtils { impl ~[Page]: PageUtils { fn mods(&self) -> ~[ModDoc] { - do vec::filter_map(*self) |page| { + do vec::filter_mapped(*self) |page| { match copy *page { ItemPage(ModTag(ModDoc)) => Some(ModDoc), _ => None @@ -296,7 +296,7 @@ impl ~[Page]: PageUtils { } fn nmods(&self) -> ~[NmodDoc] { - do vec::filter_map(*self) |page| { + do vec::filter_mapped(*self) |page| { match copy *page { ItemPage(NmodTag(nModDoc)) => Some(nModDoc), _ => None @@ -305,7 +305,7 @@ impl ~[Page]: PageUtils { } fn fns(&self) -> ~[FnDoc] { - do vec::filter_map(*self) |page| { + do vec::filter_mapped(*self) |page| { match copy *page { ItemPage(FnTag(FnDoc)) => Some(FnDoc), _ => None @@ -314,7 +314,7 @@ impl ~[Page]: PageUtils { } fn consts(&self) -> ~[ConstDoc] { - do vec::filter_map(*self) |page| { + do vec::filter_mapped(*self) |page| { match copy *page { ItemPage(ConstTag(ConstDoc)) => Some(ConstDoc), _ => None @@ -323,7 +323,7 @@ impl ~[Page]: PageUtils { } fn enums(&self) -> ~[EnumDoc] { - do vec::filter_map(*self) |page| { + do vec::filter_mapped(*self) |page| { match copy *page { ItemPage(EnumTag(EnumDoc)) => Some(EnumDoc), _ => None @@ -332,7 +332,7 @@ impl ~[Page]: PageUtils { } fn traits(&self) -> ~[TraitDoc] { - do vec::filter_map(*self) |page| { + do vec::filter_mapped(*self) |page| { match copy *page { ItemPage(TraitTag(TraitDoc)) => Some(TraitDoc), _ => None @@ -341,7 +341,7 @@ impl ~[Page]: PageUtils { } fn impls(&self) -> ~[ImplDoc] { - do vec::filter_map(*self) |page| { + do vec::filter_mapped(*self) |page| { match copy *page { ItemPage(ImplTag(ImplDoc)) => Some(ImplDoc), _ => None @@ -350,7 +350,7 @@ impl ~[Page]: PageUtils { } fn types(&self) -> ~[TyDoc] { - do vec::filter_map(*self) |page| { + do vec::filter_mapped(*self) |page| { match copy *page { ItemPage(TyTag(TyDoc)) => Some(TyDoc), _ => None diff --git a/src/librustdoc/extract.rs b/src/librustdoc/extract.rs index fc572e3da2c1d..822a423eae40c 100644 --- a/src/librustdoc/extract.rs +++ b/src/librustdoc/extract.rs @@ -92,7 +92,7 @@ fn moddoc_from_mod( ) -> doc::ModDoc { doc::ModDoc { item: itemdoc, - items: do vec::filter_map(module_.items) |item| { + items: do vec::filter_mapped(module_.items) |item| { let ItemDoc = mk_itemdoc(item.id, to_str(item.ident)); match copy item.node { ast::item_mod(m) => { diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs index c93d9f3d7c159..e9b25b07de15b 100644 --- a/src/librustdoc/fold.rs +++ b/src/librustdoc/fold.rs @@ -55,23 +55,23 @@ impl Fold: Clone { } } -type FoldDoc = fn~(fold: &Fold, doc: doc::Doc) -> doc::Doc; -type FoldCrate = fn~(fold: &Fold, doc: doc::CrateDoc) -> doc::CrateDoc; -type FoldItem = fn~(fold: &Fold, doc: doc::ItemDoc) -> doc::ItemDoc; -type FoldMod = fn~(fold: &Fold, doc: doc::ModDoc) -> doc::ModDoc; -type FoldNmod = fn~(fold: &Fold, doc: doc::NmodDoc) -> doc::NmodDoc; -type FoldFn = fn~(fold: &Fold, doc: doc::FnDoc) -> doc::FnDoc; -type FoldConst = fn~(fold: &Fold, doc: doc::ConstDoc) -> doc::ConstDoc; -type FoldEnum = fn~(fold: &Fold, doc: doc::EnumDoc) -> doc::EnumDoc; -type FoldTrait = fn~(fold: &Fold, doc: doc::TraitDoc) -> doc::TraitDoc; -type FoldImpl = fn~(fold: &Fold, doc: doc::ImplDoc) -> doc::ImplDoc; -type FoldType = fn~(fold: &Fold, doc: doc::TyDoc) -> doc::TyDoc; -type FoldStruct = fn~(fold: &Fold, +type FoldDoc = @fn(fold: &Fold, doc: doc::Doc) -> doc::Doc; +type FoldCrate = @fn(fold: &Fold, doc: doc::CrateDoc) -> doc::CrateDoc; +type FoldItem = @fn(fold: &Fold, doc: doc::ItemDoc) -> doc::ItemDoc; +type FoldMod = @fn(fold: &Fold, doc: doc::ModDoc) -> doc::ModDoc; +type FoldNmod = @fn(fold: &Fold, doc: doc::NmodDoc) -> doc::NmodDoc; +type FoldFn = @fn(fold: &Fold, doc: doc::FnDoc) -> doc::FnDoc; +type FoldConst = @fn(fold: &Fold, doc: doc::ConstDoc) -> doc::ConstDoc; +type FoldEnum = @fn(fold: &Fold, doc: doc::EnumDoc) -> doc::EnumDoc; +type FoldTrait = @fn(fold: &Fold, doc: doc::TraitDoc) -> doc::TraitDoc; +type FoldImpl = @fn(fold: &Fold, doc: doc::ImplDoc) -> doc::ImplDoc; +type FoldType = @fn(fold: &Fold, doc: doc::TyDoc) -> doc::TyDoc; +type FoldStruct = @fn(fold: &Fold, doc: doc::StructDoc) -> doc::StructDoc; // This exists because fn types don't infer correctly as record // initializers, but they do as function arguments -fn mk_fold( +fn mk_fold( ctxt: T, fold_doc: FoldDoc, fold_crate: FoldCrate, @@ -103,7 +103,7 @@ fn mk_fold( } } -pub fn default_any_fold(ctxt: T) -> Fold { +pub fn default_any_fold(ctxt: T) -> Fold { mk_fold( move ctxt, |f, d| default_seq_fold_doc(f, d), @@ -121,7 +121,7 @@ pub fn default_any_fold(ctxt: T) -> Fold { ) } -pub fn default_seq_fold(ctxt: T) -> Fold { +pub fn default_seq_fold(ctxt: T) -> Fold { mk_fold( move ctxt, |f, d| default_seq_fold_doc(f, d), @@ -139,7 +139,7 @@ pub fn default_seq_fold(ctxt: T) -> Fold { ) } -pub fn default_par_fold(ctxt: T) -> Fold { +pub fn default_par_fold(ctxt: T) -> Fold { mk_fold( move ctxt, |f, d| default_seq_fold_doc(f, d), @@ -189,7 +189,7 @@ pub fn default_seq_fold_item( doc } -pub fn default_any_fold_mod( +pub fn default_any_fold_mod( fold: &Fold, doc: doc::ModDoc ) -> doc::ModDoc { @@ -215,7 +215,7 @@ pub fn default_seq_fold_mod( } } -pub fn default_par_fold_mod( +pub fn default_par_fold_mod( fold: &Fold, doc: doc::ModDoc ) -> doc::ModDoc { @@ -228,7 +228,7 @@ pub fn default_par_fold_mod( } } -pub fn default_any_fold_nmod( +pub fn default_any_fold_nmod( fold: &Fold, doc: doc::NmodDoc ) -> doc::NmodDoc { @@ -254,7 +254,7 @@ pub fn default_seq_fold_nmod( } } -pub fn default_par_fold_nmod( +pub fn default_par_fold_nmod( fold: &Fold, doc: doc::NmodDoc ) -> doc::NmodDoc { diff --git a/src/librustdoc/markdown_index_pass.rs b/src/librustdoc/markdown_index_pass.rs index 776d2fe9083c7..42a7d0006db09 100644 --- a/src/librustdoc/markdown_index_pass.rs +++ b/src/librustdoc/markdown_index_pass.rs @@ -28,9 +28,7 @@ use std::par; pub fn mk_pass(config: config::Config) -> Pass { Pass { name: ~"markdown_index", - f: fn~(srv: astsrv::Srv, doc: doc::Doc) -> doc::Doc { - run(srv, doc, copy config) - } + f: |srv, doc| run(srv, doc, copy config) } } @@ -78,7 +76,7 @@ fn build_mod_index( config: config::Config ) -> doc::Index { doc::Index { - entries: par::map(doc.items, |doc| { + entries: doc.items.map(|doc| { item_to_entry(copy *doc, copy config) }) } @@ -89,7 +87,7 @@ fn build_nmod_index( config: config::Config ) -> doc::Index { doc::Index { - entries: par::map(doc.fns, |doc| { + entries: doc.fns.map(|doc| { item_to_entry(doc::FnTag(copy *doc), copy config) }) } diff --git a/src/librustdoc/markdown_pass.rs b/src/librustdoc/markdown_pass.rs index fc13af8a22133..161642a2f3d97 100644 --- a/src/librustdoc/markdown_pass.rs +++ b/src/librustdoc/markdown_pass.rs @@ -43,14 +43,9 @@ use syntax; pub fn mk_pass(writer_factory: WriterFactory) -> Pass { let writer_factory = Cell(writer_factory); - let f = fn~(move writer_factory, - srv: astsrv::Srv, doc: doc::Doc) -> doc::Doc { - run(srv, doc, writer_factory.take()) - }; - Pass { name: ~"markdown", - f: move f + f: |srv, doc| run(srv, doc, writer_factory.take()) } } diff --git a/src/librustdoc/page_pass.rs b/src/librustdoc/page_pass.rs index c8509826fdbab..08abe4b351b6f 100644 --- a/src/librustdoc/page_pass.rs +++ b/src/librustdoc/page_pass.rs @@ -36,9 +36,7 @@ use syntax::ast; pub fn mk_pass(output_style: config::OutputStyle) -> Pass { Pass { name: ~"page", - f: fn~(srv: astsrv::Srv, doc: doc::Doc) -> doc::Doc { - run(srv, doc, output_style) - } + f: |srv, doc| run(srv, doc, output_style) } } diff --git a/src/librustdoc/pass.rs b/src/librustdoc/pass.rs index 91e3264db1c06..e78c7d54019fc 100644 --- a/src/librustdoc/pass.rs +++ b/src/librustdoc/pass.rs @@ -20,7 +20,7 @@ use core::vec; /// A single operation on the document model pub struct Pass { name: ~str, - f: fn~(srv: astsrv::Srv, +doc: doc::Doc) -> doc::Doc + f: @fn(srv: astsrv::Srv, +doc: doc::Doc) -> doc::Doc } pub fn run_passes( diff --git a/src/librustdoc/sectionalize_pass.rs b/src/librustdoc/sectionalize_pass.rs index d6455c4c783ff..205fc0aa86dec 100644 --- a/src/librustdoc/sectionalize_pass.rs +++ b/src/librustdoc/sectionalize_pass.rs @@ -57,7 +57,7 @@ fn fold_trait(fold: &fold::Fold<()>, doc: doc::TraitDoc) -> doc::TraitDoc { let doc = fold::default_seq_fold_trait(fold, doc); doc::TraitDoc { - methods: do par::map(doc.methods) |method| { + methods: do doc.methods.map |method| { let (desc, sections) = sectionalize(copy method.desc); doc::MethodDoc { @@ -74,7 +74,7 @@ fn fold_impl(fold: &fold::Fold<()>, doc: doc::ImplDoc) -> doc::ImplDoc { let doc = fold::default_seq_fold_impl(fold, doc); doc::ImplDoc { - methods: do par::map(doc.methods) |method| { + methods: do doc.methods.map |method| { let (desc, sections) = sectionalize(copy method.desc); doc::MethodDoc { diff --git a/src/librustdoc/sort_pass.rs b/src/librustdoc/sort_pass.rs index 2792508483ca1..b7614a785c742 100644 --- a/src/librustdoc/sort_pass.rs +++ b/src/librustdoc/sort_pass.rs @@ -23,16 +23,14 @@ use util::NominalOp; use std::sort; -pub type ItemLtEqOp = pure fn~(v1: &doc::ItemTag, v2: &doc::ItemTag) -> bool; +pub type ItemLtEqOp = @pure fn(v1: &doc::ItemTag, v2: &doc::ItemTag) -> bool; type ItemLtEq = NominalOp; pub fn mk_pass(name: ~str, lteq: ItemLtEqOp) -> Pass { Pass { name: copy name, - f: fn~(move lteq, srv: astsrv::Srv, doc: doc::Doc) -> doc::Doc { - run(srv, doc, NominalOp { op: copy lteq }) - } + f: |srv, doc| run(srv, doc, NominalOp { op: lteq }) } } diff --git a/src/librustdoc/text_pass.rs b/src/librustdoc/text_pass.rs index aec8b56341fd3..79ba8f0684a58 100644 --- a/src/librustdoc/text_pass.rs +++ b/src/librustdoc/text_pass.rs @@ -23,17 +23,17 @@ use util::NominalOp; use std::par; use std::cell::Cell; -pub fn mk_pass(name: ~str, op: fn~(&str) -> ~str) -> Pass { +pub fn mk_pass(name: ~str, op: @fn(&str) -> ~str) -> Pass { let op = Cell(op); Pass { name: copy name, - f: fn~(move op, srv: astsrv::Srv, doc: doc::Doc) -> doc::Doc { + f: |srv: astsrv::Srv, doc: doc::Doc| -> doc::Doc { run(srv, doc, op.take()) } } } -type Op = fn~(&str) -> ~str; +type Op = @fn(&str) -> ~str; #[allow(non_implicitly_copyable_typarams)] fn run( @@ -76,7 +76,7 @@ fn apply_to_sections( op: NominalOp, sections: ~[doc::Section] ) -> ~[doc::Section] { - par::map(sections, |section, copy op| doc::Section { + sections.map(|section, copy op| doc::Section { header: (op.op)(copy section.header), body: (op.op)(copy section.body) }) @@ -89,7 +89,7 @@ fn fold_enum( let fold_copy = copy *fold; doc::EnumDoc { - variants: do par::map(doc.variants) |variant, copy fold_copy| { + variants: do doc.variants.map |variant, copy fold_copy| { doc::VariantDoc { desc: maybe_apply_op(copy fold_copy.ctxt, &variant.desc), .. copy *variant @@ -116,7 +116,7 @@ fn apply_to_methods( docs: ~[doc::MethodDoc] ) -> ~[doc::MethodDoc] { let op = copy op; - do par::map(docs) |doc| { + do docs.map |doc| { doc::MethodDoc { brief: maybe_apply_op(copy op, &doc.brief), desc: maybe_apply_op(copy op, &doc.desc), diff --git a/src/librustdoc/unindent_pass.rs b/src/librustdoc/unindent_pass.rs index 1c53ed5dcce04..fa8c2dd93c038 100644 --- a/src/librustdoc/unindent_pass.rs +++ b/src/librustdoc/unindent_pass.rs @@ -80,7 +80,7 @@ fn unindent(s: &str) -> ~str { if !lines.is_empty() { let unindented = ~[str::trim(vec::head(lines))] - + do par::map(vec::tail(lines)) |line| { + + do vec::tail(lines).map |line| { if str::is_whitespace(*line) { copy *line } else { diff --git a/src/libstd/arc.rs b/src/libstd/arc.rs index a8d3f15610467..a1fd7a66f7ec8 100644 --- a/src/libstd/arc.rs +++ b/src/libstd/arc.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; /** * Concurrency-enabled mechanisms for sharing mutable and/or immutable state * between tasks. diff --git a/src/libstd/arena.rs b/src/libstd/arena.rs index 3e21a320d4436..a2cbe27ea9045 100644 --- a/src/libstd/arena.rs +++ b/src/libstd/arena.rs @@ -32,8 +32,6 @@ // overhead when initializing plain-old-data and means we don't need // to waste time running the destructors of POD. -#[forbid(deprecated_mode)]; - use arena; use list; use list::{List, Cons, Nil}; diff --git a/src/libstd/base64.rs b/src/libstd/base64.rs index 5813e0919d958..d9e121798f183 100644 --- a/src/libstd/base64.rs +++ b/src/libstd/base64.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[forbid(deprecated_mode)]; - use core::io::Reader; use core::iter; use core::str; diff --git a/src/libstd/bitv.rs b/src/libstd/bitv.rs index 244d388bffe28..a94c4f790641d 100644 --- a/src/libstd/bitv.rs +++ b/src/libstd/bitv.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[forbid(deprecated_mode)]; - use core::ops; use core::prelude::*; use core::uint; diff --git a/src/libstd/c_vec.rs b/src/libstd/c_vec.rs index 17920f5de3fed..5ea5418d9882e 100644 --- a/src/libstd/c_vec.rs +++ b/src/libstd/c_vec.rs @@ -35,7 +35,6 @@ * great care must be taken to ensure that a reference to the c_vec::t is * still held if needed. */ -#[forbid(deprecated_mode)]; use core::libc; use core::option; diff --git a/src/libstd/cell.rs b/src/libstd/cell.rs index aae84a8695783..10a896a40896f 100644 --- a/src/libstd/cell.rs +++ b/src/libstd/cell.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[forbid(deprecated_mode)]; - use core::option; use core::prelude::*; diff --git a/src/libstd/cmp.rs b/src/libstd/cmp.rs index 0bd7538d9472f..110559ddcefe0 100644 --- a/src/libstd/cmp.rs +++ b/src/libstd/cmp.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[forbid(deprecated_mode)]; //! Additional general-purpose comparison functionality. use core::f32; diff --git a/src/libstd/comm.rs b/src/libstd/comm.rs index dc0fbbac64126..71eb29e26eba7 100644 --- a/src/libstd/comm.rs +++ b/src/libstd/comm.rs @@ -14,9 +14,6 @@ Higher level communication abstractions. */ -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; - use core::pipes::{GenericChan, GenericSmartChan, GenericPort}; use core::pipes::{Chan, Port, Selectable, Peekable}; use core::pipes; diff --git a/src/libstd/dbg.rs b/src/libstd/dbg.rs index cf1b816f238e3..7813357caf228 100644 --- a/src/libstd/dbg.rs +++ b/src/libstd/dbg.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[forbid(deprecated_mode)]; //! Unsafe debugging functions for inspecting values. use core::cast::reinterpret_cast; diff --git a/src/libstd/deque.rs b/src/libstd/deque.rs index 2f001ae866c6b..465c5d8f8feea 100644 --- a/src/libstd/deque.rs +++ b/src/libstd/deque.rs @@ -9,7 +9,6 @@ // except according to those terms. //! A deque. Untested as of yet. Likely buggy -#[forbid(deprecated_mode)]; #[forbid(non_camel_case_types)]; use core::cmp::Eq; diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs index aaeecfb330210..768d2dbf2d4ba 100644 --- a/src/libstd/ebml.rs +++ b/src/libstd/ebml.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[forbid(deprecated_mode)]; - use serialize; use core::io; diff --git a/src/libstd/fun_treemap.rs b/src/libstd/fun_treemap.rs index e0d4b95a7e425..d6c2cf5a265ee 100644 --- a/src/libstd/fun_treemap.rs +++ b/src/libstd/fun_treemap.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[forbid(deprecated_mode)]; - /*! * A functional key,value store that works on anything. * diff --git a/src/libstd/getopts.rs b/src/libstd/getopts.rs index 6e1a086103507..fa8fdf56428d8 100644 --- a/src/libstd/getopts.rs +++ b/src/libstd/getopts.rs @@ -72,7 +72,6 @@ * do_work(input, output); * } */ -#[forbid(deprecated_mode)]; use core::cmp::Eq; use core::prelude::*; diff --git a/src/libstd/json.rs b/src/libstd/json.rs index 13b58c433006e..99c6c2f008dd6 100644 --- a/src/libstd/json.rs +++ b/src/libstd/json.rs @@ -10,7 +10,6 @@ // Rust JSON serialization library // Copyright (c) 2011 Google Inc. -#[forbid(deprecated_mode)]; #[forbid(non_camel_case_types)]; //! json serialization diff --git a/src/libstd/list.rs b/src/libstd/list.rs index 3016abee464da..140c2013738de 100644 --- a/src/libstd/list.rs +++ b/src/libstd/list.rs @@ -9,7 +9,6 @@ // except according to those terms. //! A standard linked list -#[forbid(deprecated_mode)]; use core::cmp::Eq; use core::option; diff --git a/src/libstd/md4.rs b/src/libstd/md4.rs index 718e805b5d925..1d831af0e292a 100644 --- a/src/libstd/md4.rs +++ b/src/libstd/md4.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[forbid(deprecated_mode)]; - use core::str; use core::uint; use core::vec; diff --git a/src/libstd/net_ip.rs b/src/libstd/net_ip.rs index f4fd69aae1e12..511e80b0160f6 100644 --- a/src/libstd/net_ip.rs +++ b/src/libstd/net_ip.rs @@ -9,7 +9,6 @@ // except according to those terms. //! Types/fns concerning Internet Protocol (IP), versions 4 & 6 -#[forbid(deprecated_mode)]; use core::libc; use core::prelude::*; diff --git a/src/libstd/net_tcp.rs b/src/libstd/net_tcp.rs index 429bd6ae47455..c90518f1692b1 100644 --- a/src/libstd/net_tcp.rs +++ b/src/libstd/net_tcp.rs @@ -10,6 +10,7 @@ //! High-level interface to libuv's TCP functionality // FIXME #4425: Need FFI fixes + #[allow(deprecated_mode)]; use future; diff --git a/src/libstd/net_url.rs b/src/libstd/net_url.rs index b32c97c699837..9403438dde0ea 100644 --- a/src/libstd/net_url.rs +++ b/src/libstd/net_url.rs @@ -9,7 +9,8 @@ // except according to those terms. //! Types/fns concerning URLs (see RFC 3986) -#[forbid(deprecated_mode)]; + +#[allow(deprecated_mode)]; use core::cmp::Eq; use core::dvec::DVec; diff --git a/src/libstd/oldmap.rs b/src/libstd/oldmap.rs index 18cfc8d4a2d53..ad7e8e50e38f0 100644 --- a/src/libstd/oldmap.rs +++ b/src/libstd/oldmap.rs @@ -9,7 +9,6 @@ // except according to those terms. //! A map type - **deprecated**, use `core::hashmap` instead -#[forbid(deprecated_mode)]; use core::container::{Container, Mutable, Map}; use core::cmp::Eq; diff --git a/src/libstd/par.rs b/src/libstd/par.rs index 779dda0ab2976..8293ff1c2afdf 100644 --- a/src/libstd/par.rs +++ b/src/libstd/par.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[forbid(deprecated_mode)]; - use core::cast; use core::prelude::*; use core::ptr; @@ -38,7 +36,7 @@ const min_granularity : uint = 1024u; */ fn map_slices( xs: &[A], - f: fn() -> fn~(uint, v: &[A]) -> B) + f: &fn() -> ~fn(uint, v: &[A]) -> B) -> ~[B] { let len = xs.len(); @@ -93,9 +91,9 @@ fn map_slices( /// A parallel version of map. pub fn map( - xs: &[A], f: fn~(&A) -> B) -> ~[B] { + xs: &[A], fn_factory: &fn() -> ~fn(&A) -> B) -> ~[B] { vec::concat(map_slices(xs, || { - let f = copy f; + let f = fn_factory(); fn~(_base: uint, slice : &[A]) -> ~[B] { vec::map(slice, |x| f(x)) } @@ -103,10 +101,12 @@ pub fn map( } /// A parallel version of mapi. -pub fn mapi(xs: &[A], - f: fn~(uint, &A) -> B) -> ~[B] { +pub fn mapi( + xs: &[A], + fn_factory: &fn() -> ~fn(uint, &A) -> B) -> ~[B] +{ let slices = map_slices(xs, || { - let f = copy f; + let f = fn_factory(); fn~(base: uint, slice : &[A], copy f) -> ~[B] { vec::mapi(slice, |i, x| { f(i + base, x) @@ -119,32 +119,13 @@ pub fn mapi(xs: &[A], r } -/** - * A parallel version of mapi. - * - * In this case, f is a function that creates functions to run over the - * inner elements. This is to skirt the need for copy constructors. - */ -pub fn mapi_factory( - xs: &[A], f: fn() -> fn~(uint, A) -> B) -> ~[B] { - let slices = map_slices(xs, || { - let f = f(); - fn~(base: uint, slice : &[A], move f) -> ~[B] { - vec::mapi(slice, |i, x| { - f(i + base, *x) - }) - } - }); - let r = vec::concat(slices); - log(info, (r.len(), xs.len())); - assert(r.len() == xs.len()); - r -} - /// Returns true if the function holds for all elements in the vector. -pub fn alli(xs: &[A], f: fn~(uint, &A) -> bool) -> bool { +pub fn alli( + xs: &[A], + fn_factory: &fn() -> ~fn(uint, &A) -> bool) -> bool +{ do vec::all(map_slices(xs, || { - let f = copy f; + let f = fn_factory(); fn~(base: uint, slice : &[A], copy f) -> bool { vec::alli(slice, |i, x| { f(i + base, x) @@ -154,9 +135,11 @@ pub fn alli(xs: &[A], f: fn~(uint, &A) -> bool) -> bool { } /// Returns true if the function holds for any elements in the vector. -pub fn any(xs: &[A], f: fn~(&A) -> bool) -> bool { +pub fn any( + xs: &[A], + fn_factory: &fn() -> ~fn(&A) -> bool) -> bool { do vec::any(map_slices(xs, || { - let f = copy f; + let f = fn_factory(); fn~(_base : uint, slice: &[A], copy f) -> bool { vec::any(slice, |x| f(x)) } diff --git a/src/libstd/prettyprint.rs b/src/libstd/prettyprint.rs index d07c29d624ce5..dc2e3d3da2bd4 100644 --- a/src/libstd/prettyprint.rs +++ b/src/libstd/prettyprint.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[forbid(deprecated_mode)]; - use serialize; use core::io::Writer; diff --git a/src/libstd/rl.rs b/src/libstd/rl.rs index 5dd2a0563270b..30baa3cc5f15a 100644 --- a/src/libstd/rl.rs +++ b/src/libstd/rl.rs @@ -64,7 +64,7 @@ pub unsafe fn read(prompt: ~str) -> Option<~str> { } } -pub type CompletionCb = fn~(~str, fn(~str)); +pub type CompletionCb = @fn(~str, fn(~str)); fn complete_key(_v: @CompletionCb) {} @@ -75,7 +75,7 @@ pub unsafe fn complete(cb: CompletionCb) { extern fn callback(line: *c_char, completions: *()) { unsafe { - let cb = copy *task::local_data::local_data_get(complete_key) + let cb = *task::local_data::local_data_get(complete_key) .get(); do cb(str::raw::from_c_str(line)) |suggestion| { diff --git a/src/libstd/rope.rs b/src/libstd/rope.rs index c7601f6b6b5f5..f8aef2c5f1e99 100644 --- a/src/libstd/rope.rs +++ b/src/libstd/rope.rs @@ -33,8 +33,6 @@ * * access to a character by index is logarithmic (linear in strings); */ -#[forbid(deprecated_mode)]; - use core::cast; use core::char; use core::option; diff --git a/src/libstd/serialize.rs b/src/libstd/serialize.rs index 4938ead9ea814..972df73d21609 100644 --- a/src/libstd/serialize.rs +++ b/src/libstd/serialize.rs @@ -14,7 +14,6 @@ Core encoding and decoding interfaces. */ -#[forbid(deprecated_mode)]; #[forbid(non_camel_case_types)]; use core::at_vec; diff --git a/src/libstd/sha1.rs b/src/libstd/sha1.rs index 5fb7d892c58ca..6209170ac3d1f 100644 --- a/src/libstd/sha1.rs +++ b/src/libstd/sha1.rs @@ -22,8 +22,6 @@ * the `reset` method. */ -#[forbid(deprecated_mode)]; - use core::str; use core::uint; use core::vec; diff --git a/src/libstd/smallintmap.rs b/src/libstd/smallintmap.rs index 1cd35722ab466..9af596eb1f5f8 100644 --- a/src/libstd/smallintmap.rs +++ b/src/libstd/smallintmap.rs @@ -12,7 +12,6 @@ * A simple map based on a vector for small integer keys. Space requirements * are O(highest integer key). */ -#[forbid(deprecated_mode)]; use core::container::{Container, Mutable, Map, Set}; use core::option::{Some, None}; diff --git a/src/libstd/sort.rs b/src/libstd/sort.rs index 6e89cd9e24f92..680a2b99c4a2e 100644 --- a/src/libstd/sort.rs +++ b/src/libstd/sort.rs @@ -9,7 +9,6 @@ // except according to those terms. //! Sorting methods -#[forbid(deprecated_mode)]; use core::cmp::{Eq, Ord}; use core::dvec::DVec; @@ -64,14 +63,13 @@ pub pure fn merge_sort(v: &[const T], le: Le) -> ~[T] { } } -fn part(arr: &mut [T], left: uint, - right: uint, pivot: uint, compare_func: Le) -> uint { - let pivot_value = arr[pivot]; +fn part(arr: &mut [T], left: uint, + right: uint, pivot: uint, compare_func: Le) -> uint { arr[pivot] <-> arr[right]; let mut storage_index: uint = left; let mut i: uint = left; while i < right { - if compare_func(&arr[i], &pivot_value) { + if compare_func(&arr[i], &arr[right]) { arr[i] <-> arr[storage_index]; storage_index += 1; } @@ -81,8 +79,8 @@ fn part(arr: &mut [T], left: uint, return storage_index; } -fn qsort(arr: &mut [T], left: uint, - right: uint, compare_func: Le) { +fn qsort(arr: &mut [T], left: uint, + right: uint, compare_func: Le) { if right > left { let pivot = (left + right) / 2u; let new_pivot = part::(arr, left, right, pivot, compare_func); @@ -100,7 +98,7 @@ fn qsort(arr: &mut [T], left: uint, * Has worst case O(n^2) performance, average case O(n log n). * This is an unstable sort. */ -pub fn quick_sort(arr: &mut [T], compare_func: Le) { +pub fn quick_sort(arr: &mut [T], compare_func: Le) { if len::(arr) == 0u { return; } qsort::(arr, 0u, len::(arr) - 1u, compare_func); } diff --git a/src/libstd/std.rc b/src/libstd/std.rc index a2fbc8b1db1e2..8c142908d106f 100644 --- a/src/libstd/std.rc +++ b/src/libstd/std.rc @@ -28,10 +28,6 @@ not required in or otherwise suitable for the core library. #[allow(vecs_implicitly_copyable)]; #[deny(non_camel_case_types)]; -// XXX this is set to allow because there are two methods in encoding -// that can't be silenced otherwise. Most every module is set to forbid -#[allow(deprecated_mode)]; -#[forbid(deprecated_pattern)]; #[allow(deprecated_self)]; #[no_core]; diff --git a/src/libstd/sync.rs b/src/libstd/sync.rs index 31c596c50382d..b7e75897bf1e9 100644 --- a/src/libstd/sync.rs +++ b/src/libstd/sync.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; /** * The concurrency primitives you know and love. * diff --git a/src/libstd/tempfile.rs b/src/libstd/tempfile.rs index f10d54f327192..b786d913639cd 100644 --- a/src/libstd/tempfile.rs +++ b/src/libstd/tempfile.rs @@ -10,8 +10,6 @@ //! Temporary files and directories -#[forbid(deprecated_mode)]; - use core::os; use core::prelude::*; use core::rand; diff --git a/src/libstd/term.rs b/src/libstd/term.rs index ae5949e6f183d..5616c7211c1da 100644 --- a/src/libstd/term.rs +++ b/src/libstd/term.rs @@ -9,7 +9,6 @@ // except according to those terms. //! Simple ANSI color library -#[forbid(deprecated_mode)]; use core::i32; use core::io; diff --git a/src/libstd/test.rs b/src/libstd/test.rs index 4f0b7da89aa81..e83b759f90144 100644 --- a/src/libstd/test.rs +++ b/src/libstd/test.rs @@ -15,8 +15,6 @@ // simplest interface possible for representing and running tests // while providing a base that other test frameworks may build off of. -#[forbid(deprecated_mode)]; - use getopts; use sort; use term; @@ -51,20 +49,24 @@ pub type TestName = ~str; // the test succeeds; if the function fails then the test fails. We // may need to come up with a more clever definition of test in order // to support isolation of tests into tasks. -pub type TestFn = fn~(); +pub type TestFn = ~fn(); // The definition of a single test. A test runner will run a list of // these. pub struct TestDesc { name: TestName, - testfn: TestFn, ignore: bool, should_fail: bool } +pub struct TestDescAndFn { + desc: TestDesc, + testfn: TestFn, +} + // The default console test runner. It accepts the command line // arguments and a vector of test_descs (generated at compile time). -pub fn test_main(args: &[~str], tests: &[TestDesc]) { +pub fn test_main(args: &[~str], tests: ~[TestDescAndFn]) { let opts = match parse_opts(args) { either::Left(move o) => o, @@ -124,7 +126,7 @@ struct ConsoleTestState { // A simple console test runner pub fn run_tests_console(opts: &TestOpts, - tests: &[TestDesc]) -> bool { + tests: ~[TestDescAndFn]) -> bool { fn callback(event: &TestEvent, st: @ConsoleTestState) { debug!("callback(event=%?)", event); @@ -247,17 +249,17 @@ fn print_failures(st: @ConsoleTestState) { #[test] fn should_sort_failures_before_printing_them() { + fn dummy() {} + let s = do io::with_str_writer |wr| { let test_a = TestDesc { name: ~"a", - testfn: fn~() { }, ignore: false, should_fail: false }; let test_b = TestDesc { name: ~"b", - testfn: fn~() { }, ignore: false, should_fail: false }; @@ -291,45 +293,44 @@ enum TestEvent { type MonitorMsg = (TestDesc, TestResult); fn run_tests(opts: &TestOpts, - tests: &[TestDesc], + tests: ~[TestDescAndFn], callback: fn@(e: TestEvent)) { let mut filtered_tests = filter_tests(opts, tests); - callback(TeFiltered(copy filtered_tests)); + + let filtered_descs = filtered_tests.map(|t| t.desc); + callback(TeFiltered(filtered_descs)); // It's tempting to just spawn all the tests at once, but since we have // many tests that run in other processes we would be making a big mess. let concurrency = get_concurrency(); debug!("using %u test tasks", concurrency); - let total = vec::len(filtered_tests); - let mut run_idx = 0; - let mut wait_idx = 0; - let mut done_idx = 0; + let mut remaining = filtered_tests; + vec::reverse(remaining); + let mut pending = 0; let (p, ch) = stream(); let ch = SharedChan(ch); - while done_idx < total { - while wait_idx < concurrency && run_idx < total { - let test = copy filtered_tests[run_idx]; + while pending > 0 || !remaining.is_empty() { + while pending < concurrency && !remaining.is_empty() { + let test = remaining.pop(); if concurrency == 1 { // We are doing one test at a time so we can print the name // of the test before we run it. Useful for debugging tests // that hang forever. - callback(TeWait(copy test)); + callback(TeWait(test.desc)); } - run_test(move test, ch.clone()); - wait_idx += 1; - run_idx += 1; + run_test(test, ch.clone()); + pending += 1; } - let (test, result) = p.recv(); + let (desc, result) = p.recv(); if concurrency != 1 { - callback(TeWait(copy test)); + callback(TeWait(desc)); } - callback(TeResult(move test, result)); - wait_idx -= 1; - done_idx += 1; + callback(TeResult(desc, result)); + pending -= 1; } } @@ -349,10 +350,11 @@ fn get_concurrency() -> uint { } #[allow(non_implicitly_copyable_typarams)] -pub fn filter_tests(opts: &TestOpts, - tests: &[TestDesc]) - -> ~[TestDesc] { - let mut filtered = vec::slice(tests, 0, tests.len()); +pub fn filter_tests( + opts: &TestOpts, + tests: ~[TestDescAndFn]) -> ~[TestDescAndFn] +{ + let mut filtered = tests; // Remove tests that don't match the test filter filtered = if opts.filter.is_none() { @@ -364,10 +366,10 @@ pub fn filter_tests(opts: &TestOpts, option::None => ~"" }; - fn filter_fn(test: &TestDesc, filter_str: &str) -> - Option { - if str::contains(test.name, filter_str) { - return option::Some(copy *test); + fn filter_fn(test: TestDescAndFn, filter_str: &str) -> + Option { + if str::contains(test.desc.name, filter_str) { + return option::Some(test); } else { return option::None; } } @@ -378,26 +380,26 @@ pub fn filter_tests(opts: &TestOpts, filtered = if !opts.run_ignored { move filtered } else { - fn filter(test: &TestDesc) -> Option { - if test.ignore { - return option::Some(TestDesc { - name: test.name, - testfn: copy test.testfn, - ignore: false, - should_fail: test.should_fail}); - } else { return option::None; } + fn filter(test: TestDescAndFn) -> Option { + if test.desc.ignore { + let TestDescAndFn {desc, testfn} = test; + Some(TestDescAndFn { + desc: TestDesc {ignore: false, ..desc}, + testfn: testfn + }) + } else { + None + } }; vec::filter_map(filtered, |x| filter(x)) }; // Sort the tests alphabetically - filtered = { - pure fn lteq(t1: &TestDesc, t2: &TestDesc) -> bool { - str::le(t1.name, t2.name) - } - sort::merge_sort(filtered, lteq) - }; + pure fn lteq(t1: &TestDescAndFn, t2: &TestDescAndFn) -> bool { + str::le(t1.desc.name, t2.desc.name) + } + sort::quick_sort(filtered, lteq); move filtered } @@ -407,37 +409,40 @@ struct TestFuture { wait: fn@() -> TestResult, } -pub fn run_test(test: TestDesc, monitor_ch: SharedChan) { - if test.ignore { - monitor_ch.send((copy test, TrIgnored)); +pub fn run_test(test: TestDescAndFn, monitor_ch: SharedChan) { + let TestDescAndFn {desc, testfn} = test; + + if desc.ignore { + monitor_ch.send((desc, TrIgnored)); return; } - do task::spawn |move test| { - let testfn = copy test.testfn; + let testfn_cell = ::cell::Cell(testfn); + do task::spawn { let mut result_future = None; // task::future_result(builder); task::task().unlinked().future_result(|+r| { result_future = Some(move r); - }).spawn(move testfn); + }).spawn(testfn_cell.take()); let task_result = option::unwrap(move result_future).recv(); - let test_result = calc_result(&test, task_result == task::Success); - monitor_ch.send((copy test, test_result)); + let test_result = calc_result(&desc, task_result == task::Success); + monitor_ch.send((desc, test_result)); }; } -fn calc_result(test: &TestDesc, task_succeeded: bool) -> TestResult { +fn calc_result(desc: &TestDesc, task_succeeded: bool) -> TestResult { if task_succeeded { - if test.should_fail { TrFailed } + if desc.should_fail { TrFailed } else { TrOk } } else { - if test.should_fail { TrOk } + if desc.should_fail { TrOk } else { TrFailed } } } #[cfg(test)] mod tests { - use test::{TrFailed, TrIgnored, TrOk, filter_tests, parse_opts, TestDesc}; + use test::{TrFailed, TrIgnored, TrOk, filter_tests, parse_opts, + TestDesc, TestDescAndFn}; use test::{TestOpts, run_test}; use core::either; @@ -448,11 +453,13 @@ mod tests { #[test] pub fn do_not_run_ignored_tests() { fn f() { die!(); } - let desc = TestDesc { - name: ~"whatever", + let desc = TestDescAndFn { + desc: TestDesc { + name: ~"whatever", + ignore: true, + should_fail: false + }, testfn: f, - ignore: true, - should_fail: false }; let (p, ch) = stream(); let ch = SharedChan(ch); @@ -464,11 +471,13 @@ mod tests { #[test] pub fn ignored_tests_result_in_ignored() { fn f() { } - let desc = TestDesc { - name: ~"whatever", + let desc = TestDescAndFn { + desc: TestDesc { + name: ~"whatever", + ignore: true, + should_fail: false + }, testfn: f, - ignore: true, - should_fail: false }; let (p, ch) = stream(); let ch = SharedChan(ch); @@ -481,11 +490,13 @@ mod tests { #[ignore(cfg(windows))] pub fn test_should_fail() { fn f() { die!(); } - let desc = TestDesc { - name: ~"whatever", + let desc = TestDescAndFn { + desc: TestDesc { + name: ~"whatever", + ignore: false, + should_fail: true + }, testfn: f, - ignore: false, - should_fail: true }; let (p, ch) = stream(); let ch = SharedChan(ch); @@ -497,11 +508,13 @@ mod tests { #[test] pub fn test_should_fail_but_succeeds() { fn f() { } - let desc = TestDesc { - name: ~"whatever", + let desc = TestDescAndFn { + desc: TestDesc { + name: ~"whatever", + ignore: false, + should_fail: true + }, testfn: f, - ignore: false, - should_fail: true }; let (p, ch) = stream(); let ch = SharedChan(ch); @@ -532,6 +545,8 @@ mod tests { #[test] pub fn filter_for_ignored_option() { + fn dummy() {} + // When we run ignored tests the test filter should filter out all the // unignored tests and flip the ignore flag on the rest to false @@ -542,24 +557,28 @@ mod tests { }; let tests = ~[ - TestDesc { - name: ~"1", - testfn: fn~() { }, - ignore: true, - should_fail: false, + TestDescAndFn { + desc: TestDesc { + name: ~"1", + ignore: true, + should_fail: false, + }, + testfn: dummy, }, - TestDesc { - name: ~"2", - testfn: fn~() { }, - ignore: false, - should_fail: false, + TestDescAndFn { + desc: TestDesc { + name: ~"2", + ignore: false, + should_fail: false + }, + testfn: dummy, }, ]; let filtered = filter_tests(&opts, tests); assert (vec::len(filtered) == 1); - assert (filtered[0].name == ~"1"); - assert (filtered[0].ignore == false); + assert (filtered[0].desc.name == ~"1"); + assert (filtered[0].desc.ignore == false); } #[test] @@ -579,12 +598,16 @@ mod tests { ~"test::sort_tests"]; let tests = { - let testfn = fn~() { }; + fn testfn() { } let mut tests = ~[]; for vec::each(names) |name| { - let test = TestDesc { - name: *name, testfn: copy testfn, ignore: false, - should_fail: false}; + let test = TestDescAndFn { + desc: TestDesc { + name: *name, ignore: false, + should_fail: false + }, + testfn: testfn, + }; tests.push(move test); } move tests @@ -604,7 +627,7 @@ mod tests { for vec::each(pairs) |p| { match *p { - (ref a, ref b) => { assert (*a == b.name); } + (ref a, ref b) => { assert (*a == b.desc.name); } } } } diff --git a/src/libstd/time.rs b/src/libstd/time.rs index dd25fc36d2ddf..f696d239d30df 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[forbid(deprecated_mode)]; - use core::cmp::{Eq, Ord}; use core::int; use core::libc::{c_char, c_int, c_long, size_t, time_t}; diff --git a/src/libstd/timer.rs b/src/libstd/timer.rs index f89830ed12a90..1da1bc60314d2 100644 --- a/src/libstd/timer.rs +++ b/src/libstd/timer.rs @@ -10,8 +10,6 @@ //! Utilities that leverage libuv's `uv_timer_*` API -#[forbid(deprecated_mode)]; - use uv; use uv::iotask; use uv::iotask::IoTask; diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index 3cc287b16a32e..1e90abcc03dc6 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -12,8 +12,6 @@ //! trees. The only requirement for the types is that the key implements //! `Ord`, and that the `lt` method provides a total ordering. -#[forbid(deprecated_mode)]; - use core::container::{Container, Mutable, Map, Set}; use core::cmp::{Eq, Ord}; use core::option::{Option, Some, None}; diff --git a/src/libstd/uv_global_loop.rs b/src/libstd/uv_global_loop.rs index 736954f6b222f..9763f655a6f4e 100644 --- a/src/libstd/uv_global_loop.rs +++ b/src/libstd/uv_global_loop.rs @@ -10,8 +10,6 @@ //! A process-wide libuv event loop for library use. -#[forbid(deprecated_mode)]; - use ll = uv_ll; use iotask = uv_iotask; use get_gl = get; diff --git a/src/libstd/uv_iotask.rs b/src/libstd/uv_iotask.rs index fe4137f76be9a..a44fef54b726a 100644 --- a/src/libstd/uv_iotask.rs +++ b/src/libstd/uv_iotask.rs @@ -14,7 +14,6 @@ * The I/O task runs in its own single-threaded scheduler. By using the * `interact` function you can execute code in a uv callback. */ -#[forbid(deprecated_mode)]; use ll = uv_ll; diff --git a/src/libstd/workcache.rs b/src/libstd/workcache.rs index 4e9df14419b18..b828c4ef629f5 100644 --- a/src/libstd/workcache.rs +++ b/src/libstd/workcache.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[allow(deprecated_mode)]; + use json; use sha1; use serialize::{Encoder, Encodable, Decoder, Decodable}; diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index bc808495ca33b..574ce281e2827 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -399,16 +399,46 @@ pub impl mutability : cmp::Eq { #[auto_encode] #[auto_decode] #[deriving_eq] -pub enum Proto { - ProtoBare, // bare functions (deprecated) - ProtoUniq, // ~fn - ProtoBox, // @fn - ProtoBorrowed, // &fn +pub enum Abi { + RustAbi } -pub impl Proto : to_bytes::IterBytes { +pub impl Abi : to_bytes::IterBytes { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { - (*self as uint).iter_bytes(lsb0, f); + (*self as uint).iter_bytes(lsb0, f) + } +} + +pub impl Abi : ToStr { + pure fn to_str(&self) -> ~str { + match *self { + RustAbi => ~"\"rust\"" + } + } +} + +#[auto_encode] +#[auto_decode] +#[deriving_eq] +pub enum Sigil { + BorrowedSigil, + OwnedSigil, + ManagedSigil +} + +pub impl Sigil : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + (*self as uint).iter_bytes(lsb0, f) + } +} + +pub impl Sigil : ToStr { + pure fn to_str(&self) -> ~str { + match *self { + BorrowedSigil => ~"&", + OwnedSigil => ~"~", + ManagedSigil => ~"@" + } } } @@ -434,13 +464,6 @@ pub enum expr_vstore { expr_vstore_mut_slice, // &mut [1,2,3,4] } -pub pure fn is_blockish(p: Proto) -> bool { - match p { - ProtoBorrowed => true, - ProtoBare | ProtoUniq | ProtoBox => false - } -} - #[auto_encode] #[auto_decode] pub enum binop { @@ -671,14 +694,23 @@ pub struct expr { pub enum log_level { error, debug, log_other } // 0 = error, 1 = debug, 2 = log_other +#[auto_encode] +#[auto_decode] +#[deriving_eq] +pub enum CallSugar { + NoSugar, + DoSugar, + ForSugar +} + #[auto_encode] #[auto_decode] pub enum expr_ { expr_vstore(@expr, expr_vstore), expr_vec(~[@expr], mutability), expr_rec(~[field], Option<@expr>), - expr_call(@expr, ~[@expr], bool), // True iff last argument is a block - expr_method_call(@expr, ident, ~[@Ty], ~[@expr], bool), // Ditto + expr_call(@expr, ~[@expr], CallSugar), + expr_method_call(@expr, ident, ~[@Ty], ~[@expr], CallSugar), expr_tup(~[@expr]), expr_binary(binop, @expr, @expr), expr_unary(unop, @expr), @@ -693,7 +725,7 @@ pub enum expr_ { expr_match(@expr, ~[arm]), // FIXME(#4717) the @() is req'd on windows or else LLVM croaks - expr_fn(Proto, fn_decl, blk, @()), + expr_fn(Sigil, fn_decl, blk, @()), expr_fn_block(fn_decl, blk), // Inner expr is always an expr_fn_block. We need the wrapping node to @@ -1112,12 +1144,19 @@ pub impl Onceness : to_bytes::IterBytes { #[auto_encode] #[auto_decode] -pub struct TyFn { - proto: Proto, +pub struct TyClosure { + sigil: Sigil, region: Option<@region>, purity: purity, onceness: Onceness, - bounds: @~[ty_param_bound], + decl: fn_decl +} + +#[auto_encode] +#[auto_decode] +pub struct TyBareFn { + purity: purity, + abi: Abi, decl: fn_decl } @@ -1133,7 +1172,8 @@ pub enum ty_ { ty_ptr(mt), ty_rptr(@region, mt), ty_rec(~[ty_field]), - ty_fn(@TyFn), + ty_closure(@TyClosure), + ty_bare_fn(@TyBareFn), ty_tup(~[@Ty]), ty_path(@path, node_id), ty_mac(mac), diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index ca28641c4a3bc..c347c04641f10 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -154,7 +154,7 @@ pub fn find_attrs_by_name(attrs: &[ast::attribute], name: &str) -> option::None } }; - return vec::filter_map(attrs, filter); + return vec::filter_mapped(attrs, filter); } /// Search a list of meta items and return only those with a specific name @@ -277,9 +277,9 @@ pub fn sort_meta_items(+items: ~[@ast::meta_item]) -> ~[@ast::meta_item] { pub fn remove_meta_items_by_name(items: ~[@ast::meta_item], name: ~str) -> ~[@ast::meta_item] { - return vec::filter_map(items, |item| { + return vec::filter_mapped(items, |item| { if get_meta_item_name(*item) != name { - option::Some(/* FIXME (#2543) */ copy *item) + option::Some(*item) } else { option::None } diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 31ed65d806588..a509325faceca 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -76,7 +76,7 @@ pub impl BytePos: Sub { } pub impl BytePos: to_bytes::IterBytes { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(&self, +lsb0: bool, &&f: to_bytes::Cb) { (**self).iter_bytes(lsb0, f) } } @@ -99,7 +99,7 @@ pub impl CharPos: cmp::Ord { } pub impl CharPos: to_bytes::IterBytes { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(&self, +lsb0: bool, &&f: to_bytes::Cb) { (**self).iter_bytes(lsb0, f) } } diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs index 03aa0cde81102..21154bff01e9a 100644 --- a/src/libsyntax/ext/auto_encode.rs +++ b/src/libsyntax/ext/auto_encode.rs @@ -392,7 +392,7 @@ priv impl ext_ctxt { expr: @ast::expr, args: ~[@ast::expr] ) -> @ast::expr { - self.expr(span, ast::expr_call(expr, args, false)) + self.expr(span, ast::expr_call(expr, args, ast::NoSugar)) } fn lambda_expr(expr: @ast::expr) -> @ast::expr { diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 4d8fd39c96091..a050b2316e873 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -103,7 +103,7 @@ pub fn mk_addr_of(cx: ext_ctxt, sp: span, e: @ast::expr) -> @ast::expr { } pub fn mk_call_(cx: ext_ctxt, sp: span, fn_expr: @ast::expr, args: ~[@ast::expr]) -> @ast::expr { - mk_expr(cx, sp, ast::expr_call(fn_expr, args, false)) + mk_expr(cx, sp, ast::expr_call(fn_expr, args, ast::NoSugar)) } pub fn mk_call(cx: ext_ctxt, sp: span, fn_path: ~[ast::ident], args: ~[@ast::expr]) -> @ast::expr { diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index cfa8a3c11532d..8cecbfb12101e 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -536,13 +536,18 @@ pub fn noop_fold_ty(t: ty_, fld: ast_fold) -> ty_ { ty_rptr(region, mt) => ty_rptr(region, fold_mt(mt, fld)), ty_rec(ref fields) => ty_rec(vec::map((*fields), |f| fold_field(*f, fld))), - ty_fn(f) => - ty_fn(@TyFn { - proto: f.proto, + ty_closure(f) => + ty_closure(@TyClosure { + sigil: f.sigil, purity: f.purity, region: f.region, onceness: f.onceness, - bounds: @vec::map(*f.bounds, |x| fold_ty_param_bound(*x, fld)), + decl: fold_fn_decl(f.decl, fld) + }), + ty_bare_fn(f) => + ty_bare_fn(@TyBareFn { + purity: f.purity, + abi: f.abi, decl: fold_fn_decl(f.decl, fld) }), ty_tup(tys) => ty_tup(vec::map(tys, |ty| fld.fold_ty(*ty))), @@ -557,7 +562,7 @@ pub fn noop_fold_ty(t: ty_, fld: ast_fold) -> ty_ { pub fn noop_fold_mod(m: _mod, fld: ast_fold) -> _mod { ast::_mod { view_items: vec::map(m.view_items, |x| fld.fold_view_item(*x)), - items: vec::filter_map(m.items, |x| fld.fold_item(*x)), + items: vec::filter_mapped(m.items, |x| fld.fold_item(*x)), } } diff --git a/src/libsyntax/parse/classify.rs b/src/libsyntax/parse/classify.rs index 4ceb04c55d09a..64c4cb3c508a1 100644 --- a/src/libsyntax/parse/classify.rs +++ b/src/libsyntax/parse/classify.rs @@ -23,8 +23,10 @@ pub fn expr_requires_semi_to_be_stmt(e: @ast::expr) -> bool { | ast::expr_block(_) | ast::expr_while(*) | ast::expr_loop(*) - | ast::expr_call(_, _, true) - | ast::expr_method_call(_, _, _, _, true) => false, + | ast::expr_call(_, _, ast::DoSugar) + | ast::expr_call(_, _, ast::ForSugar) + | ast::expr_method_call(_, _, _, _, ast::DoSugar) + | ast::expr_method_call(_, _, _, _, ast::ForSugar) => false, _ => true } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 5cd78dd90490b..7fb3064c388f1 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -10,7 +10,10 @@ use core::prelude::*; -use ast::{ProtoBox, ProtoUniq, RegionTyParamBound, TraitTyParamBound}; +use ast::{Sigil, BorrowedSigil, ManagedSigil, OwnedSigil, RustAbi}; +use ast::{CallSugar, NoSugar, DoSugar, ForSugar}; +use ast::{TyBareFn, TyClosure}; +use ast::{RegionTyParamBound, TraitTyParamBound}; use ast::{provided, public, pure_fn, purity, re_static}; use ast::{_mod, add, arg, arm, attribute, bind_by_ref, bind_infer}; use ast::{bind_by_copy, bitand, bitor, bitxor, blk}; @@ -27,7 +30,7 @@ use ast::{expr_ret, expr_swap, expr_struct, expr_tup, expr_unary}; use ast::{expr_vec, expr_vstore, expr_vstore_mut_box}; use ast::{expr_vstore_fixed, expr_vstore_slice, expr_vstore_box}; use ast::{expr_vstore_mut_slice, expr_while, extern_fn, field, fn_decl}; -use ast::{expr_vstore_uniq, TyFn, Onceness, Once, Many}; +use ast::{expr_vstore_uniq, TyClosure, TyBareFn, Onceness, Once, Many}; use ast::{foreign_item, foreign_item_const, foreign_item_fn, foreign_mod}; use ast::{ident, impure_fn, infer, inherited, item, item_, item_const}; use ast::{item_const, item_enum, item_fn, item_foreign_mod, item_impl}; @@ -38,15 +41,16 @@ use ast::{m_imm, m_mutbl, mac_, mac_invoc_tt, matcher, match_nonterminal}; use ast::{match_seq, match_tok, method, mode, module_ns, mt, mul, mutability}; use ast::{named_field, neg, node_id, noreturn, not, pat, pat_box, pat_enum}; use ast::{pat_ident, pat_lit, pat_range, pat_rec, pat_region, pat_struct}; -use ast::{pat_tup, pat_uniq, pat_wild, path, private, Proto, ProtoBare}; -use ast::{ProtoBorrowed, re_self, re_anon, re_named, region, rem, required}; +use ast::{pat_tup, pat_uniq, pat_wild, path, private}; +use ast::{re_self, re_anon, re_named, region, rem, required}; use ast::{ret_style, return_val, self_ty, shl, shr, stmt, stmt_decl}; use ast::{stmt_expr, stmt_semi, stmt_mac, struct_def, struct_field}; use ast::{struct_immutable, struct_mutable, struct_variant_kind, subtract}; use ast::{sty_box, sty_by_ref, sty_region, sty_static, sty_uniq, sty_value}; use ast::{token_tree, trait_method, trait_ref, tt_delim, tt_seq, tt_tok}; use ast::{tt_nonterminal, tuple_variant_kind, Ty, ty_, ty_bot, ty_box}; -use ast::{ty_field, ty_fixed_length_vec, ty_fn, ty_infer, ty_mac, ty_method}; +use ast::{ty_field, ty_fixed_length_vec, ty_closure, ty_bare_fn}; +use ast::{ty_infer, ty_mac, ty_method}; use ast::{ty_nil, ty_param, ty_param_bound, ty_path, ty_ptr, ty_rec, ty_rptr}; use ast::{ty_tup, ty_u32, ty_uniq, ty_vec, type_value_ns, uniq}; use ast::{unnamed_field, unsafe_blk, unsafe_fn, variant, view_item}; @@ -293,25 +297,49 @@ pub impl Parser { pure fn id_to_str(id: ident) -> @~str { self.sess.interner.get(id) } - fn token_is_fn_keyword(+tok: token::Token) -> bool { + fn token_is_closure_keyword(+tok: token::Token) -> bool { self.token_is_keyword(~"pure", tok) || self.token_is_keyword(~"unsafe", tok) || self.token_is_keyword(~"once", tok) || - self.token_is_keyword(~"fn", tok) || - self.token_is_keyword(~"extern", tok) + self.token_is_keyword(~"fn", tok) } - fn parse_ty_fn(pre_proto: Option, - pre_region_name: Option) -> ty_ + fn parse_ty_bare_fn() -> ty_ { /* - (&|~|@) [r/] [pure|unsafe] [once] fn [:K] (S) -> T - ^~~~~~^ ^~~^ ^~~~~~~~~~~~^ ^~~~~^ ^~~^ ^~^ ^ - | | | | | | | - | | | | | | Return type - | | | | | Argument types - | | | | Environment bounds + extern "ABI" [pure|unsafe] fn (S) -> T + ^~~~^ ^~~~~~~~~~~~^ ^~^ ^ + | | | | + | | | Return type + | | Argument types + | | + | | + | Purity + ABI + + */ + + let purity = self.parse_purity(); + self.expect_keyword(~"fn"); + return ty_bare_fn(@TyBareFn { + abi: RustAbi, + purity: purity, + decl: self.parse_ty_fn_decl() + }); + } + + fn parse_ty_closure(pre_sigil: Option, + pre_region_name: Option) -> ty_ + { + /* + + (&|~|@) [r/] [pure|unsafe] [once] fn (S) -> T + ^~~~~~^ ^~~^ ^~~~~~~~~~~~^ ^~~~~^ ^~^ ^ + | | | | | | + | | | | | Return type + | | | | Argument types + | | | | | | | Once-ness (a.k.a., affine) | | Purity | Lifetime bound @@ -322,22 +350,13 @@ pub impl Parser { // At this point, the allocation type and lifetime bound have been // parsed. - let purity = parse_purity(&self); + let purity = self.parse_purity(); let onceness = parse_onceness(&self); + self.expect_keyword(~"fn"); + let post_sigil = self.parse_fn_ty_sigil(); - let bounds, post_proto; - if self.eat_keyword(~"extern") { - self.expect_keyword(~"fn"); - post_proto = Some(ast::ProtoBare); - bounds = @~[]; - } else { - self.expect_keyword(~"fn"); - post_proto = self.parse_fn_ty_proto(); - bounds = self.parse_optional_ty_param_bounds(); - }; - - let proto = match (pre_proto, post_proto) { - (None, None) => ast::ProtoBorrowed, + let sigil = match (pre_sigil, post_sigil) { + (None, None) => BorrowedSigil, (Some(p), None) | (None, Some(p)) => p, (Some(_), Some(_)) => { self.fatal(~"cannot combine prefix and postfix \ @@ -352,30 +371,28 @@ pub impl Parser { None }; - return ty_fn(@TyFn { - proto: proto, + return ty_closure(@TyClosure { + sigil: sigil, region: region, purity: purity, onceness: onceness, - bounds: bounds, decl: self.parse_ty_fn_decl() }); - fn parse_purity(self: &Parser) -> purity { - if self.eat_keyword(~"pure") { - return pure_fn; - } else if self.eat_keyword(~"unsafe") { - return unsafe_fn; - } else { - return impure_fn; - } - } - fn parse_onceness(self: &Parser) -> Onceness { if self.eat_keyword(~"once") {Once} else {Many} } } + fn parse_purity() -> purity { + if self.eat_keyword(~"pure") { + return pure_fn; + } else if self.eat_keyword(~"unsafe") { + return unsafe_fn; + } else { + return impure_fn; + } + } fn parse_ty_fn_decl() -> fn_decl { let inputs = do self.parse_unspanned_seq( @@ -560,10 +577,10 @@ pub impl Parser { } } else if self.token == token::AT { self.bump(); - self.parse_box_or_uniq_pointee(ast::ProtoBox, ty_box) + self.parse_box_or_uniq_pointee(ManagedSigil, ty_box) } else if self.token == token::TILDE { self.bump(); - self.parse_box_or_uniq_pointee(ast::ProtoUniq, ty_uniq) + self.parse_box_or_uniq_pointee(OwnedSigil, ty_uniq) } else if self.token == token::BINOP(token::STAR) { self.bump(); ty_ptr(self.parse_mt()) @@ -590,8 +607,10 @@ pub impl Parser { } else if self.token == token::BINOP(token::AND) { self.bump(); self.parse_borrowed_pointee() - } else if self.token_is_fn_keyword(self.token) { - self.parse_ty_fn(None, None) + } else if self.eat_keyword(~"extern") { + self.parse_ty_bare_fn() + } else if self.token_is_closure_keyword(self.token) { + self.parse_ty_closure(None, None) } else if self.token == token::MOD_SEP || is_ident_or_path(self.token) { let path = self.parse_path_with_tps(colons_before_params); @@ -603,19 +622,19 @@ pub impl Parser { } fn parse_box_or_uniq_pointee( - proto: ast::Proto, + sigil: ast::Sigil, ctor: &fn(+v: mt) -> ty_) -> ty_ { // @foo/fn() or @fn() are parsed directly as fn types: match copy self.token { token::IDENT(rname, _) => { if self.look_ahead(1u) == token::BINOP(token::SLASH) && - self.token_is_fn_keyword(self.look_ahead(2u)) + self.token_is_closure_keyword(self.look_ahead(2u)) { self.bump(); self.bump(); - return self.parse_ty_fn(Some(proto), Some(rname)); - } else if self.token_is_fn_keyword(self.token) { - return self.parse_ty_fn(Some(proto), None); + return self.parse_ty_closure(Some(sigil), Some(rname)); + } else if self.token_is_closure_keyword(self.token) { + return self.parse_ty_closure(Some(sigil), None); } } _ => {} @@ -643,8 +662,8 @@ pub impl Parser { _ => { None } }; - if self.token_is_fn_keyword(self.token) { - return self.parse_ty_fn(Some(ProtoBorrowed), rname); + if self.token_is_closure_keyword(self.token) { + return self.parse_ty_closure(Some(BorrowedSigil), rname); } let r = self.region_from_name(rname); @@ -981,9 +1000,11 @@ pub impl Parser { } else if self.eat_keyword(~"if") { return self.parse_if_expr(); } else if self.eat_keyword(~"for") { - return self.parse_sugary_call_expr(~"for", expr_loop_body); + return self.parse_sugary_call_expr(~"for", ForSugar, + expr_loop_body); } else if self.eat_keyword(~"do") { - return self.parse_sugary_call_expr(~"do", expr_do_body); + return self.parse_sugary_call_expr(~"do", DoSugar, + expr_do_body); } else if self.eat_keyword(~"while") { return self.parse_while_expr(); } else if self.eat_keyword(~"loop") { @@ -991,14 +1012,14 @@ pub impl Parser { } else if self.eat_keyword(~"match") { return self.parse_match_expr(); } else if self.eat_keyword(~"fn") { - let opt_proto = self.parse_fn_ty_proto(); - let proto = match opt_proto { - None | Some(ast::ProtoBare) => { + let opt_sigil = self.parse_fn_ty_sigil(); + let sigil = match opt_sigil { + None => { self.fatal(~"fn expr are deprecated, use fn@") } Some(p) => { p } }; - return self.parse_fn_expr(proto); + return self.parse_fn_expr(sigil); } else if self.eat_keyword(~"unsafe") { return self.parse_block_expr(lo, unsafe_blk); } else if self.token == token::LBRACKET { @@ -1176,7 +1197,7 @@ pub impl Parser { |p| p.parse_expr()); hi = self.span.hi; - let nd = expr_method_call(e, i, tys, es, false); + let nd = expr_method_call(e, i, tys, es, NoSugar); e = self.mk_expr(lo, hi, move nd); } _ => { @@ -1198,7 +1219,7 @@ pub impl Parser { |p| p.parse_expr()); hi = self.span.hi; - let nd = expr_call(e, es, false); + let nd = expr_call(e, es, NoSugar); e = self.mk_expr(lo, hi, nd); } @@ -1566,7 +1587,7 @@ pub impl Parser { self.mk_expr(q.lo, q.hi, expr_if(q.cond, q.then, q.els)) } - fn parse_fn_expr(proto: Proto) -> @expr { + fn parse_fn_expr(sigil: Sigil) -> @expr { let lo = self.last_span.lo; // if we want to allow fn expression argument types to be inferred in @@ -1576,7 +1597,7 @@ pub impl Parser { let body = self.parse_block(); self.mk_expr(lo, body.span.hi, - expr_fn(proto, decl, body, @())) + expr_fn(sigil, decl, body, @())) } // `|args| { ... }` like in `do` expressions @@ -1641,6 +1662,7 @@ pub impl Parser { } fn parse_sugary_call_expr(keyword: ~str, + sugar: CallSugar, ctor: fn(+v: @expr) -> expr_) -> @expr { let lo = self.last_span; // Parse the callee `foo` in @@ -1654,27 +1676,27 @@ pub impl Parser { // them as the lambda arguments let e = self.parse_expr_res(RESTRICT_NO_BAR_OR_DOUBLEBAR_OP); match e.node { - expr_call(f, args, false) => { + expr_call(f, args, NoSugar) => { let block = self.parse_lambda_block_expr(); let last_arg = self.mk_expr(block.span.lo, block.span.hi, ctor(block)); let args = vec::append(args, ~[last_arg]); - self.mk_expr(lo.lo, block.span.hi, expr_call(f, args, true)) + self.mk_expr(lo.lo, block.span.hi, expr_call(f, args, sugar)) } - expr_method_call(f, i, tps, args, false) => { + expr_method_call(f, i, tps, args, NoSugar) => { let block = self.parse_lambda_block_expr(); let last_arg = self.mk_expr(block.span.lo, block.span.hi, ctor(block)); let args = vec::append(args, ~[last_arg]); self.mk_expr(lo.lo, block.span.hi, - expr_method_call(f, i, tps, args, true)) + expr_method_call(f, i, tps, args, sugar)) } expr_field(f, i, tps) => { let block = self.parse_lambda_block_expr(); let last_arg = self.mk_expr(block.span.lo, block.span.hi, ctor(block)); self.mk_expr(lo.lo, block.span.hi, - expr_method_call(f, i, tps, ~[last_arg], true)) + expr_method_call(f, i, tps, ~[last_arg], sugar)) } expr_path(*) | expr_call(*) | expr_method_call(*) | expr_paren(*) => { @@ -1682,7 +1704,7 @@ pub impl Parser { let last_arg = self.mk_expr(block.span.lo, block.span.hi, ctor(block)); self.mk_expr(lo.lo, last_arg.span.hi, - expr_call(e, ~[last_arg], true)) + expr_call(e, ~[last_arg], sugar)) } _ => { // There may be other types of expressions that can @@ -3592,19 +3614,19 @@ pub impl Parser { (id, item_enum(enum_definition, ty_params), None) } - fn parse_fn_ty_proto() -> Option { + fn parse_fn_ty_sigil() -> Option { match self.token { token::AT => { self.bump(); - Some(ProtoBox) + Some(ManagedSigil) } token::TILDE => { self.bump(); - Some(ProtoUniq) + Some(OwnedSigil) } token::BINOP(token::AND) => { self.bump(); - Some(ProtoBorrowed) + Some(BorrowedSigil) } _ => { None diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 5079766239b00..bcbee7b2f2444 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -404,9 +404,15 @@ pub fn print_type_ex(s: ps, &&ty: @ast::Ty, print_colons: bool) { commasep(s, inconsistent, elts, print_type); pclose(s); } - ast::ty_fn(f) => { - print_ty_fn(s, Some(f.proto), f.region, f.purity, - f.onceness, f.bounds, f.decl, None, None, None); + ast::ty_bare_fn(f) => { + print_ty_fn(s, Some(f.abi), None, None, + f.purity, ast::Many, f.decl, None, + None, None); + } + ast::ty_closure(f) => { + print_ty_fn(s, None, Some(f.sigil), f.region, + f.purity, f.onceness, f.decl, None, + None, None); } ast::ty_path(path, _) => print_path(s, path, print_colons), ast::ty_fixed_length_vec(mt, v) => { @@ -806,8 +812,8 @@ pub fn print_ty_method(s: ps, m: ast::ty_method) { hardbreak_if_not_bol(s); maybe_print_comment(s, m.span.lo); print_outer_attributes(s, m.attrs); - print_ty_fn(s, None, None, m.purity, ast::Many, - @~[], m.decl, Some(m.ident), Some(m.tps), + print_ty_fn(s, None, None, None, m.purity, ast::Many, + m.decl, Some(m.ident), Some(m.tps), Some(m.self_ty.node)); word(s.s, ~";"); } @@ -1046,32 +1052,32 @@ pub fn print_expr_vstore(s: ps, t: ast::expr_vstore) { } pub fn print_call_pre(s: ps, - has_block: bool, + sugar: ast::CallSugar, base_args: &mut ~[@ast::expr]) -> Option<@ast::expr> { - if has_block { - let blk_arg = base_args.pop(); - match blk_arg.node { - ast::expr_loop_body(_) => { head(s, ~"for"); } - ast::expr_do_body(_) => { head(s, ~"do"); } - _ => {} - } - Some(blk_arg) - } else { - None + match sugar { + ast::DoSugar => { + head(s, ~"do"); + Some(base_args.pop()) + } + ast::ForSugar => { + head(s, ~"for"); + Some(base_args.pop()) + } + ast::NoSugar => None } } pub fn print_call_post(s: ps, - has_block: bool, + sugar: ast::CallSugar, blk: &Option<@ast::expr>, base_args: &mut ~[@ast::expr]) { - if !has_block || !base_args.is_empty() { + if sugar == ast::NoSugar || !base_args.is_empty() { popen(s); commasep_exprs(s, inconsistent, *base_args); pclose(s); } - if has_block { + if sugar != ast::NoSugar { nbsp(s); match blk.get().node { // need to handle closures specifically @@ -1181,15 +1187,15 @@ pub fn print_expr(s: ps, &&expr: @ast::expr) { commasep_exprs(s, inconsistent, exprs); pclose(s); } - ast::expr_call(func, args, has_block) => { + ast::expr_call(func, args, sugar) => { let mut base_args = copy args; - let blk = print_call_pre(s, has_block, &mut base_args); + let blk = print_call_pre(s, sugar, &mut base_args); print_expr(s, func); - print_call_post(s, has_block, &blk, &mut base_args); + print_call_post(s, sugar, &blk, &mut base_args); } - ast::expr_method_call(func, ident, tys, args, has_block) => { + ast::expr_method_call(func, ident, tys, args, sugar) => { let mut base_args = copy args; - let blk = print_call_pre(s, has_block, &mut base_args); + let blk = print_call_pre(s, sugar, &mut base_args); print_expr(s, func); word(s.s, ~"."); print_ident(s, ident); @@ -1198,7 +1204,7 @@ pub fn print_expr(s: ps, &&expr: @ast::expr) { commasep(s, inconsistent, tys, print_type); word(s.s, ~">"); } - print_call_post(s, has_block, &blk, &mut base_args); + print_call_post(s, sugar, &blk, &mut base_args); } ast::expr_binary(op, lhs, rhs) => { print_expr(s, lhs); @@ -1305,13 +1311,13 @@ pub fn print_expr(s: ps, &&expr: @ast::expr) { } bclose_(s, expr.span, match_indent_unit); } - ast::expr_fn(proto, decl, ref body, _) => { + ast::expr_fn(sigil, decl, ref body, _) => { // containing cbox, will be closed by print-block at } cbox(s, indent_unit); // head-box, will be closed by print-block at start ibox(s, 0u); print_fn_header_info(s, None, None, ast::Many, - Some(proto), ast::inherited); + Some(sigil), ast::inherited); print_fn_args_and_ret(s, decl, None); space(s.s); print_block(s, (*body)); @@ -1900,33 +1906,32 @@ pub fn print_arg(s: ps, input: ast::arg) { } pub fn print_ty_fn(s: ps, - opt_proto: Option, + opt_abi: Option, + opt_sigil: Option, opt_region: Option<@ast::region>, purity: ast::purity, onceness: ast::Onceness, - bounds: @~[ast::ty_param_bound], decl: ast::fn_decl, id: Option, tps: Option<~[ast::ty_param]>, opt_self_ty: Option) { ibox(s, indent_unit); // Duplicates the logic in `print_fn_header_info()`. This is because that - // function prints the proto in the wrong place. That should be fixed. + // function prints the sigil in the wrong place. That should be fixed. print_self_ty_if_static(s, opt_self_ty); - print_opt_proto(s, opt_proto); + print_opt_abi(s, opt_abi); + print_opt_sigil(s, opt_sigil); for opt_region.each |r| { print_region(s, ~"", *r, ~"/"); } print_purity(s, purity); print_onceness(s, onceness); word(s.s, ~"fn"); - print_bounds(s, bounds); match id { Some(id) => { word(s.s, ~" "); print_ident(s, id); } _ => () } match tps { Some(tps) => print_type_params(s, tps), _ => () } zerobreak(s.s); popen(s); - // It is unfortunate to duplicate the commasep logic, but we - // we want the self type, the args, and the capture clauses all - // in the same box. + // It is unfortunate to duplicate the commasep logic, but we we want the + // self type and the args all in the same box. box(s, 0u, inconsistent); let mut first = true; for opt_self_ty.each |self_ty| { @@ -2157,12 +2162,18 @@ pub fn print_opt_purity(s: ps, opt_purity: Option) { } } -pub fn print_opt_proto(s: ps, opt_proto: Option) { - match opt_proto { - Some(ast::ProtoBare) => { word(s.s, ~"extern "); } - Some(ast::ProtoBorrowed) => { word(s.s, ~"&"); } - Some(ast::ProtoUniq) => { word(s.s, ~"~"); } - Some(ast::ProtoBox) => { word(s.s, ~"@"); } +pub fn print_opt_abi(s: ps, opt_abi: Option) { + match opt_abi { + Some(ast::RustAbi) => { word_nbsp(s, ~"extern"); } + None => {} + }; +} + +pub fn print_opt_sigil(s: ps, opt_sigil: Option) { + match opt_sigil { + Some(ast::BorrowedSigil) => { word(s.s, ~"&"); } + Some(ast::OwnedSigil) => { word(s.s, ~"~"); } + Some(ast::ManagedSigil) => { word(s.s, ~"@"); } None => {} }; } @@ -2171,20 +2182,20 @@ pub fn print_fn_header_info(s: ps, opt_sty: Option, opt_purity: Option, onceness: ast::Onceness, - opt_proto: Option, + opt_sigil: Option, vis: ast::visibility) { print_self_ty_if_static(s, opt_sty); word(s.s, visibility_qualified(vis, ~"")); print_opt_purity(s, opt_purity); print_onceness(s, onceness); word(s.s, ~"fn"); - print_opt_proto(s, opt_proto); + print_opt_sigil(s, opt_sigil); } -pub fn opt_proto_to_str(opt_p: Option) -> ~str { +pub fn opt_sigil_to_str(opt_p: Option) -> ~str { match opt_p { None => ~"fn", - Some(p) => proto_to_str(p) + Some(p) => fmt!("fn%s", p.to_str()) } } @@ -2218,15 +2229,6 @@ pub fn print_onceness(s: ps, o: ast::Onceness) { } } -pub fn proto_to_str(p: ast::Proto) -> ~str { - return match p { - ast::ProtoBare => ~"extern fn", - ast::ProtoBorrowed => ~"fn&", - ast::ProtoUniq => ~"fn~", - ast::ProtoBox => ~"fn@" - }; -} - #[cfg(test)] pub mod test { use ast; diff --git a/src/libsyntax/syntax.rc b/src/libsyntax/syntax.rc index a6d50b9cf0908..877817af06c18 100644 --- a/src/libsyntax/syntax.rc +++ b/src/libsyntax/syntax.rc @@ -22,7 +22,6 @@ #[allow(vecs_implicitly_copyable)]; #[allow(non_camel_case_types)]; #[allow(deprecated_mode)]; -#[warn(deprecated_pattern)]; #[allow(deprecated_self)]; #[no_core]; diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index eea1a6906e44a..37b96e0565370 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -30,10 +30,10 @@ use core::vec; pub enum vt { mk_vt(visitor), } pub enum fn_kind { - fk_item_fn(ident, ~[ty_param], purity), //< an item declared with fn() - fk_method(ident, ~[ty_param], @method), - fk_anon(Proto), //< an anonymous function like fn@(...) - fk_fn_block, //< a block {||...} + fk_item_fn(ident, ~[ty_param], purity), // fn foo() + fk_method(ident, ~[ty_param], @method), // fn foo(&self) + fk_anon(ast::Sigil), // fn@(x, y) { ... } + fk_fn_block, // |x, y| ... fk_dtor(~[ty_param], ~[attribute], node_id /* self id */, def_id /* parent class id */) // class destructor @@ -217,9 +217,12 @@ pub fn visit_ty(t: @Ty, e: E, v: vt) { ty_tup(ts) => for ts.each |tt| { (v.visit_ty)(*tt, e, v); }, - ty_fn(f) => { + ty_closure(f) => { + for f.decl.inputs.each |a| { (v.visit_ty)(a.ty, e, v); } + (v.visit_ty)(f.decl.output, e, v); + } + ty_bare_fn(f) => { for f.decl.inputs.each |a| { (v.visit_ty)(a.ty, e, v); } - visit_ty_param_bounds(f.bounds, e, v); (v.visit_ty)(f.decl.output, e, v); } ty_path(p, _) => visit_path(p, e, v), diff --git a/src/test/bench/graph500-bfs.rs b/src/test/bench/graph500-bfs.rs index 5ade0c9ed25db..222307bd240df 100644 --- a/src/test/bench/graph500-bfs.rs +++ b/src/test/bench/graph500-bfs.rs @@ -9,6 +9,7 @@ // except according to those terms. #[legacy_modes]; +#[allow(deprecated_mode)]; /*! @@ -247,8 +248,13 @@ fn pbfs(&&graph: arc::ARC, key: node_id) -> bfs_result { } } + fn is_gray_factory() -> ~fn(c: &color) -> bool { + let r: ~fn(c: &color) -> bool = is_gray; + r + } + let mut i = 0; - while par::any(colors, is_gray) { + while par::any(colors, is_gray_factory) { // Do the BFS. log(info, fmt!("PBFS iteration %?", i)); i += 1; @@ -257,14 +263,13 @@ fn pbfs(&&graph: arc::ARC, key: node_id) -> bfs_result { let color = arc::ARC(move colors); let color_vec = arc::get(&color); // FIXME #3387 requires this temp - colors = do par::mapi_factory(*color_vec) { + colors = do par::mapi(*color_vec) { let colors = arc::clone(&color); let graph = arc::clone(&graph); - fn~(move graph, move colors, +i: uint, +c: color) -> color { - let c : color = c; + fn~(+i: uint, +c: &color) -> color { let colors = arc::get(&colors); let graph = arc::get(&graph); - match c { + match *c { white => { let i = i as node_id; @@ -290,11 +295,13 @@ fn pbfs(&&graph: arc::ARC, key: node_id) -> bfs_result { } // Convert the results. - do par::map(colors) |c| { - match *c { - white => { -1i64 } - black(parent) => { parent } - _ => { die!(~"Found remaining gray nodes in BFS") } + do par::map(colors) { + fn~(c: &color) -> i64 { + match *c { + white => { -1i64 } + black(parent) => { parent } + _ => { die!(~"Found remaining gray nodes in BFS") } + } } } } @@ -377,14 +384,15 @@ fn validate(edges: ~[(node_id, node_id)], log(info, ~"Verifying tree and graph edges..."); - let edges = copy edges; - let status = do par::alli(tree) |u, v| { - let u = u as node_id; - if *v == -1i64 || u == root { - true - } - else { - edges.contains(&(u, *v)) || edges.contains(&(*v, u)) + let status = do par::alli(tree) { + let edges = copy edges; + fn~(+u: uint, v: &i64) -> bool { + let u = u as node_id; + if *v == -1i64 || u == root { + true + } else { + edges.contains(&(u, *v)) || edges.contains(&(*v, u)) + } } }; diff --git a/src/test/bench/task-perf-alloc-unwind.rs b/src/test/bench/task-perf-alloc-unwind.rs index 20dcb079597e5..8e5ab45bae868 100644 --- a/src/test/bench/task-perf-alloc-unwind.rs +++ b/src/test/bench/task-perf-alloc-unwind.rs @@ -15,6 +15,10 @@ extern mod std; use std::list::{List, Cons, Nil}; use std::time::precise_time_s; +enum UniqueList { + ULNil, ULCons(~UniqueList) +} + fn main() { let (repeat, depth) = if os::getenv(~"RUST_BENCH").is_some() { (50, 1000) @@ -43,7 +47,6 @@ struct State { box: @nillist, unique: ~nillist, fn_box: fn@() -> @nillist, - fn_unique: fn~() -> ~nillist, tuple: (@nillist, ~nillist), vec: ~[@nillist], res: r @@ -76,7 +79,6 @@ fn recurse_or_fail(depth: int, st: Option) { box: @Nil, unique: ~Nil, fn_box: fn@() -> @nillist { @Nil::<()> }, - fn_unique: fn~() -> ~nillist { ~Nil::<()> }, tuple: (@Nil, ~Nil), vec: ~[@Nil], res: r(@Nil) @@ -84,14 +86,11 @@ fn recurse_or_fail(depth: int, st: Option) { } Some(st) => { let fn_box = st.fn_box; - let fn_unique = copy st.fn_unique; State { box: @Cons((), st.box), unique: ~Cons((), @*st.unique), fn_box: fn@() -> @nillist { @Cons((), fn_box()) }, - fn_unique: fn~(move fn_unique) -> ~nillist - { ~Cons((), @*fn_unique()) }, tuple: (@Cons((), st.tuple.first()), ~Cons((), @*st.tuple.second())), vec: st.vec + ~[@Cons((), st.vec.last())], diff --git a/src/test/compile-fail/bad-var-env-capture-in-block-arg.rs b/src/test/compile-fail/bad-var-env-capture-in-block-arg.rs deleted file mode 100644 index b093af6e80c66..0000000000000 --- a/src/test/compile-fail/bad-var-env-capture-in-block-arg.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -fn main() { - let x = 3; - fn blah(_a: extern fn()) {} - blah(|| { - log(debug, x); //~ ERROR attempted dynamic environment capture - }); -} \ No newline at end of file diff --git a/src/test/compile-fail/block-arg-used-as-lambda-with-illegal-cap.rs b/src/test/compile-fail/block-arg-used-as-lambda-with-illegal-cap.rs deleted file mode 100644 index 0671e8046016d..0000000000000 --- a/src/test/compile-fail/block-arg-used-as-lambda-with-illegal-cap.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -fn to_lambda1(f: fn@(uint) -> uint) -> fn@(uint) -> uint { - return f; -} - -fn to_lambda2(b: fn(uint) -> uint) -> fn@(uint) -> uint { - return to_lambda1(|x| b(x)); //~ ERROR illegal move from argument `b` -} - -fn main() { -} diff --git a/src/test/compile-fail/functional-struct-update.rs b/src/test/compile-fail/functional-struct-update.rs deleted file mode 100644 index c0430a6a8bb7d..0000000000000 --- a/src/test/compile-fail/functional-struct-update.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -struct Bar { - x: int, -} - -impl Bar : Drop { - fn finalize(&self) { - io::println("Goodbye, cruel world"); - } -} - -struct Foo { - x: int, - y: Bar -} - -fn main() { - let a = Foo { x: 1, y: Bar { x: 5 } }; - let c = Foo { x: 4, .. a}; //~ ERROR cannot copy field `y` of base expression, which has a noncopyable type - io::println(fmt!("%?", c)); -} - diff --git a/src/test/compile-fail/issue-3044.rs b/src/test/compile-fail/issue-3044.rs index 2a5785b23b75c..46ad7f6458944 100644 --- a/src/test/compile-fail/issue-3044.rs +++ b/src/test/compile-fail/issue-3044.rs @@ -8,12 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: Non-function passed to a `do` function as its last argument, or wrong number of arguments passed to a `do` function fn main() { let needlesArr: ~[char] = ~['a', 'f']; do vec::foldr(needlesArr) |x, y| { + //~^ ERROR 2 parameters were supplied (including the closure passed by the `do` keyword) + //~^^ ERROR Unconstrained region variable #2 + // + // this last error is, um, non-ideal. } -// for some reason if I use the new error syntax for the two error messages this generates, -// the test runner gets confused -- tjc } diff --git a/src/test/compile-fail/kindck-owned.rs b/src/test/compile-fail/kindck-owned.rs index 52031c900a289..bc6dd8f5dc959 100644 --- a/src/test/compile-fail/kindck-owned.rs +++ b/src/test/compile-fail/kindck-owned.rs @@ -24,6 +24,6 @@ fn main() { copy2(@&x); //~ ERROR missing `&static` copy2(fn@() {}); - copy2(fn~() {}); //~ WARNING instantiating copy type parameter with a not implicitly copyable type - copy2(fn&() {}); //~ ERROR missing `copy &static` + copy2(fn~() {}); //~ ERROR missing `copy` + copy2(fn&() {}); //~ ERROR missing `&static` } diff --git a/src/test/compile-fail/moves-sru-moved-field.rs b/src/test/compile-fail/moves-sru-moved-field.rs new file mode 100644 index 0000000000000..660e5596ca552 --- /dev/null +++ b/src/test/compile-fail/moves-sru-moved-field.rs @@ -0,0 +1,27 @@ +type Noncopyable = ~fn(); + +struct Foo { + copied: int, + moved: ~int, + noncopyable: Noncopyable +} + +fn test0(f: Foo, g: Noncopyable, h: Noncopyable) { + // just copy implicitly copyable fields from `f`, no moves: + let _b = Foo {moved: ~1, noncopyable: g, ..f}; + let _c = Foo {moved: ~2, noncopyable: h, ..f}; +} + +fn test1(f: Foo, g: Noncopyable, h: Noncopyable) { + // copying move-by-default fields from `f`, so move: + let _b = Foo {noncopyable: g, ..f}; + let _c = Foo {noncopyable: h, ..f}; //~ ERROR use of moved value: `f` +} + +fn test2(f: Foo, g: Noncopyable) { + // move non-copyable field + let _b = Foo {copied: 22, moved: ~23, ..f}; + let _c = Foo {noncopyable: g, ..f}; //~ ERROR use of moved value: `f` +} + +fn main() {} diff --git a/src/test/run-pass/bounded-fn-type.rs b/src/test/run-pass/bounded-fn-type.rs deleted file mode 100644 index 5f4a88375a489..0000000000000 --- a/src/test/run-pass/bounded-fn-type.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -fn ignore(_x: T) {} - -pub fn main() { - let f: fn@:Owned() = ||(); - ignore(f); -} - diff --git a/src/test/run-pass/morestack6.rs b/src/test/run-pass/morestack6.rs index 4a254f6a7ebc6..9b852cbc635aa 100644 --- a/src/test/run-pass/morestack6.rs +++ b/src/test/run-pass/morestack6.rs @@ -29,11 +29,11 @@ fn calllink08() { unsafe { rustrt::get_task_id(); } } fn calllink09() { unsafe { rustrt::rust_sched_threads(); } } fn calllink10() { unsafe { rustrt::rust_get_task(); } } -fn runtest(f: fn~(), frame_backoff: u32) { +fn runtest(f: extern fn(), frame_backoff: u32) { runtest2(f, frame_backoff, 0 as *u8); } -fn runtest2(f: fn~(), frame_backoff: u32, last_stk: *u8) -> u32 { +fn runtest2(f: extern fn(), frame_backoff: u32, last_stk: *u8) -> u32 { unsafe { let curr_stk = rustrt::debug_get_stk_seg(); if (last_stk != curr_stk && last_stk != 0 as *u8) { @@ -67,6 +67,6 @@ pub fn main() { let f = *f; let sz = rng.next() % 256u32 + 256u32; let frame_backoff = rng.next() % 10u32 + 1u32; - task::try(|move f| runtest(f, frame_backoff) ); + task::try(|| runtest(f, frame_backoff) ); } } diff --git a/src/test/run-pass/newtype.rs b/src/test/run-pass/newtype.rs index 697a579f4bcfc..18c446fe35054 100644 --- a/src/test/run-pass/newtype.rs +++ b/src/test/run-pass/newtype.rs @@ -16,5 +16,6 @@ fn compute(i: mytype) -> int { return i.val + 20; } pub fn main() { let myval = mytype(Mytype{compute: compute, val: 30}); + io::println(fmt!("%d", compute(myval))); assert ((myval.compute)(myval) == 50); } diff --git a/src/test/run-pass/sendfn-deep-copy.rs b/src/test/run-pass/sendfn-deep-copy.rs deleted file mode 100644 index 520ddf3f73a75..0000000000000 --- a/src/test/run-pass/sendfn-deep-copy.rs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -pub fn main() { test05(); } - -fn mk_counter() -> fn~(A) -> (A,uint) { - // The only reason that the counter is generic is so that it closes - // over both a type descriptor and some data. - let v = ~[mut 0u]; - return fn~(a: A) -> (A,uint) { - let n = v[0]; - v[0] = n + 1u; - (a, n) - }; -} - -fn test05() { - let fp0 = mk_counter::(); - - assert (5.3f, 0u) == fp0(5.3f); - assert (5.5f, 1u) == fp0(5.5f); - - let fp1 = copy fp0; - - assert (5.3f, 2u) == fp0(5.3f); - assert (5.3f, 2u) == fp1(5.3f); - assert (5.5f, 3u) == fp0(5.5f); - assert (5.5f, 3u) == fp1(5.5f); -} diff --git a/src/test/run-pass/test-ignore-cfg.rs b/src/test/run-pass/test-ignore-cfg.rs index 589b9794f644d..1f4df7be1f352 100644 --- a/src/test/run-pass/test-ignore-cfg.rs +++ b/src/test/run-pass/test-ignore-cfg.rs @@ -28,11 +28,11 @@ fn checktests() { // Pull the tests out of the secreturn test module let tests = __test::tests(); - let shouldignore = option::get( - vec::find(tests, |t| t.name == ~"shouldignore" )); - assert shouldignore.ignore == true; + assert vec::any( + tests, + |t| t.desc.name == ~"shouldignore" && t.desc.ignore); - let shouldnotignore = option::get( - vec::find(tests, |t| t.name == ~"shouldnotignore" )); - assert shouldnotignore.ignore == false; + assert vec::any( + tests, + |t| t.desc.name == ~"shouldnotignore" && !t.desc.ignore); } \ No newline at end of file