diff options
148 files changed, 2667 insertions, 1789 deletions
diff --git a/src/doc/guide.md b/src/doc/guide.md index 2f16c783446..03a73db8aa4 100644 --- a/src/doc/guide.md +++ b/src/doc/guide.md @@ -1575,8 +1575,6 @@ we haven't seen before. Here's a simple program that reads some input, and then prints it back out: ```{rust,ignore} -use std::io; - fn main() { println!("Type something!"); diff --git a/src/etc/zsh/_rust b/src/etc/zsh/_rust index b423191d54a..f4e8f6f7873 100644 --- a/src/etc/zsh/_rust +++ b/src/etc/zsh/_rust @@ -4,109 +4,166 @@ local -a _rustc_opts_switches _rustc_opts_lint _rustc_opts_debug typeset -A opt_args +_rustc_debuginfo_levels=( + "0[no debug info]" + "1[line-tables only (for stacktraces and breakpoints)]" + "2[full debug info with variable and type information (same as -g)]" +) + +_rustc_crate_types=( + 'bin' + 'lib' + 'rlib' + 'dylib' + 'staticlib' +) + +_rustc_emit_types=( + 'asm' + 'bc' + 'ir' + 'obj' + 'link' +) +_rustc_pretty_types=( + 'normal[un-annotated source]' + 'expanded[crates expanded]' + 'typed[crates expanded, with type annotations]' + 'identified[fully parenthesized, AST nodes and blocks with IDs]' + 'flowgraph=[graphviz formatted flowgraph for node]:NODEID:' +) +_rustc_color_types=( + 'auto[colorize, if output goes to a tty (default)]' + 'always[always colorize output]' + 'never[never colorize output]' +) + +_rustc_opts_vals=( + --crate-name='[Specify the name of the crate being built]' + --crate-type='[Comma separated list of types of crates for the compiler to emit]:TYPES:_values -s "," "Crate types" "$_rustc_crate_types[@]"' + --emit='[Comma separated list of types of output for the compiler to emit]:TYPES:_values -s "," "Emit Targets" "$_rustc_emit_types[@]"' + --debuginfo='[Emit DWARF debug info to the objects created]:LEVEL:_values "Debug Levels" "$_rustc_debuginfo_levels[@]"' + --dep-info='[Output dependency info to <filename> after compiling]::FILE:_files -/' + --sysroot='[Override the system root]:PATH:_files -/' + --cfg='[Configure the compilation environment]:SPEC:' + --out-dir='[Write output to compiler-chosen filename in <dir>. Ignored if -o is specified. (default the current directory)]:DIR:_files -/' + -o'[Write output to <filename>. Ignored if more than one --emit is specified.]:FILENAME:_files' + --opt-level='[Optimize with possible levels 0-3]:LEVEL:(0 1 2 3)' + --pretty='[Pretty-print the input instead of compiling]::TYPE:_values "TYPES" "$_rustc_pretty_types[@]"' + -L'[Add a directory to the library search path]:DIR:_files -/' + --target='[Target triple cpu-manufacturer-kernel\[-os\] to compile]:TRIPLE:' + --color='[Configure coloring of output]:CONF:_values "COLORS" "$_rustc_color_types[@]"' + {-v,--version}'[Print version info and exit]::VERBOSE:(verbose)' + --explain='[Provide a detailed explanation of an error message]:OPT:' + --extern'[Specify where an external rust library is located]:ARG:' +) + _rustc_opts_switches=( - --ar'[Program to use for managing archives instead of the default.]' - -c'[Compile and assemble, but do not link]' - --cfg'[Configure the compilation environment]' - --crate-id'[Output the crate id and exit]' - --crate-file-name'[deprecated in favor of --print-file-name]' - --crate-name'[Specify the name of the crate being built]' - --crate-type'[Specify the type of crate to crate]' - --debuginfo'[Emit DWARF debug info to the objects created: 0 = no debug info, 1 = line-tables only (for stacktraces and breakpoints), 2 = full debug info with variable and type information (same as -g)]' - --dep-info'[Output dependency info to <filename> after compiling]' -g'[Equivalent to --debuginfo=2]' {-h,--help}'[Display this message]' - -L'[Add a directory to the library search path]' - --linker'[Program to use for linking instead of the default.]' - --link-args'[FLAGS is a space-separated list of flags passed to the linker]' - --llvm-args'[A list of arguments to pass to llvm, comma separated]' - --ls'[List the symbols defined by a library crate]' --no-analysis'[Parse and expand the output, but run no analysis or produce output]' - --no-rpath'[Disables setting the rpath in libs/exes]' --no-trans'[Run all passes except translation; no output]' -O'[Equivalent to --opt-level=2]' - -o'[Write output to <filename>]' - --opt-level'[Optimize with possible levels 0-3]' - --out-dir'[Write output to compiler-chosen filename in <dir>]' --parse-only'[Parse only; do not compile, assemble, or link]' - --passes'[Comma or space separated list of pass names to use]' - --pretty'[Pretty-print the input instead of compiling]' --print-crate-name'[Output the crate name and exit]' --print-file-name'[Output the file(s) that would be written if compilation continued and exit]' - --save-temps'[Write intermediate files (.bc, .opt.bc, .o) in addition to normal output]' - --sysroot'[Override the system root]' --test'[Build a test harness]' - --target'[Target triple cpu-manufacturer-kernel\[-os\] to compile]' - --target-cpu'[Select target processor (llc -mcpu=help for details)]' - --target-feature'[Target specific attributes (llc -mattr=help for details)]' - --relocation-model'[Relocation model (llc --help for details)]' - {-v,--version}'[Print version info and exit]' ) +_rustc_opts_codegen=( + 'ar=[Path to the archive utility to use when assembling archives.]:BIN:_path_files' + 'linker=[Path to the linker utility to use when linking libraries, executables, and objects.]:BIN:_path_files' + 'link-args=[A space-separated list of extra arguments to pass to the linker when the linker is invoked.]:ARGS:' + 'target-cpu=[Selects a target processor. If the value is "help", then a list of available CPUs is printed.]:CPU:' + 'target-feature=[A space-separated list of features to enable or disable for the target. A preceding "+" enables a feature while a preceding "-" disables it. Available features can be discovered through target-cpu=help.]:FEATURE:' + 'passes=[A space-separated list of extra LLVM passes to run. A value of "list" will cause rustc to print all known passes and exit. The passes specified are appended at the end of the normal pass manager.]:LIST:' + 'llvm-args=[A space-separated list of arguments to pass through to LLVM.]:ARGS:' + 'save-temps[If specified, the compiler will save more files (.bc, .o, .no-opt.bc) generated throughout compilation in the output directory.]' + 'rpath[If specified, then the rpath value for dynamic libraries will be set in either dynamic library or executable outputs.]' + 'no-prepopulate-passes[Suppresses pre-population of the LLVM pass manager that is run over the module.]' + 'no-vectorize-loops[Suppresses running the loop vectorization LLVM pass, regardless of optimization level.]' + 'no-vectorize-slp[Suppresses running the LLVM SLP vectorization pass, regardless of optimization level.]' + 'soft-float[Generates software floating point library calls instead of hardware instructions.]' + 'prefer-dynamic[Prefers dynamic linking to static linking.]' + "no-integrated-as[Force usage of an external assembler rather than LLVM's integrated one.]" + 'no-redzone[disable the use of the redzone]' + 'relocation-model=[The relocation model to use. (default: pic)]:MODEL:(pic static dynamic-no-pic)' + 'code-model=[choose the code model to use (llc -code-model for details)]:MODEL:' + 'metadata=[metadata to mangle symbol names with]:VAL:' + 'extra-filenames=[extra data to put in each output filename]:VAL:' + 'codegen-units=[divide crate into N units to optimize in parallel]:N:' + 'help[Show all codegen options]' +) + _rustc_opts_lint=( - 'attribute-usage[detects bad use of attributes]' - 'ctypes[proper use of libc types in foreign modules]' - 'dead-assignment[detect assignments that will never be read]' - 'dead-code[detect piece of code that will never be used]' - 'default-type-param-usage[prevents explicitly setting a type parameter with a default]' - 'deprecated[detects use of #\[deprecated\] items]' + 'help[Show a list of all lints]' 'experimental[detects use of #\[experimental\] items]' - 'heap-memory[use of any (~ type or @ type) heap memory]' + 'heap-memory[use of any (Box type or @ type) heap memory]' 'managed-heap-memory[use of managed (@ type) heap memory]' 'missing-doc[detects missing documentation for public members]' - 'non-camel-case-types[types, variants and traits should have camel case names]' - 'non-uppercase-pattern-statics[static constants in match patterns should be all caps]' 'non-uppercase-statics[static constants should have uppercase identifiers]' 'owned-heap-memory[use of owned (~ type) heap memory]' + 'unnecessary-qualification[detects unnecessarily qualified names]' + 'unsafe-block[usage of an `unsafe` block]' + 'unstable[detects use of #\[unstable\] items (incl. items with no stability attribute)]' + 'unused-result[unused result of an expression in a statement]' + 'variant-size-difference[detects enums with widely varying variant sizes]' + 'ctypes[proper use of libc types in foreign modules]' + 'dead-assignment[detect assignments that will never be read]' + 'dead-code[detect piece of code that will never be used]' + 'deprecated[detects use of #\[deprecated\] items]' + 'non-camel-case-types[types, variants and traits should have camel case names]' + 'non-snake-case[methods, functions, lifetime parameters and modules should have snake case names]' 'path-statement[path statements with no effect]' + 'raw-pointer-deriving[uses of #\[deriving\] with raw pointers are rarely correct]' 'type-limits[comparisons made useless by limits of the types involved]' 'type-overflow[literal out of range for its type]' - 'unknown-crate-type[unknown crate type found in #\[crate_type\] directive]' - 'unknown-features[unknown features found in crate-level #\[feature\] directives]' 'unnecessary-allocation[detects unnecessary allocations that can be eliminated]' 'unnecessary-parens[`if`, `match`, `while` and `return` do not need parentheses]' - 'unnecessary-qualification[detects unnecessarily qualified names]' - 'unnecessary-typecast[detects unnecessary type casts, that can be removed]' 'unreachable-code[detects unreachable code]' 'unrecognized-lint[unrecognized lint attribute]' - 'unsafe-block[usage of an `unsafe` block]' - 'unstable[detects use of #\[unstable\] items (incl. items with no stability attribute)]' + 'unsigned-negate[using an unary minus operator on unsigned type]' + 'unused-attribute[detects attributes that were not used by the compiler]' 'unused-imports[imports that are never used]' 'unused-must-use[unused result of a type flagged as #\[must_use\]]' "unused-mut[detect mut variables which don't need to be mutable]" - 'unused-result[unused result of an expression in a statement]' 'unused-unsafe[unnecessary use of an `unsafe` block]' 'unused-variable[detect variables which are not used in any way]' + 'visible-private-types[detect use of private types in exported type signatures]' 'warnings[mass-change the level for lints which produce warnings]' 'while-true[suggest using `loop { }` instead of `while true { }`]' + 'unknown-crate-type[unknown crate type found in #\[crate_type\] directive]' + 'unknown-features[unknown features found in crate-level #\[feature\] directives]' + 'bad-style[group of non_camel_case_types, non_snake_case, non_uppercase_statics]' + 'unused[group of unused_imports, unused_variable, dead_assignment, dead_code, unused_mut, unreachable_code]' ) _rustc_opts_debug=( + 'verbose[in general, enable more debug printouts]' + 'time-passes[measure time of each rustc pass]' + 'count-llvm-insns[count where LLVM instrs originate]' + 'time-llvm-passes[measure time of each LLVM pass]' + 'trans-stats[gather trans statistics]' 'asm-comments[generate comments into the assembly (may change behavior)]' + 'no-verify[skip LLVM verification]' 'borrowck-stats[gather borrowck statistics]' - 'count-llvm-insns[count where LLVM instrs originate]' - 'count-type-sizes[count the sizes of aggregate types]' - 'debug-info[Produce debug info (experimental)]' + 'no-landing-pads[omit landing pads for unwinding]' 'debug-llvm[enable debug output from LLVM]' - 'extra-debug-info[Extra debugging info (experimental)]' - 'gc[Garbage collect shared data (experimental)]' - 'gen-crate-map[Force generation of a toplevel crate map]' - 'lto[Perform LLVM link-time optimizations]' + 'show-span[show spans for compiler debugging]' + 'count-type-sizes[count the sizes of aggregate types]' 'meta-stats[gather metadata statistics]' - "no-integrated-as[Use external assembler rather than LLVM's integrated one]" - 'no-landing-pads[omit landing pads for unwinding]' 'no-opt[do not optimize, even if -O is passed]' - "no-prepopulate-passes[Don't pre-populate the pass managers with a list of passes, only use the passes from --passes]" - "no-vectorize-loops[Don't run the loop vectorization optimization passes]" - "no-vectorize-slp[Don't run LLVM's SLP vectorization passes]" - 'no-verify[skip LLVM verification]' - 'prefer-dynamic[Prefer dynamic linking to static linking]' 'print-link-args[Print the arguments passed to the linker]' + 'gc[Garbage collect shared data (experimental)]' 'print-llvm-passes[Prints the llvm optimization passes being run]' - 'soft-float[Generate software floating point library calls]' - 'time-llvm-passes[measure time of each LLVM pass]' - 'time-passes[measure time of each rustc pass]' - 'trans-stats[gather trans statistics]' - 'verbose[in general, enable more debug printouts]' + 'lto[Perform LLVM link-time optimizations]' + 'ast-json[Print the AST as JSON and halt]' + 'ast-json-noexpand[Print the pre-expansion AST as JSON and halt]' + 'ls[List the symbols defined by a library crate]' + 'save-analysis[Write syntax and type analysis information in addition to normal output]' + 'flowgraph-print-loans[Include loan analysis data in --pretty flowgraph output]' + 'flowgraph-print-moves[Include move analysis data in --pretty flowgraph output]' + 'flowgraph-print-assigns[Include assignment analysis data in --pretty flowgraph output]' + 'flowgraph-print-all[Include all dataflow analysis data in --pretty flowgraph output]' ) _rustc_opts_fun_lint(){ @@ -115,14 +172,20 @@ _rustc_opts_fun_lint(){ } _rustc_opts_fun_debug(){ - _describe 'options' _rustc_opts_debug + _values 'options' "$_rustc_opts_debug[@]" +} + +_rustc_opts_fun_codegen(){ + _values 'options' "$_rustc_opts_codegen[@]" } _arguments -s : \ - '(-W --warn)'{-W,--warn}'[Set lint warnings]:lint options:_rustc_opts_fun_lint' \ - '(-A --allow)'{-A,--allow}'[Set lint allowed]:lint options:_rustc_opts_fun_lint' \ - '(-D --deny)'{-D,--deny}'[Set lint denied]:lint options:_rustc_opts_fun_lint' \ - '(-F --forbid)'{-F,--forbid}'[Set lint forbidden]:lint options:_rustc_opts_fun_lint' \ + '(-W --warn)'{-W,--warn=}'[Set lint warnings]:lint options:_rustc_opts_fun_lint' \ + '(-A --allow)'{-A,--allow=}'[Set lint allowed]:lint options:_rustc_opts_fun_lint' \ + '(-D --deny)'{-D,--deny=}'[Set lint denied]:lint options:_rustc_opts_fun_lint' \ + '(-F --forbid)'{-F,--forbid=}'[Set lint forbidden]:lint options:_rustc_opts_fun_lint' \ '*-Z[Set internal debugging options]:debug options:_rustc_opts_fun_debug' \ + '*-C[Set internal Codegen options]:codegen options:_rustc_opts_fun_codegen' \ "$_rustc_opts_switches[@]" \ - '*::files:_files -g "*.rs"' + "$_rustc_opts_vals[@]" \ + '::files:_files -g "*.rs"' diff --git a/src/grammar/verify.rs b/src/grammar/verify.rs index f2ae5a1ea4e..a95eeb3c97d 100644 --- a/src/grammar/verify.rs +++ b/src/grammar/verify.rs @@ -211,7 +211,7 @@ fn parse_antlr_token(s: &str, tokens: &HashMap<String, Token>) -> TokenAndSpan { let sp = syntax::codemap::Span { lo: syntax::codemap::BytePos(from_str::<u32>(start).unwrap() - offset), hi: syntax::codemap::BytePos(from_str::<u32>(end).unwrap() + 1), - expn_info: None + expn_id: syntax::codemap::NO_EXPANSION }; TokenAndSpan { diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 05d91a75041..a12d403603f 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -872,7 +872,7 @@ mod tests { use {Mutable, MutableSeq}; use str; - use str::{Str, StrSlice, Owned, Slice}; + use str::{Str, StrSlice, Owned}; use super::String; use vec::Vec; @@ -898,10 +898,10 @@ mod tests { #[test] fn test_from_utf8_lossy() { let xs = b"hello"; - assert_eq!(String::from_utf8_lossy(xs), Slice("hello")); + assert_eq!(String::from_utf8_lossy(xs), str::Slice("hello")); let xs = "ศไทย中华Việt Nam".as_bytes(); - assert_eq!(String::from_utf8_lossy(xs), Slice("ศไทย中华Việt Nam")); + assert_eq!(String::from_utf8_lossy(xs), str::Slice("ศไทย中华Việt Nam")); let xs = b"Hello\xC2 There\xFF Goodbye"; assert_eq!(String::from_utf8_lossy(xs), diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index f570573262a..4051f682134 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -20,6 +20,7 @@ use core::default::Default; use core::fmt; use core::mem; use core::num; +use core::ops; use core::ptr; use core::raw::Slice as RawSlice; use core::uint; @@ -464,6 +465,47 @@ impl<T> Index<uint,T> for Vec<T> { } }*/ +impl<T> ops::Slice<uint, [T]> for Vec<T> { + #[inline] + fn as_slice_<'a>(&'a self) -> &'a [T] { + self.as_slice() + } + + #[inline] + fn slice_from_<'a>(&'a self, start: &uint) -> &'a [T] { + self.as_slice().slice_from_(start) + } + + #[inline] + fn slice_to_<'a>(&'a self, end: &uint) -> &'a [T] { + self.as_slice().slice_to_(end) + } + #[inline] + fn slice_<'a>(&'a self, start: &uint, end: &uint) -> &'a [T] { + self.as_slice().slice_(start, end) + } +} + +impl<T> ops::SliceMut<uint, [T]> for Vec<T> { + #[inline] + fn as_mut_slice_<'a>(&'a mut self) -> &'a mut [T] { + self.as_mut_slice() + } + + #[inline] + fn slice_from_mut_<'a>(&'a mut self, start: &uint) -> &'a mut [T] { + self.as_mut_slice().slice_from_mut_(start) + } + + #[inline] + fn slice_to_mut_<'a>(&'a mut self, end: &uint) -> &'a mut [T] { + self.as_mut_slice().slice_to_mut_(end) + } + #[inline] + fn slice_mut_<'a>(&'a mut self, start: &uint, end: &uint) -> &'a mut [T] { + self.as_mut_slice().slice_mut_(start, end) + } +} impl<T> FromIterator<T> for Vec<T> { #[inline] fn from_iter<I:Iterator<T>>(mut iterator: I) -> Vec<T> { @@ -2327,6 +2369,44 @@ mod tests { let _ = vec[3]; } + // NOTE uncomment after snapshot + /* + #[test] + #[should_fail] + fn test_slice_out_of_bounds_1() { + let x: Vec<int> = vec![1, 2, 3, 4, 5]; + x[-1..]; + } + + #[test] + #[should_fail] + fn test_slice_out_of_bounds_2() { + let x: Vec<int> = vec![1, 2, 3, 4, 5]; + x[..6]; + } + + #[test] + #[should_fail] + fn test_slice_out_of_bounds_3() { + let x: Vec<int> = vec![1, 2, 3, 4, 5]; + x[-1..4]; + } + + #[test] + #[should_fail] + fn test_slice_out_of_bounds_4() { + let x: Vec<int> = vec![1, 2, 3, 4, 5]; + x[1..6]; + } + + #[test] + #[should_fail] + fn test_slice_out_of_bounds_5() { + let x: Vec<int> = vec![1, 2, 3, 4, 5]; + x[3..2]; + } + */ + #[test] fn test_swap_remove_empty() { let mut vec: Vec<uint> = vec!(); diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 94febf03635..718d3119995 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -638,7 +638,7 @@ shr_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64) * ``` */ #[lang="index"] -pub trait Index<Index,Result> { +pub trait Index<Index, Result> { /// The method for the indexing (`Foo[Bar]`) operation fn index<'a>(&'a self, index: &Index) -> &'a Result; } @@ -651,7 +651,7 @@ pub trait Index<Index,Result> { * # Example * * A trivial implementation of `IndexMut`. When `Foo[Foo]` happens, it ends up - * calling `index`, and therefore, `main` prints `Indexing!`. + * calling `index_mut`, and therefore, `main` prints `Indexing!`. * * ``` * struct Foo; @@ -669,13 +669,112 @@ pub trait Index<Index,Result> { * ``` */ #[lang="index_mut"] -pub trait IndexMut<Index,Result> { +pub trait IndexMut<Index, Result> { /// The method for the indexing (`Foo[Bar]`) operation fn index_mut<'a>(&'a mut self, index: &Index) -> &'a mut Result; } /** * + * The `Slice` trait is used to specify the functionality of slicing operations + * like `arr[from..to]` when used in an immutable context. + * + * # Example + * + * A trivial implementation of `Slice`. When `Foo[..Foo]` happens, it ends up + * calling `slice_to`, and therefore, `main` prints `Slicing!`. + * + * ``` + * struct Foo; + * + * impl ::core::ops::Slice<Foo, Foo> for Foo { + * fn as_slice_<'a>(&'a self) -> &'a Foo { + * println!("Slicing!"); + * self + * } + * fn slice_from_<'a>(&'a self, from: &Foo) -> &'a Foo { + * println!("Slicing!"); + * self + * } + * fn slice_to_<'a>(&'a self, to: &Foo) -> &'a Foo { + * println!("Slicing!"); + * self + * } + * fn slice_<'a>(&'a self, from: &Foo, to: &Foo) -> &'a Foo { + * println!("Slicing!"); + * self + * } + * } + * + * fn main() { + * Foo[..Foo]; + * } + * ``` + */ +// FIXME(#17273) remove the postscript _s +#[lang="slice"] +pub trait Slice<Idx, Sized? Result> for Sized? { + /// The method for the slicing operation foo[] + fn as_slice_<'a>(&'a self) -> &'a Result; + /// The method for the slicing operation foo[from..] + fn slice_from_<'a>(&'a self, from: &Idx) -> &'a Result; + /// The method for the slicing operation foo[..to] + fn slice_to_<'a>(&'a self, to: &Idx) -> &'a Result; + /// The method for the slicing operation foo[from..to] + fn slice_<'a>(&'a self, from: &Idx, to: &Idx) -> &'a Result; +} + +/** + * + * The `SliceMut` trait is used to specify the functionality of slicing + * operations like `arr[from..to]`, when used in a mutable context. + * + * # Example + * + * A trivial implementation of `SliceMut`. When `Foo[Foo..]` happens, it ends up + * calling `slice_from_mut`, and therefore, `main` prints `Slicing!`. + * + * ``` + * struct Foo; + * + * impl ::core::ops::SliceMut<Foo, Foo> for Foo { + * fn as_mut_slice_<'a>(&'a mut self) -> &'a mut Foo { + * println!("Slicing!"); + * self + * } + * fn slice_from_mut_<'a>(&'a mut self, from: &Foo) -> &'a mut Foo { + * println!("Slicing!"); + * self + * } + * fn slice_to_mut_<'a>(&'a mut self, to: &Foo) -> &'a mut Foo { + * println!("Slicing!"); + * self + * } + * fn slice_mut_<'a>(&'a mut self, from: &Foo, to: &Foo) -> &'a mut Foo { + * println!("Slicing!"); + * self + * } + * } + * + * fn main() { + * Foo[mut Foo..]; + * } + * ``` + */ +// FIXME(#17273) remove the postscript _s +#[lang="slice_mut"] +pub trait SliceMut<Idx, Sized? Result> for Sized? { + /// The method for the slicing operation foo[] + fn as_mut_slice_<'a>(&'a mut self) -> &'a mut Result; + /// The method for the slicing operation foo[from..] + fn slice_from_mut_<'a>(&'a mut self, from: &Idx) -> &'a mut Result; + /// The method for the slicing operation foo[..to] + fn slice_to_mut_<'a>(&'a mut self, to: &Idx) -> &'a mut Result; + /// The method for the slicing operation foo[from..to] + fn slice_mut_<'a>(&'a mut self, from: &Idx, to: &Idx) -> &'a mut Result; +} +/** + * * The `Deref` trait is used to specify the functionality of dereferencing * operations like `*v`. * diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 65ad7bb1753..5368cb44502 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -42,6 +42,7 @@ use cmp; use default::Default; use iter::*; use num::{CheckedAdd, Saturating, div_rem}; +use ops; use option::{None, Option, Some}; use ptr; use ptr::RawPtr; @@ -475,6 +476,63 @@ impl<'a,T> ImmutableSlice<'a, T> for &'a [T] { } } +impl<T> ops::Slice<uint, [T]> for [T] { + #[inline] + fn as_slice_<'a>(&'a self) -> &'a [T] { + self + } + + #[inline] + fn slice_from_<'a>(&'a self, start: &uint) -> &'a [T] { + self.slice_(start, &self.len()) + } + + #[inline] + fn slice_to_<'a>(&'a self, end: &uint) -> &'a [T] { + self.slice_(&0, end) + } + #[inline] + fn slice_<'a>(&'a self, start: &uint, end: &uint) -> &'a [T] { + assert!(*start <= *end); + assert!(*end <= self.len()); + unsafe { + transmute(RawSlice { + data: self.as_ptr().offset(*start as int), + len: (*end - *start) + }) + } + } +} + +impl<T> ops::SliceMut<uint, [T]> for [T] { + #[inline] + fn as_mut_slice_<'a>(&'a mut self) -> &'a mut [T] { + self + } + + #[inline] + fn slice_from_mut_<'a>(&'a mut self, start: &uint) -> &'a mut [T] { + let len = &self.len(); + self.slice_mut_(start, len) + } + + #[inline] + fn slice_to_mut_<'a>(&'a mut self, end: &uint) -> &'a mut [T] { + self.slice_mut_(&0, end) + } + #[inline] + fn slice_mut_<'a>(&'a mut self, start: &uint, end: &uint) -> &'a mut [T] { + assert!(*start <= *end); + assert!(*end <= self.len()); + unsafe { + transmute(RawSlice { + data: self.as_ptr().offset(*start as int), + len: (*end - *start) + }) + } + } +} + /// Extension methods for vectors such that their elements are /// mutable. #[experimental = "may merge with other traits; may lose region param; needs review"] diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index 9272369f73c..a9f34e1195c 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -23,6 +23,7 @@ use std::char; use std::str; +use std::string; /// A piece is a portion of the format string which represents the next part /// to emit. These are emitted as a stream by the `Parser` class. @@ -32,7 +33,7 @@ pub enum Piece<'a> { String(&'a str), /// This describes that formatting should process the next argument (as /// specified inside) for emission. - Argument(Argument<'a>), + NextArgument(Argument<'a>), } /// Representation of an argument specification. @@ -129,7 +130,7 @@ pub struct Parser<'a> { input: &'a str, cur: str::CharOffsets<'a>, /// Error messages accumulated during parsing - pub errors: Vec<String>, + pub errors: Vec<string::String>, } impl<'a> Iterator<Piece<'a>> for Parser<'a> { @@ -140,7 +141,7 @@ impl<'a> Iterator<Piece<'a>> for Parser<'a> { if self.consume('{') { Some(String(self.string(pos + 1))) } else { - let ret = Some(Argument(self.argument())); + let ret = Some(NextArgument(self.argument())); self.must_consume('}'); ret } @@ -469,28 +470,28 @@ mod tests { #[test] fn format_nothing() { - same("{}", [Argument(Argument { + same("{}", [NextArgument(Argument { position: ArgumentNext, format: fmtdflt(), })]); } #[test] fn format_position() { - same("{3}", [Argument(Argument { + same("{3}", [NextArgument(Argument { position: ArgumentIs(3), format: fmtdflt(), })]); } #[test] fn format_position_nothing_else() { - same("{3:}", [Argument(Argument { + same("{3:}", [NextArgument(Argument { position: ArgumentIs(3), format: fmtdflt(), })]); } #[test] fn format_type() { - same("{3:a}", [Argument(Argument { + same("{3:a}", [NextArgument(Argument { position: ArgumentIs(3), format: FormatSpec { fill: None, @@ -504,7 +505,7 @@ mod tests { } #[test] fn format_align_fill() { - same("{3:>}", [Argument(Argument { + same("{3:>}", [NextArgument(Argument { position: ArgumentIs(3), format: FormatSpec { fill: None, @@ -515,7 +516,7 @@ mod tests { ty: "", }, })]); - same("{3:0<}", [Argument(Argument { + same("{3:0<}", [NextArgument(Argument { position: ArgumentIs(3), format: FormatSpec { fill: Some('0'), @@ -526,7 +527,7 @@ mod tests { ty: "", }, })]); - same("{3:*<abcd}", [Argument(Argument { + same("{3:*<abcd}", [NextArgument(Argument { position: ArgumentIs(3), format: FormatSpec { fill: Some('*'), @@ -540,7 +541,7 @@ mod tests { } #[test] fn format_counts() { - same("{:10s}", [Argument(Argument { + same("{:10s}", [NextArgument(Argument { position: ArgumentNext, format: FormatSpec { fill: None, @@ -551,7 +552,7 @@ mod tests { ty: "s", }, })]); - same("{:10$.10s}", [Argument(Argument { + same("{:10$.10s}", [NextArgument(Argument { position: ArgumentNext, format: FormatSpec { fill: None, @@ -562,7 +563,7 @@ mod tests { ty: "s", }, })]); - same("{:.*s}", [Argument(Argument { + same("{:.*s}", [NextArgument(Argument { position: ArgumentNext, format: FormatSpec { fill: None, @@ -573,7 +574,7 @@ mod tests { ty: "s", }, })]); - same("{:.10$s}", [Argument(Argument { + same("{:.10$s}", [NextArgument(Argument { position: ArgumentNext, format: FormatSpec { fill: None, @@ -584,7 +585,7 @@ mod tests { ty: "s", }, })]); - same("{:a$.b$s}", [Argument(Argument { + same("{:a$.b$s}", [NextArgument(Argument { position: ArgumentNext, format: FormatSpec { fill: None, @@ -598,7 +599,7 @@ mod tests { } #[test] fn format_flags() { - same("{:-}", [Argument(Argument { + same("{:-}", [NextArgument(Argument { position: ArgumentNext, format: FormatSpec { fill: None, @@ -609,7 +610,7 @@ mod tests { ty: "", }, })]); - same("{:+#}", [Argument(Argument { + same("{:+#}", [NextArgument(Argument { position: ArgumentNext, format: FormatSpec { fill: None, @@ -623,7 +624,7 @@ mod tests { } #[test] fn format_mixture() { - same("abcd {3:a} efg", [String("abcd "), Argument(Argument { + same("abcd {3:a} efg", [String("abcd "), NextArgument(Argument { position: ArgumentIs(3), format: FormatSpec { fill: None, diff --git a/src/libnative/io/net.rs b/src/libnative/io/net.rs index af7508ccbe9..8418e741167 100644 --- a/src/libnative/io/net.rs +++ b/src/libnative/io/net.rs @@ -37,7 +37,7 @@ pub fn ntohs(u: u16) -> u16 { } enum InAddr { - InAddr(libc::in_addr), + In4Addr(libc::in_addr), In6Addr(libc::in6_addr), } @@ -48,7 +48,7 @@ fn ip_to_inaddr(ip: rtio::IpAddr) -> InAddr { (b as u32 << 16) | (c as u32 << 8) | (d as u32 << 0); - InAddr(libc::in_addr { + In4Addr(libc::in_addr { s_addr: Int::from_be(ip) }) } @@ -74,7 +74,7 @@ fn addr_to_sockaddr(addr: rtio::SocketAddr, -> libc::socklen_t { unsafe { let len = match ip_to_inaddr(addr.ip) { - InAddr(inaddr) => { + In4Addr(inaddr) => { let storage = storage as *mut _ as *mut libc::sockaddr_in; (*storage).sin_family = libc::AF_INET as libc::sa_family_t; (*storage).sin_port = htons(addr.port); @@ -723,7 +723,7 @@ impl UdpSocket { pub fn set_membership(&mut self, addr: rtio::IpAddr, opt: libc::c_int) -> IoResult<()> { match ip_to_inaddr(addr) { - InAddr(addr) => { + In4Addr(addr) => { let mreq = libc::ip_mreq { imr_multiaddr: addr, // interface == INADDR_ANY diff --git a/src/libnum/bigint.rs b/src/libnum/bigint.rs index 3f91ce11915..efa3402073f 100644 --- a/src/libnum/bigint.rs +++ b/src/libnum/bigint.rs @@ -618,7 +618,7 @@ impl ToBigUint for BigInt { fn to_biguint(&self) -> Option<BigUint> { if self.sign == Plus { Some(self.data.clone()) - } else if self.sign == Zero { + } else if self.sign == NoSign { Some(Zero::zero()) } else { None @@ -838,7 +838,7 @@ fn get_radix_base(radix: uint) -> (DoubleBigDigit, uint) { /// A Sign is a `BigInt`'s composing element. #[deriving(PartialEq, PartialOrd, Eq, Ord, Clone, Show)] -pub enum Sign { Minus, Zero, Plus } +pub enum Sign { Minus, NoSign, Plus } impl Neg<Sign> for Sign { /// Negate Sign value. @@ -846,7 +846,7 @@ impl Neg<Sign> for Sign { fn neg(&self) -> Sign { match *self { Minus => Plus, - Zero => Zero, + NoSign => NoSign, Plus => Minus } } @@ -882,7 +882,7 @@ impl Ord for BigInt { if scmp != Equal { return scmp; } match self.sign { - Zero => Equal, + NoSign => Equal, Plus => self.data.cmp(&other.data), Minus => other.data.cmp(&self.data), } @@ -933,11 +933,11 @@ impl Shr<uint, BigInt> for BigInt { impl Zero for BigInt { #[inline] fn zero() -> BigInt { - BigInt::from_biguint(Zero, Zero::zero()) + BigInt::from_biguint(NoSign, Zero::zero()) } #[inline] - fn is_zero(&self) -> bool { self.sign == Zero } + fn is_zero(&self) -> bool { self.sign == NoSign } } impl One for BigInt { @@ -951,7 +951,7 @@ impl Signed for BigInt { #[inline] fn abs(&self) -> BigInt { match self.sign { - Plus | Zero => self.clone(), + Plus | NoSign => self.clone(), Minus => BigInt::from_biguint(Plus, self.data.clone()) } } @@ -966,7 +966,7 @@ impl Signed for BigInt { match self.sign { Plus => BigInt::from_biguint(Plus, One::one()), Minus => BigInt::from_biguint(Minus, One::one()), - Zero => Zero::zero(), + NoSign => Zero::zero(), } } @@ -981,8 +981,8 @@ impl Add<BigInt, BigInt> for BigInt { #[inline] fn add(&self, other: &BigInt) -> BigInt { match (self.sign, other.sign) { - (Zero, _) => other.clone(), - (_, Zero) => self.clone(), + (NoSign, _) => other.clone(), + (_, NoSign) => self.clone(), (Plus, Plus) => BigInt::from_biguint(Plus, self.data + other.data), (Plus, Minus) => self - (-*other), (Minus, Plus) => other - (-*self), @@ -995,8 +995,8 @@ impl Sub<BigInt, BigInt> for BigInt { #[inline] fn sub(&self, other: &BigInt) -> BigInt { match (self.sign, other.sign) { - (Zero, _) => -other, - (_, Zero) => self.clone(), + (NoSign, _) => -other, + (_, NoSign) => self.clone(), (Plus, Plus) => match self.data.cmp(&other.data) { Less => BigInt::from_biguint(Minus, other.data - self.data), Greater => BigInt::from_biguint(Plus, self.data - other.data), @@ -1013,7 +1013,7 @@ impl Mul<BigInt, BigInt> for BigInt { #[inline] fn mul(&self, other: &BigInt) -> BigInt { match (self.sign, other.sign) { - (Zero, _) | (_, Zero) => Zero::zero(), + (NoSign, _) | (_, NoSign) => Zero::zero(), (Plus, Plus) | (Minus, Minus) => { BigInt::from_biguint(Plus, self.data * other.data) }, @@ -1087,9 +1087,9 @@ impl Integer for BigInt { let d = BigInt::from_biguint(Plus, d_ui); let r = BigInt::from_biguint(Plus, r_ui); match (self.sign, other.sign) { - (_, Zero) => fail!(), - (Plus, Plus) | (Zero, Plus) => ( d, r), - (Plus, Minus) | (Zero, Minus) => (-d, r), + (_, NoSign) => fail!(), + (Plus, Plus) | (NoSign, Plus) => ( d, r), + (Plus, Minus) | (NoSign, Minus) => (-d, r), (Minus, Plus) => (-d, -r), (Minus, Minus) => ( d, -r) } @@ -1113,9 +1113,9 @@ impl Integer for BigInt { let d = BigInt::from_biguint(Plus, d_ui); let m = BigInt::from_biguint(Plus, m_ui); match (self.sign, other.sign) { - (_, Zero) => fail!(), - (Plus, Plus) | (Zero, Plus) => (d, m), - (Plus, Minus) | (Zero, Minus) => if m.is_zero() { + (_, NoSign) => fail!(), + (Plus, Plus) | (NoSign, Plus) => (d, m), + (Plus, Minus) | (NoSign, Minus) => if m.is_zero() { (-d, Zero::zero()) } else { (-d - One::one(), m + *other) @@ -1166,7 +1166,7 @@ impl ToPrimitive for BigInt { fn to_i64(&self) -> Option<i64> { match self.sign { Plus => self.data.to_i64(), - Zero => Some(0), + NoSign => Some(0), Minus => { self.data.to_u64().and_then(|n| { let m: u64 = 1 << 63; @@ -1186,7 +1186,7 @@ impl ToPrimitive for BigInt { fn to_u64(&self) -> Option<u64> { match self.sign { Plus => self.data.to_u64(), - Zero => Some(0), + NoSign => Some(0), Minus => None } } @@ -1272,7 +1272,7 @@ impl ToStrRadix for BigInt { fn to_str_radix(&self, radix: uint) -> String { match self.sign { Plus => self.data.to_str_radix(radix), - Zero => "0".to_string(), + NoSign => "0".to_string(), Minus => format!("-{}", self.data.to_str_radix(radix)), } } @@ -1334,7 +1334,7 @@ impl<R: Rng> RandBigInt for R { if self.gen() { return self.gen_bigint(bit_size); } else { - Zero + NoSign } } else if self.gen() { Plus @@ -1385,8 +1385,8 @@ impl BigInt { /// The digits are be in base 2^32. #[inline] pub fn from_biguint(sign: Sign, data: BigUint) -> BigInt { - if sign == Zero || data.is_zero() { - return BigInt { sign: Zero, data: Zero::zero() }; + if sign == NoSign || data.is_zero() { + return BigInt { sign: NoSign, data: Zero::zero() }; } BigInt { sign: sign, data: data } } @@ -1415,7 +1415,7 @@ impl BigInt { pub fn to_biguint(&self) -> Option<BigUint> { match self.sign { Plus => Some(self.data.clone()), - Zero => Some(Zero::zero()), + NoSign => Some(Zero::zero()), Minus => None } } @@ -2288,7 +2288,7 @@ mod biguint_tests { mod bigint_tests { use Integer; use super::{BigDigit, BigUint, ToBigUint}; - use super::{Sign, Minus, Zero, Plus, BigInt, RandBigInt, ToBigInt}; + use super::{Sign, Minus, NoSign, Plus, BigInt, RandBigInt, ToBigInt}; use std::cmp::{Less, Equal, Greater}; use std::i64; @@ -2307,9 +2307,9 @@ mod bigint_tests { assert_eq!(inp, ans); } check(Plus, 1, Plus, 1); - check(Plus, 0, Zero, 0); + check(Plus, 0, NoSign, 0); check(Minus, 1, Minus, 1); - check(Zero, 1, Zero, 0); + check(NoSign, 1, NoSign, 0); } #[test] @@ -2357,8 +2357,8 @@ mod bigint_tests { #[test] fn test_hash() { - let a = BigInt::new(Zero, vec!()); - let b = BigInt::new(Zero, vec!(0)); + let a = BigInt::new(NoSign, vec!()); + let b = BigInt::new(NoSign, vec!(0)); let c = BigInt::new(Plus, vec!(1)); let d = BigInt::new(Plus, vec!(1,0,0,0,0,0)); let e = BigInt::new(Plus, vec!(0,0,0,0,0,1)); diff --git a/src/libregex/compile.rs b/src/libregex/compile.rs index 869dd25e3fa..c4b517c5259 100644 --- a/src/libregex/compile.rs +++ b/src/libregex/compile.rs @@ -16,7 +16,7 @@ use std::cmp; use parse; use parse::{ Flags, FLAG_EMPTY, - Nothing, Literal, Dot, Class, Begin, End, WordBoundary, Capture, Cat, Alt, + Nothing, Literal, Dot, AstClass, Begin, End, WordBoundary, Capture, Cat, Alt, Rep, ZeroOne, ZeroMore, OneMore, }; @@ -148,7 +148,7 @@ impl<'r> Compiler<'r> { Nothing => {}, Literal(c, flags) => self.push(OneChar(c, flags)), Dot(nl) => self.push(Any(nl)), - Class(ranges, flags) => + AstClass(ranges, flags) => self.push(CharClass(ranges, flags)), Begin(flags) => self.push(EmptyBegin(flags)), End(flags) => self.push(EmptyEnd(flags)), diff --git a/src/libregex/lib.rs b/src/libregex/lib.rs index 4f849a8a67b..9ff65fe3e2a 100644 --- a/src/libregex/lib.rs +++ b/src/libregex/lib.rs @@ -425,7 +425,7 @@ pub mod native { FLAG_EMPTY, FLAG_NOCASE, FLAG_MULTI, FLAG_DOTNL, FLAG_SWAP_GREED, FLAG_NEGATED, }; - pub use re::{Dynamic, Native}; + pub use re::{Dynamic, ExDynamic, Native, ExNative}; pub use vm::{ MatchKind, Exists, Location, Submatches, StepState, StepMatchEarlyReturn, StepMatch, StepContinue, diff --git a/src/libregex/parse.rs b/src/libregex/parse.rs index 12555b7c443..ad60829c088 100644 --- a/src/libregex/parse.rs +++ b/src/libregex/parse.rs @@ -53,7 +53,7 @@ pub enum Ast { Nothing, Literal(char, Flags), Dot(Flags), - Class(Vec<(char, char)>, Flags), + AstClass(Vec<(char, char)>, Flags), Begin(Flags), End(Flags), WordBoundary(Flags), @@ -101,7 +101,7 @@ impl Greed { /// state. #[deriving(Show)] enum BuildAst { - Ast(Ast), + Expr(Ast), Paren(Flags, uint, String), // '(' Bar, // '|' } @@ -152,7 +152,7 @@ impl BuildAst { fn unwrap(self) -> Result<Ast, Error> { match self { - Ast(x) => Ok(x), + Expr(x) => Ok(x), _ => fail!("Tried to unwrap non-AST item: {}", self), } } @@ -311,7 +311,7 @@ impl<'a> Parser<'a> { } fn push(&mut self, ast: Ast) { - self.stack.push(Ast(ast)) + self.stack.push(Expr(ast)) } fn push_repeater(&mut self, c: char) -> Result<(), Error> { @@ -388,8 +388,8 @@ impl<'a> Parser<'a> { match c { '[' => match self.try_parse_ascii() { - Some(Class(asciis, flags)) => { - alts.push(Class(asciis, flags ^ negated)); + Some(AstClass(asciis, flags)) => { + alts.push(AstClass(asciis, flags ^ negated)); continue } Some(ast) => @@ -399,8 +399,8 @@ impl<'a> Parser<'a> { }, '\\' => { match try!(self.parse_escape()) { - Class(asciis, flags) => { - alts.push(Class(asciis, flags ^ negated)); + AstClass(asciis, flags) => { + alts.push(AstClass(asciis, flags ^ negated)); continue } Literal(c2, _) => c = c2, // process below @@ -417,7 +417,7 @@ impl<'a> Parser<'a> { ']' => { if ranges.len() > 0 { let flags = negated | (self.flags & FLAG_NOCASE); - let mut ast = Class(combine_ranges(ranges), flags); + let mut ast = AstClass(combine_ranges(ranges), flags); for alt in alts.into_iter() { ast = Alt(box alt, box ast) } @@ -485,7 +485,7 @@ impl<'a> Parser<'a> { Some(ranges) => { self.chari = closer; let flags = negated | (self.flags & FLAG_NOCASE); - Some(Class(combine_ranges(ranges), flags)) + Some(AstClass(combine_ranges(ranges), flags)) } } } @@ -611,7 +611,7 @@ impl<'a> Parser<'a> { let ranges = perl_unicode_class(c); let mut flags = self.flags & FLAG_NOCASE; if c.is_uppercase() { flags |= FLAG_NEGATED } - Ok(Class(ranges, flags)) + Ok(AstClass(ranges, flags)) } _ => { self.err(format!("Invalid escape sequence '\\\\{}'", @@ -655,7 +655,7 @@ impl<'a> Parser<'a> { name).as_slice()) } Some(ranges) => { - Ok(Class(ranges, negated | (self.flags & FLAG_NOCASE))) + Ok(AstClass(ranges, negated | (self.flags & FLAG_NOCASE))) } } } @@ -888,7 +888,7 @@ impl<'a> Parser<'a> { while i > from { i = i - 1; match self.stack.pop().unwrap() { - Ast(x) => combined = mk(x, combined), + Expr(x) => combined = mk(x, combined), _ => {}, } } diff --git a/src/libregex/re.rs b/src/libregex/re.rs index 8e4145b2a31..c2578d227ee 100644 --- a/src/libregex/re.rs +++ b/src/libregex/re.rs @@ -110,14 +110,14 @@ pub enum Regex { // See the comments for the `program` module in `lib.rs` for a more // detailed explanation for what `regex!` requires. #[doc(hidden)] - Dynamic(Dynamic), + Dynamic(ExDynamic), #[doc(hidden)] - Native(Native), + Native(ExNative), } #[deriving(Clone)] #[doc(hidden)] -pub struct Dynamic { +pub struct ExDynamic { original: String, names: Vec<Option<String>>, #[doc(hidden)] @@ -125,7 +125,7 @@ pub struct Dynamic { } #[doc(hidden)] -pub struct Native { +pub struct ExNative { #[doc(hidden)] pub original: &'static str, #[doc(hidden)] @@ -134,8 +134,8 @@ pub struct Native { pub prog: fn(MatchKind, &str, uint, uint) -> Vec<Option<uint>> } -impl Clone for Native { - fn clone(&self) -> Native { *self } +impl Clone for ExNative { + fn clone(&self) -> ExNative { *self } } impl fmt::Show for Regex { @@ -156,7 +156,7 @@ impl Regex { pub fn new(re: &str) -> Result<Regex, parse::Error> { let ast = try!(parse::parse(re)); let (prog, names) = Program::new(ast); - Ok(Dynamic(Dynamic { + Ok(Dynamic(ExDynamic { original: re.to_string(), names: names, prog: prog, @@ -510,8 +510,8 @@ impl Regex { /// Returns the original string of this regex. pub fn as_str<'a>(&'a self) -> &'a str { match *self { - Dynamic(Dynamic { ref original, .. }) => original.as_slice(), - Native(Native { ref original, .. }) => original.as_slice(), + Dynamic(ExDynamic { ref original, .. }) => original.as_slice(), + Native(ExNative { ref original, .. }) => original.as_slice(), } } @@ -915,8 +915,8 @@ fn exec(re: &Regex, which: MatchKind, input: &str) -> CaptureLocs { fn exec_slice(re: &Regex, which: MatchKind, input: &str, s: uint, e: uint) -> CaptureLocs { match *re { - Dynamic(Dynamic { ref prog, .. }) => vm::run(which, prog, input, s, e), - Native(Native { prog, .. }) => prog(which, input, s, e), + Dynamic(ExDynamic { ref prog, .. }) => vm::run(which, prog, input, s, e), + Native(ExNative { prog, .. }) => prog(which, input, s, e), } } diff --git a/src/libregex_macros/lib.rs b/src/libregex_macros/lib.rs index 12809184003..ae6dd2a4d70 100644 --- a/src/libregex_macros/lib.rs +++ b/src/libregex_macros/lib.rs @@ -42,7 +42,7 @@ use regex::Regex; use regex::native::{ OneChar, CharClass, Any, Save, Jump, Split, Match, EmptyBegin, EmptyEnd, EmptyWordBoundary, - Program, Dynamic, Native, + Program, Dynamic, ExDynamic, Native, FLAG_NOCASE, FLAG_MULTI, FLAG_DOTNL, FLAG_NEGATED, }; @@ -91,7 +91,7 @@ fn native(cx: &mut ExtCtxt, sp: codemap::Span, tts: &[ast::TokenTree]) } }; let prog = match re { - Dynamic(Dynamic { ref prog, .. }) => prog.clone(), + Dynamic(ExDynamic { ref prog, .. }) => prog.clone(), Native(_) => unreachable!(), }; @@ -322,7 +322,7 @@ fn exec<'t>(which: ::regex::native::MatchKind, input: &'t str, } } -::regex::native::Native(::regex::native::Native { +::regex::native::Native(::regex::native::ExNative { original: $regex, names: CAP_NAMES, prog: exec, diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index de1eef1dce3..d31e19b4467 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -659,19 +659,18 @@ fn link_rlib<'a>(sess: &'a Session, ab.add_file(&metadata).unwrap(); remove(sess, &metadata); - if sess.opts.cg.codegen_units == 1 { - // For LTO purposes, the bytecode of this library is also - // inserted into the archive. We currently do this only when - // codegen_units == 1, so we don't have to deal with multiple - // bitcode files per crate. - // + // For LTO purposes, the bytecode of this library is also inserted + // into the archive. If codegen_units > 1, we insert each of the + // bitcode files. + for i in range(0, sess.opts.cg.codegen_units) { // Note that we make sure that the bytecode filename in the // archive is never exactly 16 bytes long by adding a 16 byte // extension to it. This is to work around a bug in LLDB that // would cause it to crash if the name of a file in an archive // was exactly 16 bytes. - let bc_filename = obj_filename.with_extension("bc"); - let bc_deflated_filename = obj_filename.with_extension("bytecode.deflate"); + let bc_filename = obj_filename.with_extension(format!("{}.bc", i).as_slice()); + let bc_deflated_filename = obj_filename.with_extension( + format!("{}.bytecode.deflate", i).as_slice()); let bc_data = match fs::File::open(&bc_filename).read_to_end() { Ok(buffer) => buffer, @@ -705,8 +704,13 @@ fn link_rlib<'a>(sess: &'a Session, ab.add_file(&bc_deflated_filename).unwrap(); remove(sess, &bc_deflated_filename); - if !sess.opts.cg.save_temps && - !sess.opts.output_types.contains(&OutputTypeBitcode) { + + // See the bottom of back::write::run_passes for an explanation + // of when we do and don't keep .0.bc files around. + let user_wants_numbered_bitcode = + sess.opts.output_types.contains(&OutputTypeBitcode) && + sess.opts.cg.codegen_units > 1; + if !sess.opts.cg.save_temps && !user_wants_numbered_bitcode { remove(sess, &bc_filename); } } @@ -1024,7 +1028,9 @@ fn link_args(cmd: &mut Command, // Mark all dynamic libraries and executables as compatible with ASLR // FIXME #17098: ASLR breaks gdb - // cmd.arg("-Wl,--dynamicbase"); + if sess.opts.debuginfo == NoDebugInfo { + cmd.arg("-Wl,--dynamicbase"); + } // Mark all dynamic libraries and executables as compatible with the larger 4GiB address // space available to x86 Windows binaries on x86_64. diff --git a/src/librustc/back/lto.rs b/src/librustc/back/lto.rs index 250557d0af1..cd425b5fec1 100644 --- a/src/librustc/back/lto.rs +++ b/src/librustc/back/lto.rs @@ -21,6 +21,7 @@ use util::common::time; use libc; use flate; +use std::iter; use std::mem; pub fn run(sess: &session::Session, llmod: ModuleRef, @@ -60,78 +61,84 @@ pub fn run(sess: &session::Session, llmod: ModuleRef, let file = path.filename_str().unwrap(); let file = file.slice(3, file.len() - 5); // chop off lib/.rlib debug!("reading {}", file); - let bc_encoded = time(sess.time_passes(), - format!("read {}.bytecode.deflate", name).as_slice(), - (), - |_| { - archive.read(format!("{}.bytecode.deflate", - file).as_slice()) - }); - let bc_encoded = match bc_encoded { - Some(data) => data, - None => { - sess.fatal(format!("missing compressed bytecode in {} \ - (perhaps it was compiled with -C codegen-units > 1)", - path.display()).as_slice()); - }, - }; - let bc_extractor = if is_versioned_bytecode_format(bc_encoded) { - |_| { - // Read the version - let version = extract_bytecode_format_version(bc_encoded); - - if version == 1 { - // The only version existing so far - let data_size = extract_compressed_bytecode_size_v1(bc_encoded); - let compressed_data = bc_encoded.slice( - link::RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET, - link::RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET + data_size as uint); - - match flate::inflate_bytes(compressed_data) { - Some(inflated) => inflated, + for i in iter::count(0u, 1) { + let bc_encoded = time(sess.time_passes(), + format!("check for {}.{}.bytecode.deflate", name, i).as_slice(), + (), + |_| { + archive.read(format!("{}.{}.bytecode.deflate", + file, i).as_slice()) + }); + let bc_encoded = match bc_encoded { + Some(data) => data, + None => { + if i == 0 { + // No bitcode was found at all. + sess.fatal(format!("missing compressed bytecode in {}", + path.display()).as_slice()); + } + // No more bitcode files to read. + break; + }, + }; + let bc_extractor = if is_versioned_bytecode_format(bc_encoded) { + |_| { + // Read the version + let version = extract_bytecode_format_version(bc_encoded); + + if version == 1 { + // The only version existing so far + let data_size = extract_compressed_bytecode_size_v1(bc_encoded); + let compressed_data = bc_encoded.slice( + link::RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET, + link::RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET + data_size as uint); + + match flate::inflate_bytes(compressed_data) { + Some(inflated) => inflated, + None => { + sess.fatal(format!("failed to decompress bc of `{}`", + name).as_slice()) + } + } + } else { + sess.fatal(format!("Unsupported bytecode format version {}", + version).as_slice()) + } + } + } else { + // the object must be in the old, pre-versioning format, so simply + // inflate everything and let LLVM decide if it can make sense of it + |_| { + match flate::inflate_bytes(bc_encoded) { + Some(bc) => bc, None => { sess.fatal(format!("failed to decompress bc of `{}`", name).as_slice()) } } - } else { - sess.fatal(format!("Unsupported bytecode format version {}", - version).as_slice()) } - } - } else { - // the object must be in the old, pre-versioning format, so simply - // inflate everything and let LLVM decide if it can make sense of it - |_| { - match flate::inflate_bytes(bc_encoded) { - Some(bc) => bc, - None => { - sess.fatal(format!("failed to decompress bc of `{}`", - name).as_slice()) - } + }; + + let bc_decoded = time(sess.time_passes(), + format!("decode {}.{}.bc", file, i).as_slice(), + (), + bc_extractor); + + let ptr = bc_decoded.as_slice().as_ptr(); + debug!("linking {}, part {}", name, i); + time(sess.time_passes(), + format!("ll link {}.{}", name, i).as_slice(), + (), + |()| unsafe { + if !llvm::LLVMRustLinkInExternalBitcode(llmod, + ptr as *const libc::c_char, + bc_decoded.len() as libc::size_t) { + write::llvm_err(sess.diagnostic().handler(), + format!("failed to load bc of `{}`", + name.as_slice())); } - } - }; - - let bc_decoded = time(sess.time_passes(), - format!("decode {}.bc", file).as_slice(), - (), - bc_extractor); - - let ptr = bc_decoded.as_slice().as_ptr(); - debug!("linking {}", name); - time(sess.time_passes(), - format!("ll link {}", name).as_slice(), - (), - |()| unsafe { - if !llvm::LLVMRustLinkInExternalBitcode(llmod, - ptr as *const libc::c_char, - bc_decoded.len() as libc::size_t) { - write::llvm_err(sess.diagnostic().handler(), - format!("failed to load bc of `{}`", - name.as_slice())); - } - }); + }); + } } // Internalize everything but the reachable symbols of the current module diff --git a/src/librustc/back/write.rs b/src/librustc/back/write.rs index cff5ac5375d..7242c12ae0c 100644 --- a/src/librustc/back/write.rs +++ b/src/librustc/back/write.rs @@ -11,7 +11,7 @@ use back::lto; use back::link::{get_cc_prog, remove}; use driver::driver::{CrateTranslation, ModuleTranslation, OutputFilenames}; -use driver::config::{NoDebugInfo, Passes, AllPasses}; +use driver::config::{NoDebugInfo, Passes, SomePasses, AllPasses}; use driver::session::Session; use driver::config; use llvm; @@ -341,7 +341,7 @@ unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_vo let pass_name = pass_name.as_str().expect("got a non-UTF8 pass name from LLVM"); let enabled = match cgcx.remark { AllPasses => true, - Passes(ref v) => v.iter().any(|s| s.as_slice() == pass_name), + SomePasses(ref v) => v.iter().any(|s| s.as_slice() == pass_name), }; if enabled { @@ -482,14 +482,14 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, if config.emit_asm { let path = output_names.with_extension(format!("{}.s", name_extra).as_slice()); with_codegen(tm, llmod, config.no_builtins, |cpm| { - write_output_file(cgcx.handler, tm, cpm, llmod, &path, llvm::AssemblyFile); + write_output_file(cgcx.handler, tm, cpm, llmod, &path, llvm::AssemblyFileType); }); } if config.emit_obj { let path = output_names.with_extension(format!("{}.o", name_extra).as_slice()); with_codegen(tm, llmod, config.no_builtins, |cpm| { - write_output_file(cgcx.handler, tm, cpm, llmod, &path, llvm::ObjectFile); + write_output_file(cgcx.handler, tm, cpm, llmod, &path, llvm::ObjectFileType); }); } }); @@ -540,13 +540,12 @@ pub fn run_passes(sess: &Session, metadata_config.emit_bc = true; } - // Emit a bitcode file for the crate if we're emitting an rlib. + // Emit bitcode files for the crate if we're emitting an rlib. // Whenever an rlib is created, the bitcode is inserted into the // archive in order to allow LTO against it. let needs_crate_bitcode = sess.crate_types.borrow().contains(&config::CrateTypeRlib) && - sess.opts.output_types.contains(&OutputTypeExe) && - sess.opts.cg.codegen_units == 1; + sess.opts.output_types.contains(&OutputTypeExe); if needs_crate_bitcode { modules_config.emit_bc = true; } @@ -602,19 +601,8 @@ pub fn run_passes(sess: &Session, // Process the work items, optionally using worker threads. if sess.opts.cg.codegen_units == 1 { run_work_singlethreaded(sess, trans.reachable.as_slice(), work_items); - - if needs_crate_bitcode { - // The only bitcode file produced (aside from metadata) was - // "crate.0.bc". Rename to "crate.bc" since that's what - // `link_rlib` expects to find. - fs::copy(&crate_output.with_extension("0.bc"), - &crate_output.temp_path(OutputTypeBitcode)).unwrap(); - } } else { run_work_multithreaded(sess, work_items, sess.opts.cg.codegen_units); - - assert!(!needs_crate_bitcode, - "can't produce a crate bitcode file from multiple compilation units"); } // All codegen is finished. @@ -624,14 +612,14 @@ pub fn run_passes(sess: &Session, // Produce final compile outputs. - let copy_if_one_unit = |ext: &str, output_type: OutputType| { + let copy_if_one_unit = |ext: &str, output_type: OutputType, keep_numbered: bool| { // Three cases: if sess.opts.cg.codegen_units == 1 { // 1) Only one codegen unit. In this case it's no difficulty // to copy `foo.0.x` to `foo.x`. fs::copy(&crate_output.with_extension(ext), &crate_output.path(output_type)).unwrap(); - if !sess.opts.cg.save_temps { + if !sess.opts.cg.save_temps && !keep_numbered { // The user just wants `foo.x`, not `foo.0.x`. remove(sess, &crate_output.with_extension(ext)); } @@ -716,17 +704,18 @@ pub fn run_passes(sess: &Session, // Flag to indicate whether the user explicitly requested bitcode. // Otherwise, we produced it only as a temporary output, and will need // to get rid of it. - // FIXME: Since we don't support LTO anyway, maybe we can avoid - // producing the temporary .0.bc's in the first place? - let mut save_bitcode = false; + let mut user_wants_bitcode = false; for output_type in output_types.iter() { match *output_type { OutputTypeBitcode => { - save_bitcode = true; - copy_if_one_unit("0.bc", OutputTypeBitcode); + user_wants_bitcode = true; + // Copy to .bc, but always keep the .0.bc. There is a later + // check to figure out if we should delete .0.bc files, or keep + // them for making an rlib. + copy_if_one_unit("0.bc", OutputTypeBitcode, true); }, - OutputTypeLlvmAssembly => { copy_if_one_unit("0.ll", OutputTypeLlvmAssembly); }, - OutputTypeAssembly => { copy_if_one_unit("0.s", OutputTypeAssembly); }, + OutputTypeLlvmAssembly => { copy_if_one_unit("0.ll", OutputTypeLlvmAssembly, false); }, + OutputTypeAssembly => { copy_if_one_unit("0.s", OutputTypeAssembly, false); }, OutputTypeObject => { link_obj(&crate_output.path(OutputTypeObject)); }, OutputTypeExe => { // If OutputTypeObject is already in the list, then @@ -739,7 +728,7 @@ pub fn run_passes(sess: &Session, }, } } - let save_bitcode = save_bitcode; + let user_wants_bitcode = user_wants_bitcode; // Clean up unwanted temporary files. @@ -755,22 +744,36 @@ pub fn run_passes(sess: &Session, if !sess.opts.cg.save_temps { // Remove the temporary .0.o objects. If the user didn't - // explicitly request bitcode (with --emit=bc), we must remove - // .0.bc as well. (We don't touch the crate.bc that may have been - // produced earlier.) + // explicitly request bitcode (with --emit=bc), and the bitcode is not + // needed for building an rlib, then we must remove .0.bc as well. + + // Specific rules for keeping .0.bc: + // - If we're building an rlib (`needs_crate_bitcode`), then keep + // it. + // - If the user requested bitcode (`user_wants_bitcode`), and + // codegen_units > 1, then keep it. + // - If the user requested bitcode but codegen_units == 1, then we + // can toss .0.bc because we copied it to .bc earlier. + // - If we're not building an rlib and the user didn't request + // bitcode, then delete .0.bc. + // If you change how this works, also update back::link::link_rlib, + // where .0.bc files are (maybe) deleted after making an rlib. + let keep_numbered_bitcode = needs_crate_bitcode || + (user_wants_bitcode && sess.opts.cg.codegen_units > 1); + for i in range(0, trans.modules.len()) { if modules_config.emit_obj { let ext = format!("{}.o", i); remove(sess, &crate_output.with_extension(ext.as_slice())); } - if modules_config.emit_bc && !save_bitcode { + if modules_config.emit_bc && !keep_numbered_bitcode { let ext = format!("{}.bc", i); remove(sess, &crate_output.with_extension(ext.as_slice())); } } - if metadata_config.emit_bc && !save_bitcode { + if metadata_config.emit_bc && !user_wants_bitcode { remove(sess, &crate_output.with_extension("metadata.bc")); } } diff --git a/src/librustc/driver/config.rs b/src/librustc/driver/config.rs index 309c7a44c5d..72e2d244ad3 100644 --- a/src/librustc/driver/config.rs +++ b/src/librustc/driver/config.rs @@ -237,14 +237,14 @@ pub fn debugging_opts_map() -> Vec<(&'static str, &'static str, u64)> { #[deriving(Clone)] pub enum Passes { - Passes(Vec<String>), + SomePasses(Vec<String>), AllPasses, } impl Passes { pub fn is_empty(&self) -> bool { match *self { - Passes(ref v) => v.is_empty(), + SomePasses(ref v) => v.is_empty(), AllPasses => false, } } @@ -276,7 +276,7 @@ macro_rules! cgoptions( &[ $( (stringify!($opt), cgsetters::$opt, $desc) ),* ]; mod cgsetters { - use super::{CodegenOptions, Passes, AllPasses}; + use super::{CodegenOptions, Passes, SomePasses, AllPasses}; $( pub fn $opt(cg: &mut CodegenOptions, v: Option<&str>) -> bool { @@ -335,7 +335,7 @@ macro_rules! cgoptions( v => { let mut passes = vec!(); if parse_list(&mut passes, v) { - *slot = Passes(passes); + *slot = SomePasses(passes); true } else { false @@ -389,7 +389,7 @@ cgoptions!( "extra data to put in each output filename"), codegen_units: uint = (1, parse_uint, "divide crate into N units to optimize in parallel"), - remark: Passes = (Passes(Vec::new()), parse_passes, + remark: Passes = (SomePasses(Vec::new()), parse_passes, "print remarks for these optimization passes (space separated, or \"all\")"), ) diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index bb454e07fc1..4ff9133c8a5 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -17,7 +17,7 @@ use lint; use llvm::{ContextRef, ModuleRef}; use metadata::common::LinkMeta; use metadata::creader; -use middle::{trans, freevars, stability, kind, ty, typeck, reachable}; +use middle::{trans, stability, kind, ty, typeck, reachable}; use middle::dependency_format; use middle; use plugin::load::Plugins; @@ -378,11 +378,13 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session, middle::lang_items::collect_language_items(krate, &sess)); let middle::resolve::CrateMap { - def_map: def_map, - exp_map2: exp_map2, - trait_map: trait_map, - external_exports: external_exports, - last_private_map: last_private_map + def_map, + freevars, + capture_mode_map, + exp_map2, + trait_map, + external_exports, + last_private_map } = time(time_passes, "resolution", (), |_| middle::resolve::resolve_crate(&sess, &lang_items, krate)); @@ -401,10 +403,6 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session, plugin::build::find_plugin_registrar( sess.diagnostic(), krate))); - let (freevars, capture_modes) = - time(time_passes, "freevar finding", (), |_| - freevars::annotate_freevars(&def_map, krate)); - let region_map = time(time_passes, "region resolution", (), |_| middle::region::resolve_crate(&sess, krate)); @@ -423,7 +421,7 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session, named_region_map, ast_map, freevars, - capture_modes, + capture_mode_map, region_map, lang_items, stability_index); diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index c5b9f33be28..2994954c3d7 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -29,7 +29,7 @@ This API is completely unstable and subject to change. html_root_url = "http://doc.rust-lang.org/master/")] #![allow(deprecated)] -#![feature(macro_rules, globs, struct_variant, managed_boxes, quote)] +#![feature(macro_rules, globs, struct_variant, quote)] #![feature(default_type_params, phase, unsafe_destructor)] #![allow(unknown_features)] // NOTE: Remove after next snapshot @@ -93,7 +93,6 @@ pub mod middle { pub mod effect; pub mod entry; pub mod expr_use_visitor; - pub mod freevars; pub mod graph; pub mod intrinsicck; pub mod kind; diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 473c3935769..588e275455a 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -42,7 +42,7 @@ use syntax::abi; use syntax::ast_map; use syntax::attr::AttrMetaMethods; use syntax::attr; -use syntax::codemap::Span; +use syntax::codemap::{Span, NO_EXPANSION}; use syntax::parse::token; use syntax::{ast, ast_util, visit}; use syntax::ptr::P; @@ -954,8 +954,7 @@ impl LintPass for NonSnakeCase { match &p.node { &ast::PatIdent(_, ref path1, _) => { match cx.tcx.def_map.borrow().find(&p.id) { - Some(&def::DefLocal(_, _)) | Some(&def::DefBinding(_, _)) | - Some(&def::DefArg(_, _)) => { + Some(&def::DefLocal(_)) => { self.check_snake_case(cx, "variable", path1.node, p.span); } _ => {} @@ -1297,7 +1296,7 @@ impl LintPass for UnnecessaryAllocation { match cx.tcx.adjustments.borrow().find(&e.id) { Some(adjustment) => { match *adjustment { - ty::AutoDerefRef(ty::AutoDerefRef { ref autoref, .. }) => { + ty::AdjustDerefRef(ty::AutoDerefRef { ref autoref, .. }) => { match (allocation, autoref) { (VectorAllocation, &Some(ty::AutoPtr(_, _, None))) => { cx.span_lint(UNNECESSARY_ALLOCATION, e.span, @@ -1492,7 +1491,7 @@ impl LintPass for Stability { fn check_expr(&mut self, cx: &Context, e: &ast::Expr) { // if the expression was produced by a macro expansion, - if e.span.expn_info.is_some() { return } + if e.span.expn_id != NO_EXPANSION { return } let id = match e.node { ast::ExprPath(..) | ast::ExprStruct(..) => { @@ -1512,12 +1511,12 @@ impl LintPass for Stability { typeck::MethodStaticUnboxedClosure(def_id) => { def_id } - typeck::MethodParam(typeck::MethodParam { + typeck::MethodTypeParam(typeck::MethodParam { trait_ref: ref trait_ref, method_num: index, .. }) | - typeck::MethodObject(typeck::MethodObject { + typeck::MethodTraitObject(typeck::MethodObject { trait_ref: ref trait_ref, method_num: index, .. diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 399313ddd8e..acb4f1be85c 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -18,13 +18,12 @@ use driver::session::Session; use metadata::decoder; use middle::def; use metadata::encoder as e; -use middle::freevars::{CaptureMode, freevar_entry}; -use middle::freevars; use middle::region; use metadata::tydecode; use metadata::tydecode::{DefIdSource, NominalType, TypeWithId, TypeParameter}; use metadata::tydecode::{RegionParameter}; use metadata::tyencode; +use middle::mem_categorization::Typer; use middle::subst; use middle::subst::VecPerParamSpace; use middle::typeck::{MethodCall, MethodCallee, MethodOrigin}; @@ -42,7 +41,6 @@ use syntax; use libc; use std::io::Seek; use std::mem; -use std::gc::GC; use std::rc::Rc; use rbml::io::SeekableMemWriter; @@ -462,8 +460,7 @@ impl tr for def::Def { def::DefMod(did) => { def::DefMod(did.tr(dcx)) } def::DefForeignMod(did) => { def::DefForeignMod(did.tr(dcx)) } def::DefStatic(did, m) => { def::DefStatic(did.tr(dcx), m) } - def::DefArg(nid, b) => { def::DefArg(dcx.tr_id(nid), b) } - def::DefLocal(nid, b) => { def::DefLocal(dcx.tr_id(nid), b) } + def::DefLocal(nid) => { def::DefLocal(dcx.tr_id(nid)) } def::DefVariant(e_did, v_did, is_s) => { def::DefVariant(e_did.tr(dcx), v_did.tr(dcx), is_s) }, @@ -472,11 +469,9 @@ impl tr for def::Def { def::DefAssociatedTy(did) => def::DefAssociatedTy(did.tr(dcx)), def::DefPrimTy(p) => def::DefPrimTy(p), def::DefTyParam(s, did, v) => def::DefTyParam(s, did.tr(dcx), v), - def::DefBinding(nid, bm) => def::DefBinding(dcx.tr_id(nid), bm), def::DefUse(did) => def::DefUse(did.tr(dcx)), - def::DefUpvar(nid1, def, nid2, nid3) => { + def::DefUpvar(nid1, nid2, nid3) => { def::DefUpvar(dcx.tr_id(nid1), - box(GC) (*def).tr(dcx), dcx.tr_id(nid2), dcx.tr_id(nid3)) } @@ -541,36 +536,36 @@ impl tr for ty::TraitStore { // ______________________________________________________________________ // Encoding and decoding of freevar information -fn encode_freevar_entry(rbml_w: &mut Encoder, fv: &freevar_entry) { +fn encode_freevar_entry(rbml_w: &mut Encoder, fv: &ty::Freevar) { (*fv).encode(rbml_w).unwrap(); } -fn encode_capture_mode(rbml_w: &mut Encoder, cm: CaptureMode) { +fn encode_capture_mode(rbml_w: &mut Encoder, cm: ast::CaptureClause) { cm.encode(rbml_w).unwrap(); } trait rbml_decoder_helper { fn read_freevar_entry(&mut self, dcx: &DecodeContext) - -> freevar_entry; - fn read_capture_mode(&mut self) -> CaptureMode; + -> ty::Freevar; + fn read_capture_mode(&mut self) -> ast::CaptureClause; } impl<'a> rbml_decoder_helper for reader::Decoder<'a> { fn read_freevar_entry(&mut self, dcx: &DecodeContext) - -> freevar_entry { - let fv: freevar_entry = Decodable::decode(self).unwrap(); + -> ty::Freevar { + let fv: ty::Freevar = Decodable::decode(self).unwrap(); fv.tr(dcx) } - fn read_capture_mode(&mut self) -> CaptureMode { - let cm: CaptureMode = Decodable::decode(self).unwrap(); + fn read_capture_mode(&mut self) -> ast::CaptureClause { + let cm: ast::CaptureClause = Decodable::decode(self).unwrap(); cm } } -impl tr for freevar_entry { - fn tr(&self, dcx: &DecodeContext) -> freevar_entry { - freevar_entry { +impl tr for ty::Freevar { + fn tr(&self, dcx: &DecodeContext) -> ty::Freevar { + ty::Freevar { def: self.def.tr(dcx), span: self.span.tr(dcx), } @@ -646,8 +641,8 @@ impl tr for MethodOrigin { typeck::MethodStaticUnboxedClosure(did) => { typeck::MethodStaticUnboxedClosure(did.tr(dcx)) } - typeck::MethodParam(ref mp) => { - typeck::MethodParam( + typeck::MethodTypeParam(ref mp) => { + typeck::MethodTypeParam( typeck::MethodParam { // def-id is already translated when we read it out trait_ref: mp.trait_ref.clone(), @@ -655,8 +650,8 @@ impl tr for MethodOrigin { } ) } - typeck::MethodObject(ref mo) => { - typeck::MethodObject( + typeck::MethodTraitObject(ref mo) => { + typeck::MethodTraitObject( typeck::MethodObject { trait_ref: mo.trait_ref.clone(), .. *mo @@ -962,8 +957,8 @@ impl<'a> rbml_writer_helpers for Encoder<'a> { }) } - typeck::MethodParam(ref p) => { - this.emit_enum_variant("MethodParam", 2, 1, |this| { + typeck::MethodTypeParam(ref p) => { + this.emit_enum_variant("MethodTypeParam", 2, 1, |this| { this.emit_struct("MethodParam", 2, |this| { try!(this.emit_struct_field("trait_ref", 0, |this| { Ok(this.emit_trait_ref(ecx, &*p.trait_ref)) @@ -976,8 +971,8 @@ impl<'a> rbml_writer_helpers for Encoder<'a> { }) } - typeck::MethodObject(ref o) => { - this.emit_enum_variant("MethodObject", 3, 1, |this| { + typeck::MethodTraitObject(ref o) => { + this.emit_enum_variant("MethodTraitObject", 3, 1, |this| { this.emit_struct("MethodObject", 2, |this| { try!(this.emit_struct_field("trait_ref", 0, |this| { Ok(this.emit_trait_ref(ecx, &*o.trait_ref)) @@ -1072,13 +1067,13 @@ impl<'a> rbml_writer_helpers for Encoder<'a> { self.emit_enum("AutoAdjustment", |this| { match *adj { - ty::AutoAddEnv(store) => { + ty::AdjustAddEnv(store) => { this.emit_enum_variant("AutoAddEnv", 0, 1, |this| { this.emit_enum_variant_arg(0, |this| store.encode(this)) }) } - ty::AutoDerefRef(ref auto_deref_ref) => { + ty::AdjustDerefRef(ref auto_deref_ref) => { this.emit_enum_variant("AutoDerefRef", 1, 1, |this| { this.emit_enum_variant_arg(0, |this| Ok(this.emit_auto_deref_ref(ecx, auto_deref_ref))) @@ -1292,8 +1287,8 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, }); for freevar in fv.iter() { - match freevars::get_capture_mode(tcx, id) { - freevars::CaptureByRef => { + match tcx.capture_mode(id) { + ast::CaptureByRef => { rbml_w.tag(c::tag_table_upvar_borrow_map, |rbml_w| { rbml_w.id(id); rbml_w.tag(c::tag_table_val, |rbml_w| { @@ -1374,7 +1369,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, }) } } - ty::AutoDerefRef(ref adj) => { + ty::AdjustDerefRef(ref adj) => { assert!(!ty::adjust_is_object(adjustment)); for autoderef in range(0, adj.autoderefs) { let method_call = MethodCall::autoderef(id, autoderef); @@ -1505,7 +1500,7 @@ impl<'a> rbml_decoder_decoder_helpers for reader::Decoder<'a> { { self.read_enum("MethodOrigin", |this| { let variants = ["MethodStatic", "MethodStaticUnboxedClosure", - "MethodParam", "MethodObject"]; + "MethodTypeParam", "MethodTraitObject"]; this.read_enum_variant(variants, |this, i| { Ok(match i { 0 => { @@ -1519,8 +1514,8 @@ impl<'a> rbml_decoder_decoder_helpers for reader::Decoder<'a> { } 2 => { - this.read_struct("MethodParam", 2, |this| { - Ok(typeck::MethodParam( + this.read_struct("MethodTypeParam", 2, |this| { + Ok(typeck::MethodTypeParam( typeck::MethodParam { trait_ref: { this.read_struct_field("trait_ref", 0, |this| { @@ -1537,8 +1532,8 @@ impl<'a> rbml_decoder_decoder_helpers for reader::Decoder<'a> { } 3 => { - this.read_struct("MethodObject", 2, |this| { - Ok(typeck::MethodObject( + this.read_struct("MethodTraitObject", 2, |this| { + Ok(typeck::MethodTraitObject( typeck::MethodObject { trait_ref: { this.read_struct_field("trait_ref", 0, |this| { @@ -1685,14 +1680,14 @@ impl<'a> rbml_decoder_decoder_helpers for reader::Decoder<'a> { let store: ty::TraitStore = this.read_enum_variant_arg(0, |this| Decodable::decode(this)).unwrap(); - ty::AutoAddEnv(store.tr(dcx)) + ty::AdjustAddEnv(store.tr(dcx)) } 1 => { let auto_deref_ref: ty::AutoDerefRef = this.read_enum_variant_arg(0, |this| Ok(this.read_auto_deref_ref(dcx))).unwrap(); - ty::AutoDerefRef(auto_deref_ref) + ty::AdjustDerefRef(auto_deref_ref) } _ => fail!("bad enum variant for ty::AutoAdjustment") }) @@ -2035,7 +2030,7 @@ impl fake_ext_ctxt for parse::ParseSess { codemap::Span { lo: codemap::BytePos(0), hi: codemap::BytePos(0), - expn_info: None + expn_id: codemap::NO_EXPANSION } } fn ident_of(&self, st: &str) -> ast::Ident { diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index df637e7a052..95009bc2dbf 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -514,9 +514,9 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { true } - pub fn is_local_variable_or_arg(&self, cmt: mc::cmt) -> bool { + fn is_local_variable_or_arg(&self, cmt: mc::cmt) -> bool { match cmt.cat { - mc::cat_local(_) | mc::cat_arg(_) => true, + mc::cat_local(_) => true, _ => false } } @@ -775,7 +775,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { debug!("mark_variable_as_used_mut(cmt={})", cmt.repr(this.tcx())); match cmt.cat.clone() { mc::cat_copied_upvar(mc::CopiedUpvar { upvar_id: id, .. }) | - mc::cat_local(id) | mc::cat_arg(id) => { + mc::cat_local(id) => { this.tcx().used_mut_nodes.borrow_mut().insert(id); return; } diff --git a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs index f58cc950383..25439fce68c 100644 --- a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs +++ b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs @@ -147,8 +147,7 @@ fn check_and_get_illegal_move_origin(bccx: &BorrowckCtxt, } mc::cat_rvalue(..) | - mc::cat_local(..) | - mc::cat_arg(..) => { + mc::cat_local(..) => { None } diff --git a/src/librustc/middle/borrowck/gather_loans/lifetime.rs b/src/librustc/middle/borrowck/gather_loans/lifetime.rs index e13717e5abd..c0712332525 100644 --- a/src/librustc/middle/borrowck/gather_loans/lifetime.rs +++ b/src/librustc/middle/borrowck/gather_loans/lifetime.rs @@ -69,7 +69,6 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> { mc::cat_rvalue(..) | mc::cat_copied_upvar(..) | // L-Local mc::cat_local(..) | // L-Local - mc::cat_arg(..) | // L-Local mc::cat_upvar(..) | mc::cat_deref(_, _, mc::BorrowedPtr(..)) | // L-Deref-Borrowed mc::cat_deref(_, _, mc::Implicit(..)) | @@ -174,8 +173,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> { mc::cat_static_item => { ty::ReStatic } - mc::cat_local(local_id) | - mc::cat_arg(local_id) => { + mc::cat_local(local_id) => { ty::ReScope(self.bccx.tcx.region_maps.var_scope(local_id)) } mc::cat_deref(_, _, mc::UnsafePtr(..)) => { diff --git a/src/librustc/middle/borrowck/gather_loans/restrictions.rs b/src/librustc/middle/borrowck/gather_loans/restrictions.rs index 90e17e4d79c..e0018919b98 100644 --- a/src/librustc/middle/borrowck/gather_loans/restrictions.rs +++ b/src/librustc/middle/borrowck/gather_loans/restrictions.rs @@ -66,8 +66,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> { Safe } - mc::cat_local(local_id) | - mc::cat_arg(local_id) => { + mc::cat_local(local_id) => { // R-Variable, locally declared let lp = Rc::new(LpVar(local_id)); SafeIf(lp.clone(), vec![lp]) diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index 0d584a7664f..e1e37b3d371 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -321,8 +321,7 @@ pub fn opt_loan_path(cmt: &mc::cmt) -> Option<Rc<LoanPath>> { None } - mc::cat_local(id) | - mc::cat_arg(id) => { + mc::cat_local(id) => { Some(Rc::new(LpVar(id))) } @@ -425,12 +424,12 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { adj: &ty::AutoAdjustment) -> mc::cmt { let r = match *adj { - ty::AutoDerefRef( + ty::AdjustDerefRef( ty::AutoDerefRef { autoderefs: autoderefs, ..}) => { self.mc().cat_expr_autoderefd(expr, autoderefs) } - ty::AutoAddEnv(..) => { + ty::AdjustAddEnv(..) => { // no autoderefs self.mc().cat_expr_unadjusted(expr) } diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs index f1c288ae7a9..b268c2a7a51 100644 --- a/src/librustc/middle/cfg/construct.rs +++ b/src/librustc/middle/cfg/construct.rs @@ -424,6 +424,13 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { self.call(expr, pred, &**l, Some(&**r).into_iter()) } + ast::ExprSlice(ref base, ref start, ref end, _) => { + self.call(expr, + pred, + &**base, + start.iter().chain(end.iter()).map(|x| &**x)) + } + ast::ExprUnary(_, ref e) if self.is_method_call(expr) => { self.call(expr, pred, &**e, None::<ast::Expr>.iter()) } diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index b75d61100ec..345b8c88372 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -101,12 +101,12 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { } } typeck::MethodStaticUnboxedClosure(_) => {} - typeck::MethodParam(typeck::MethodParam { + typeck::MethodTypeParam(typeck::MethodParam { trait_ref: ref trait_ref, method_num: index, .. }) | - typeck::MethodObject(typeck::MethodObject { + typeck::MethodTraitObject(typeck::MethodObject { trait_ref: ref trait_ref, method_num: index, .. diff --git a/src/librustc/middle/def.rs b/src/librustc/middle/def.rs index ae45d827def..1863a19b56d 100644 --- a/src/librustc/middle/def.rs +++ b/src/librustc/middle/def.rs @@ -12,8 +12,6 @@ use middle::subst::ParamSpace; use syntax::ast; use syntax::ast_util::local_def; -use std::gc::Gc; - #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum Def { DefFn(ast::DefId, ast::FnStyle), @@ -22,20 +20,18 @@ pub enum Def { DefMod(ast::DefId), DefForeignMod(ast::DefId), DefStatic(ast::DefId, bool /* is_mutbl */), - DefArg(ast::NodeId, ast::BindingMode), - DefLocal(ast::NodeId, ast::BindingMode), + DefLocal(ast::NodeId), DefVariant(ast::DefId /* enum */, ast::DefId /* variant */, bool /* is_structure */), DefTy(ast::DefId, bool /* is_enum */), DefAssociatedTy(ast::DefId), DefTrait(ast::DefId), DefPrimTy(ast::PrimTy), DefTyParam(ParamSpace, ast::DefId, uint), - DefBinding(ast::NodeId, ast::BindingMode), DefUse(ast::DefId), - DefUpvar(ast::NodeId, // id of closed over var - Gc<Def>, // closed over def + DefUpvar(ast::NodeId, // id of closed over local ast::NodeId, // expr node that creates the closure - ast::NodeId), // id for the block/body of the closure expr + ast::NodeId), // block node for the closest enclosing proc + // or unboxed closure, DUMMY_NODE_ID otherwise /// Note that if it's a tuple struct's definition, the node id of the ast::DefId /// may either refer to the item definition's id or the StructDef.ctor_id. @@ -68,11 +64,9 @@ impl Def { DefMethod(id, _) => { id } - DefArg(id, _) | - DefLocal(id, _) | + DefLocal(id) | DefSelfTy(id) | - DefUpvar(id, _, _, _) | - DefBinding(id, _) | + DefUpvar(id, _, _) | DefRegion(id) | DefTyParamBinder(id) | DefLabel(id) => { diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index c8c5284022d..0b4f661a16a 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -16,10 +16,11 @@ use middle::mem_categorization as mc; use middle::def; -use middle::freevars; +use middle::mem_categorization::Typer; use middle::pat_util; use middle::ty; -use middle::typeck::{MethodCall, MethodObject, MethodOrigin, MethodParam}; +use middle::typeck::{MethodCall, MethodObject, MethodTraitObject}; +use middle::typeck::{MethodOrigin, MethodParam, MethodTypeParam}; use middle::typeck::{MethodStatic, MethodStaticUnboxedClosure}; use middle::typeck; use util::ppaux::Repr; @@ -177,8 +178,8 @@ impl OverloadedCallType { MethodStaticUnboxedClosure(def_id) => { OverloadedCallType::from_unboxed_closure(tcx, def_id) } - MethodParam(MethodParam { trait_ref: ref trait_ref, .. }) | - MethodObject(MethodObject { trait_ref: ref trait_ref, .. }) => { + MethodTypeParam(MethodParam { trait_ref: ref trait_ref, .. }) | + MethodTraitObject(MethodObject { trait_ref: ref trait_ref, .. }) => { OverloadedCallType::from_trait_id(tcx, trait_ref.def_id) } } @@ -316,7 +317,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> { ast::ExprPath(..) => { } ast::ExprUnary(ast::UnDeref, ref base) => { // *base - if !self.walk_overloaded_operator(expr, &**base, None) { + if !self.walk_overloaded_operator(expr, &**base, Vec::new()) { self.select_from_expr(&**base); } } @@ -330,12 +331,23 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> { } ast::ExprIndex(ref lhs, ref rhs) => { // lhs[rhs] - if !self.walk_overloaded_operator(expr, &**lhs, Some(&**rhs)) { + if !self.walk_overloaded_operator(expr, &**lhs, vec![&**rhs]) { self.select_from_expr(&**lhs); self.consume_expr(&**rhs); } } + ast::ExprSlice(ref base, ref start, ref end, _) => { // base[start..end] + let args = match (start, end) { + (&Some(ref e1), &Some(ref e2)) => vec![&**e1, &**e2], + (&Some(ref e), &None) => vec![&**e], + (&None, &Some(ref e)) => vec![&**e], + (&None, &None) => Vec::new() + }; + let overloaded = self.walk_overloaded_operator(expr, &**base, args); + assert!(overloaded); + } + ast::ExprCall(ref callee, ref args) => { // callee(args) self.walk_callee(expr, &**callee); self.consume_exprs(args); @@ -430,13 +442,13 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> { } ast::ExprUnary(_, ref lhs) => { - if !self.walk_overloaded_operator(expr, &**lhs, None) { + if !self.walk_overloaded_operator(expr, &**lhs, Vec::new()) { self.consume_expr(&**lhs); } } ast::ExprBinary(_, ref lhs, ref rhs) => { - if !self.walk_overloaded_operator(expr, &**lhs, Some(&**rhs)) { + if !self.walk_overloaded_operator(expr, &**lhs, vec![&**rhs]) { self.consume_expr(&**lhs); self.consume_expr(&**rhs); } @@ -673,7 +685,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> { None => { } Some(adjustment) => { match *adjustment { - ty::AutoAddEnv(..) => { + ty::AdjustAddEnv(..) => { // Creating a closure consumes the input and stores it // into the resulting rvalue. debug!("walk_adjustment(AutoAddEnv)"); @@ -681,7 +693,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> { return_if_err!(self.mc.cat_expr_unadjusted(expr)); self.delegate_consume(expr.id, expr.span, cmt_unadjusted); } - ty::AutoDerefRef(ty::AutoDerefRef { + ty::AdjustDerefRef(ty::AutoDerefRef { autoref: ref opt_autoref, autoderefs: n }) => { @@ -774,7 +786,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> { fn walk_overloaded_operator(&mut self, expr: &ast::Expr, receiver: &ast::Expr, - rhs: Option<&ast::Expr>) + rhs: Vec<&ast::Expr>) -> bool { if !self.typer.is_method_call(expr.id) { @@ -911,12 +923,12 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> { debug!("walk_captures({})", closure_expr.repr(self.tcx())); let tcx = self.typer.tcx(); - freevars::with_freevars(tcx, closure_expr.id, |freevars| { - match freevars::get_capture_mode(self.tcx(), closure_expr.id) { - freevars::CaptureByRef => { + ty::with_freevars(tcx, closure_expr.id, |freevars| { + match self.tcx().capture_mode(closure_expr.id) { + ast::CaptureByRef => { self.walk_by_ref_captures(closure_expr, freevars); } - freevars::CaptureByValue => { + ast::CaptureByValue => { self.walk_by_value_captures(closure_expr, freevars); } } @@ -925,7 +937,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> { fn walk_by_ref_captures(&mut self, closure_expr: &ast::Expr, - freevars: &[freevars::freevar_entry]) { + freevars: &[ty::Freevar]) { for freevar in freevars.iter() { let id_var = freevar.def.def_id().node; let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.id, @@ -950,7 +962,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> { fn walk_by_value_captures(&mut self, closure_expr: &ast::Expr, - freevars: &[freevars::freevar_entry]) { + freevars: &[ty::Freevar]) { for freevar in freevars.iter() { let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.id, closure_expr.span, diff --git a/src/librustc/middle/freevars.rs b/src/librustc/middle/freevars.rs deleted file mode 100644 index 5b7c72208ea..00000000000 --- a/src/librustc/middle/freevars.rs +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright 2012-2014 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 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// A pass that annotates for each loops and functions with the free -// variables that they contain. - -#![allow(non_camel_case_types)] - -use middle::def; -use middle::mem_categorization::Typer; -use middle::resolve; -use middle::ty; -use util::nodemap::{NodeMap, NodeSet}; - -use syntax::ast; -use syntax::codemap::Span; -use syntax::visit::Visitor; -use syntax::visit; - -#[deriving(Clone, Decodable, Encodable, Show)] -pub enum CaptureMode { - /// Copy/move the value from this llvm ValueRef into the environment. - CaptureByValue, - - /// Access by reference (used for stack closures). - CaptureByRef -} - -// A vector of defs representing the free variables referred to in a function. -// (The def_upvar will already have been stripped). -#[deriving(Encodable, Decodable)] -pub struct freevar_entry { - pub def: def::Def, //< The variable being accessed free. - pub span: Span //< First span where it is accessed (there can be multiple) -} - -pub type freevar_map = NodeMap<Vec<freevar_entry>>; - -pub type CaptureModeMap = NodeMap<CaptureMode>; - -struct CollectFreevarsVisitor<'a> { - seen: NodeSet, - refs: Vec<freevar_entry>, - def_map: &'a resolve::DefMap, - capture_mode_map: &'a mut CaptureModeMap, - depth: uint -} - -impl<'a, 'v> Visitor<'v> for CollectFreevarsVisitor<'a> { - fn visit_item(&mut self, _: &ast::Item) { - // ignore_item - } - - fn visit_expr(&mut self, expr: &ast::Expr) { - match expr.node { - ast::ExprProc(..) => { - self.capture_mode_map.insert(expr.id, CaptureByValue); - self.depth += 1; - visit::walk_expr(self, expr); - self.depth -= 1; - } - ast::ExprFnBlock(_, _, _) => { - // NOTE(stage0): After snapshot, change to: - // - //let capture_mode = match capture_clause { - // ast::CaptureByValue => CaptureByValue, - // ast::CaptureByRef => CaptureByRef, - //}; - let capture_mode = CaptureByRef; - self.capture_mode_map.insert(expr.id, capture_mode); - self.depth += 1; - visit::walk_expr(self, expr); - self.depth -= 1; - } - ast::ExprUnboxedFn(capture_clause, _, _, _) => { - let capture_mode = match capture_clause { - ast::CaptureByValue => CaptureByValue, - ast::CaptureByRef => CaptureByRef, - }; - self.capture_mode_map.insert(expr.id, capture_mode); - self.depth += 1; - visit::walk_expr(self, expr); - self.depth -= 1; - } - ast::ExprPath(..) => { - let mut def = *self.def_map.borrow().find(&expr.id) - .expect("path not found"); - let mut i = 0; - while i < self.depth { - match def { - def::DefUpvar(_, inner, _, _) => { def = *inner; } - _ => break - } - i += 1; - } - if i == self.depth { // Made it to end of loop - let dnum = def.def_id().node; - if !self.seen.contains(&dnum) { - self.refs.push(freevar_entry { - def: def, - span: expr.span, - }); - self.seen.insert(dnum); - } - } - } - _ => visit::walk_expr(self, expr) - } - } -} - -// Searches through part of the AST for all references to locals or -// upvars in this frame and returns the list of definition IDs thus found. -// Since we want to be able to collect upvars in some arbitrary piece -// of the AST, we take a walker function that we invoke with a visitor -// in order to start the search. -fn collect_freevars(def_map: &resolve::DefMap, - blk: &ast::Block, - capture_mode_map: &mut CaptureModeMap) - -> Vec<freevar_entry> { - let mut v = CollectFreevarsVisitor { - seen: NodeSet::new(), - refs: Vec::new(), - def_map: def_map, - capture_mode_map: &mut *capture_mode_map, - depth: 1 - }; - - v.visit_block(blk); - - v.refs -} - -struct AnnotateFreevarsVisitor<'a> { - def_map: &'a resolve::DefMap, - freevars: freevar_map, - capture_mode_map: CaptureModeMap, -} - -impl<'a, 'v> Visitor<'v> for AnnotateFreevarsVisitor<'a> { - fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl, - blk: &'v ast::Block, s: Span, nid: ast::NodeId) { - let vars = collect_freevars(self.def_map, - blk, - &mut self.capture_mode_map); - self.freevars.insert(nid, vars); - visit::walk_fn(self, fk, fd, blk, s); - } -} - -// Build a map from every function and for-each body to a set of the -// freevars contained in it. The implementation is not particularly -// efficient as it fully recomputes the free variables at every -// node of interest rather than building up the free variables in -// one pass. This could be improved upon if it turns out to matter. -pub fn annotate_freevars(def_map: &resolve::DefMap, krate: &ast::Crate) - -> (freevar_map, CaptureModeMap) { - let mut visitor = AnnotateFreevarsVisitor { - def_map: def_map, - freevars: NodeMap::new(), - capture_mode_map: NodeMap::new(), - }; - visit::walk_crate(&mut visitor, krate); - - let AnnotateFreevarsVisitor { - freevars, - capture_mode_map, - .. - } = visitor; - (freevars, capture_mode_map) -} - -pub fn with_freevars<T>(tcx: &ty::ctxt, fid: ast::NodeId, f: |&[freevar_entry]| -> T) -> T { - match tcx.freevars.borrow().find(&fid) { - None => fail!("with_freevars: {} has no freevars", fid), - Some(d) => f(d.as_slice()) - } -} - -pub fn get_capture_mode<'tcx, T:Typer<'tcx>>(tcx: &T, closure_expr_id: ast::NodeId) - -> CaptureMode { - tcx.capture_mode(closure_expr_id) -} diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index aeb0c155a3f..4a5b2e01463 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use middle::freevars::freevar_entry; -use middle::freevars; use middle::mem_categorization::Typer; use middle::subst; use middle::ty; @@ -146,10 +144,10 @@ fn check_item(cx: &mut Context, item: &Item) { fn with_appropriate_checker(cx: &Context, id: NodeId, fn_span: Span, - b: |checker: |&Context, &freevar_entry||) { + b: |checker: |&Context, &ty::Freevar||) { fn check_for_uniq(cx: &Context, fn_span: Span, - fv: &freevar_entry, + fv: &ty::Freevar, bounds: ty::BuiltinBounds) { // all captured data must be owned, regardless of whether it is // moved in or copied in. @@ -162,7 +160,7 @@ fn with_appropriate_checker(cx: &Context, fn check_for_block(cx: &Context, fn_span: Span, fn_id: NodeId, - fv: &freevar_entry, + fv: &ty::Freevar, bounds: ty::BuiltinBounds) { let id = fv.def.def_id().node; let var_t = ty::node_id_to_type(cx.tcx, id); @@ -177,7 +175,7 @@ fn with_appropriate_checker(cx: &Context, bounds, Some(var_t)); } - fn check_for_bare(cx: &Context, fv: &freevar_entry) { + fn check_for_bare(cx: &Context, fv: &ty::Freevar) { span_err!(cx.tcx.sess, fv.span, E0143, "can't capture dynamic environment in a fn item; \ use the || {} closure form instead", "{ ... }"); @@ -227,7 +225,7 @@ fn check_fn( // <Check kinds on free variables: with_appropriate_checker(cx, fn_id, sp, |chk| { - freevars::with_freevars(cx.tcx, fn_id, |freevars| { + ty::with_freevars(cx.tcx, fn_id, |freevars| { for fv in freevars.iter() { chk(cx, fv); } @@ -274,6 +272,7 @@ pub fn check_expr(cx: &mut Context, e: &Expr) { visit::walk_expr(cx, e); } + fn check_ty(cx: &mut Context, aty: &Ty) { match aty.node { TyPath(_, _, id) => { diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 1875c53f074..daba3b701c0 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -247,6 +247,8 @@ lets_do_this! { ShrTraitLangItem, "shr", shr_trait; IndexTraitLangItem, "index", index_trait; IndexMutTraitLangItem, "index_mut", index_mut_trait; + SliceTraitLangItem, "slice", slice_trait; + SliceMutTraitLangItem, "slice_mut", slice_mut_trait; UnsafeTypeLangItem, "unsafe", unsafe_type; diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index fee6c77a799..b6893a6a3b4 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -103,7 +103,6 @@ */ use middle::def::*; -use middle::freevars; use middle::mem_categorization::Typer; use middle::pat_util; use middle::ty; @@ -116,6 +115,7 @@ use std::mem::transmute; use std::rc::Rc; use std::str; use std::uint; +use syntax::ast; use syntax::ast::*; use syntax::codemap::{BytePos, original_sp, Span}; use syntax::parse::token::special_idents; @@ -183,7 +183,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for IrMaps<'a, 'tcx> { b: &'v Block, s: Span, n: NodeId) { visit_fn(self, fk, fd, b, s, n); } - fn visit_local(&mut self, l: &Local) { visit_local(self, l); } + fn visit_local(&mut self, l: &ast::Local) { visit_local(self, l); } fn visit_expr(&mut self, ex: &Expr) { visit_expr(self, ex); } fn visit_arm(&mut self, a: &Arm) { visit_arm(self, a); } } @@ -346,7 +346,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Liveness<'a, 'tcx> { fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Block, s: Span, n: NodeId) { check_fn(self, fk, fd, b, s, n); } - fn visit_local(&mut self, l: &Local) { + fn visit_local(&mut self, l: &ast::Local) { check_local(self, l); } fn visit_expr(&mut self, ex: &Expr) { @@ -408,7 +408,7 @@ fn visit_fn(ir: &mut IrMaps, lsets.warn_about_unused_args(decl, entry_ln); } -fn visit_local(ir: &mut IrMaps, local: &Local) { +fn visit_local(ir: &mut IrMaps, local: &ast::Local) { pat_util::pat_bindings(&ir.tcx.def_map, &*local.pat, |_, p_id, sp, path1| { debug!("adding local variable {}", p_id); let name = path1.node; @@ -437,24 +437,15 @@ fn visit_arm(ir: &mut IrMaps, arm: &Arm) { visit::walk_arm(ir, arm); } -fn moved_variable_node_id_from_def(def: Def) -> Option<NodeId> { - match def { - DefBinding(nid, _) | - DefArg(nid, _) | - DefLocal(nid, _) => Some(nid), - - _ => None - } -} - fn visit_expr(ir: &mut IrMaps, expr: &Expr) { match expr.node { // live nodes required for uses or definitions of variables: ExprPath(_) => { let def = ir.tcx.def_map.borrow().get_copy(&expr.id); debug!("expr {}: path that leads to {:?}", expr.id, def); - if moved_variable_node_id_from_def(def).is_some() { - ir.add_live_node_for_node(expr.id, ExprNode(expr.span)); + match def { + DefLocal(..) => ir.add_live_node_for_node(expr.id, ExprNode(expr.span)), + _ => {} } visit::walk_expr(ir, expr); } @@ -468,15 +459,15 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) { // in better error messages than just pointing at the closure // construction site. let mut call_caps = Vec::new(); - freevars::with_freevars(ir.tcx, expr.id, |freevars| { + ty::with_freevars(ir.tcx, expr.id, |freevars| { for fv in freevars.iter() { - match moved_variable_node_id_from_def(fv.def) { - Some(rv) => { + match fv.def { + DefLocal(rv) => { let fv_ln = ir.add_live_node(FreeVarNode(fv.span)); call_caps.push(CaptureInfo {ln: fv_ln, var_nid: rv}); } - None => {} + _ => {} } } }); @@ -511,7 +502,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) { // otherwise, live nodes are not required: ExprIndex(..) | ExprField(..) | ExprTupField(..) | ExprVec(..) | - ExprCall(..) | ExprMethodCall(..) | ExprTup(..) | + ExprCall(..) | ExprMethodCall(..) | ExprTup(..) | ExprSlice(..) | ExprBinary(..) | ExprAddrOf(..) | ExprCast(..) | ExprUnary(..) | ExprBreak(_) | ExprAgain(_) | ExprLit(_) | ExprRet(..) | ExprBlock(..) | @@ -913,7 +904,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } } - fn propagate_through_local(&mut self, local: &Local, succ: LiveNode) + fn propagate_through_local(&mut self, local: &ast::Local, succ: LiveNode) -> LiveNode { // Note: we mark the variable as defined regardless of whether // there is an initializer. Initially I had thought to only mark @@ -1184,6 +1175,12 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { self.propagate_through_expr(&**l, r_succ) } + ExprSlice(ref e1, ref e2, ref e3, _) => { + let succ = e3.as_ref().map_or(succ, |e| self.propagate_through_expr(&**e, succ)); + let succ = e2.as_ref().map_or(succ, |e| self.propagate_through_expr(&**e, succ)); + self.propagate_through_expr(&**e1, succ) + } + ExprAddrOf(_, ref e) | ExprCast(ref e, _) | ExprUnary(_, ref e) | @@ -1296,9 +1293,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { fn access_path(&mut self, expr: &Expr, succ: LiveNode, acc: uint) -> LiveNode { - let def = self.ir.tcx.def_map.borrow().get_copy(&expr.id); - match moved_variable_node_id_from_def(def) { - Some(nid) => { + match self.ir.tcx.def_map.borrow().get_copy(&expr.id) { + DefLocal(nid) => { let ln = self.live_node(expr.id, expr.span); if acc != 0u { self.init_from_succ(ln, succ); @@ -1307,7 +1303,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } ln } - None => succ + _ => succ } } @@ -1403,7 +1399,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { // _______________________________________________________________________ // Checking for error conditions -fn check_local(this: &mut Liveness, local: &Local) { +fn check_local(this: &mut Liveness, local: &ast::Local) { match local.init { Some(_) => { this.warn_about_unused_or_dead_vars_in_pat(&*local.pat); @@ -1468,7 +1464,7 @@ fn check_expr(this: &mut Liveness, expr: &Expr) { ExprWhile(..) | ExprLoop(..) | ExprIndex(..) | ExprField(..) | ExprTupField(..) | ExprVec(..) | ExprTup(..) | ExprBinary(..) | ExprCast(..) | ExprUnary(..) | ExprRet(..) | ExprBreak(..) | - ExprAgain(..) | ExprLit(_) | ExprBlock(..) | + ExprAgain(..) | ExprLit(_) | ExprBlock(..) | ExprSlice(..) | ExprMac(..) | ExprAddrOf(..) | ExprStruct(..) | ExprRepeat(..) | ExprParen(..) | ExprFnBlock(..) | ExprProc(..) | ExprUnboxedFn(..) | ExprPath(..) | ExprBox(..) => { @@ -1520,11 +1516,12 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { sp, "not all control paths return a value"); if ends_with_stmt { let last_stmt = body.stmts.last().unwrap(); - let original_span = original_sp(last_stmt.span, sp); + let original_span = original_sp(self.ir.tcx.sess.codemap(), + last_stmt.span, sp); let span_semicolon = Span { lo: original_span.hi - BytePos(1), hi: original_span.hi, - expn_info: original_span.expn_info + expn_id: original_span.expn_id }; self.ir.tcx.sess.span_note( span_semicolon, "consider removing this semicolon:"); @@ -1537,7 +1534,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { match expr.node { ExprPath(_) => { match self.ir.tcx.def_map.borrow().get_copy(&expr.id) { - DefLocal(nid, _) => { + DefLocal(nid) => { // Assignment to an immutable variable or argument: only legal // if there is no later assignment. If this local is actually // mutable, then check for a reassignment to flag the mutability @@ -1546,16 +1543,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { let var = self.variable(nid, expr.span); self.warn_about_dead_assign(expr.span, expr.id, ln, var); } - def => { - match moved_variable_node_id_from_def(def) { - Some(nid) => { - let ln = self.live_node(expr.id, expr.span); - let var = self.variable(nid, expr.span); - self.warn_about_dead_assign(expr.span, expr.id, ln, var); - } - None => {} - } - } + _ => {} } } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 17d941b5958..6350fa6a506 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -63,7 +63,6 @@ #![allow(non_camel_case_types)] use middle::def; -use middle::freevars; use middle::ty; use middle::typeck; use util::nodemap::{DefIdMap, NodeMap}; @@ -71,6 +70,7 @@ use util::ppaux::{ty_to_string, Repr}; use syntax::ast::{MutImmutable, MutMutable}; use syntax::ast; +use syntax::ast_map; use syntax::codemap::Span; use syntax::print::pprust; use syntax::parse::token; @@ -85,7 +85,6 @@ pub enum categorization { cat_copied_upvar(CopiedUpvar), // upvar copied into proc env cat_upvar(ty::UpvarId, ty::UpvarBorrow), // by ref upvar from stack closure cat_local(ast::NodeId), // local variable - cat_arg(ast::NodeId), // formal argument cat_deref(cmt, uint, PointerKind), // deref of a ptr cat_interior(cmt, InteriorKind), // something interior: field, tuple, etc cat_downcast(cmt), // selects a particular enum variant (*1) @@ -273,7 +272,7 @@ pub trait Typer<'tcx> { fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<ast::NodeId>; fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> ty::UpvarBorrow; fn capture_mode(&self, closure_expr_id: ast::NodeId) - -> freevars::CaptureMode; + -> ast::CaptureClause; fn unboxed_closures<'a>(&'a self) -> &'a RefCell<DefIdMap<ty::UnboxedClosure>>; } @@ -312,28 +311,19 @@ impl MutabilityCategory { } } - fn from_def(def: &def::Def) -> MutabilityCategory { - match *def { - def::DefFn(..) | def::DefStaticMethod(..) | def::DefSelfTy(..) | - def::DefMod(..) | def::DefForeignMod(..) | def::DefVariant(..) | - def::DefTy(..) | def::DefTrait(..) | def::DefPrimTy(..) | - def::DefTyParam(..) | def::DefUse(..) | def::DefStruct(..) | - def::DefTyParamBinder(..) | def::DefRegion(..) | def::DefLabel(..) | - def::DefMethod(..) | def::DefAssociatedTy(..) => { - fail!("no MutabilityCategory for def: {}", *def) - } - - def::DefStatic(_, false) => McImmutable, - def::DefStatic(_, true) => McDeclared, - - def::DefArg(_, binding_mode) | - def::DefBinding(_, binding_mode) | - def::DefLocal(_, binding_mode) => match binding_mode { - ast::BindByValue(ast::MutMutable) => McDeclared, - _ => McImmutable + fn from_local(tcx: &ty::ctxt, id: ast::NodeId) -> MutabilityCategory { + match tcx.map.get(id) { + ast_map::NodeLocal(p) | ast_map::NodeArg(p) => match p.node { + ast::PatIdent(bind_mode, _, _) => { + if bind_mode == ast::BindByValue(ast::MutMutable) { + McDeclared + } else { + McImmutable + } + } + _ => tcx.sess.span_bug(p.span, "expected identifier pattern") }, - - def::DefUpvar(_, def, _, _) => MutabilityCategory::from_def(&*def) + _ => tcx.sess.span_bug(tcx.map.span(id), "expected identifier pattern") } } @@ -414,14 +404,14 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { Some(adjustment) => { match *adjustment { - ty::AutoAddEnv(..) => { + ty::AdjustAddEnv(..) => { // Convert a bare fn to a closure by adding NULL env. // Result is an rvalue. let expr_ty = if_ok!(self.expr_ty_adjusted(expr)); Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty)) } - ty::AutoDerefRef( + ty::AdjustDerefRef( ty::AutoDerefRef { autoref: Some(_), ..}) => { // Equivalent to &*expr or something similar. @@ -430,7 +420,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty)) } - ty::AutoDerefRef( + ty::AdjustDerefRef( ty::AutoDerefRef { autoref: None, autoderefs: autoderefs}) => { // Equivalent to *expr or something similar. @@ -504,7 +494,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { ast::ExprAssign(..) | ast::ExprAssignOp(..) | ast::ExprFnBlock(..) | ast::ExprProc(..) | ast::ExprUnboxedFn(..) | ast::ExprRet(..) | - ast::ExprUnary(..) | + ast::ExprUnary(..) | ast::ExprSlice(..) | ast::ExprMethodCall(..) | ast::ExprCast(..) | ast::ExprVec(..) | ast::ExprTup(..) | ast::ExprIf(..) | ast::ExprBinary(..) | ast::ExprWhile(..) | @@ -546,30 +536,17 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { })) } - def::DefStatic(_, _) => { + def::DefStatic(_, mutbl) => { Ok(Rc::new(cmt_ { id:id, span:span, cat:cat_static_item, - mutbl: MutabilityCategory::from_def(&def), + mutbl: if mutbl { McDeclared } else { McImmutable}, ty:expr_ty })) } - def::DefArg(vid, _) => { - // Idea: make this could be rewritten to model by-ref - // stuff as `&const` and `&mut`? - - Ok(Rc::new(cmt_ { - id: id, - span: span, - cat: cat_arg(vid), - mutbl: MutabilityCategory::from_def(&def), - ty:expr_ty - })) - } - - def::DefUpvar(var_id, _, fn_node_id, _) => { + def::DefUpvar(var_id, fn_node_id, _) => { let ty = if_ok!(self.node_ty(fn_node_id)); match ty::get(ty).sty { ty::ty_closure(ref closure_ty) => { @@ -597,7 +574,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { onceness: closure_ty.onceness, capturing_proc: fn_node_id, }), - mutbl: MutabilityCategory::from_def(&def), + mutbl: MutabilityCategory::from_local(self.tcx(), var_id), ty:expr_ty })) } @@ -620,7 +597,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { onceness: onceness, capturing_proc: fn_node_id, }), - mutbl: MutabilityCategory::from_def(&def), + mutbl: MutabilityCategory::from_local(self.tcx(), var_id), ty: expr_ty })) } @@ -634,14 +611,12 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { } } - def::DefLocal(vid, _) | - def::DefBinding(vid, _) => { - // by-value/by-ref bindings are local variables + def::DefLocal(vid) => { Ok(Rc::new(cmt_ { id: id, span: span, cat: cat_local(vid), - mutbl: MutabilityCategory::from_def(&def), + mutbl: MutabilityCategory::from_local(self.tcx(), vid), ty: expr_ty })) } @@ -1196,11 +1171,13 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { cat_rvalue(..) => { "non-lvalue".to_string() } - cat_local(_) => { - "local variable".to_string() - } - cat_arg(..) => { - "argument".to_string() + cat_local(vid) => { + match self.tcx().map.find(vid) { + Some(ast_map::NodeArg(_)) => { + "argument".to_string() + } + _ => "local variable".to_string() + } } cat_deref(ref base, _, pk) => { match base.cat { @@ -1267,7 +1244,6 @@ impl cmt_ { cat_static_item | cat_copied_upvar(..) | cat_local(..) | - cat_arg(..) | cat_deref(_, _, UnsafePtr(..)) | cat_deref(_, _, GcPtr(..)) | cat_deref(_, _, BorrowedPtr(..)) | @@ -1311,7 +1287,6 @@ impl cmt_ { cat_rvalue(..) | cat_local(..) | cat_upvar(..) | - cat_arg(_) | cat_deref(_, _, UnsafePtr(..)) => { // yes, it's aliasable, but... None } @@ -1363,8 +1338,7 @@ impl Repr for categorization { cat_rvalue(..) | cat_copied_upvar(..) | cat_local(..) | - cat_upvar(..) | - cat_arg(..) => { + cat_upvar(..) => { format!("{:?}", *self) } cat_deref(ref cmt, derefs, ptr) => { diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 8aac96a5410..36778e7cfc3 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -19,8 +19,8 @@ use middle::def; use lint; use middle::resolve; use middle::ty; -use middle::typeck::{MethodCall, MethodMap, MethodOrigin, MethodParam}; -use middle::typeck::{MethodStatic, MethodStaticUnboxedClosure, MethodObject}; +use middle::typeck::{MethodCall, MethodMap, MethodOrigin, MethodParam, MethodTypeParam}; +use middle::typeck::{MethodStatic, MethodStaticUnboxedClosure, MethodObject, MethodTraitObject}; use util::nodemap::{NodeMap, NodeSet}; use syntax::ast; @@ -829,8 +829,8 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { MethodStaticUnboxedClosure(_) => {} // Trait methods are always all public. The only controlling factor // is whether the trait itself is accessible or not. - MethodParam(MethodParam { trait_ref: ref trait_ref, .. }) | - MethodObject(MethodObject { trait_ref: ref trait_ref, .. }) => { + MethodTypeParam(MethodParam { trait_ref: ref trait_ref, .. }) | + MethodTraitObject(MethodObject { trait_ref: ref trait_ref, .. }) => { self.report_error(self.ensure_public(span, trait_ref.def_id, None, "source trait")); } diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 6fa33f4b5aa..11ea84c75d3 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -19,7 +19,8 @@ use middle::lang_items::LanguageItems; use middle::pat_util::pat_bindings; use middle::subst::{ParamSpace, FnSpace, TypeSpace}; use middle::ty::{ExplicitSelfCategory, StaticExplicitSelfCategory}; -use util::nodemap::{NodeMap, DefIdSet, FnvHashMap}; +use middle::ty::{CaptureModeMap, Freevar, FreevarMap}; +use util::nodemap::{NodeMap, NodeSet, DefIdSet, FnvHashMap}; use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum}; use syntax::ast::{DeclItem, DefId, Expr, ExprAgain, ExprBreak, ExprField}; @@ -28,7 +29,7 @@ use syntax::ast::{ExprPath, ExprProc, ExprStruct, ExprUnboxedFn, FnDecl}; use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic, Generics}; use syntax::ast::{Ident, ImplItem, Item, ItemEnum, ItemFn, ItemForeignMod}; use syntax::ast::{ItemImpl, ItemMac, ItemMod, ItemStatic, ItemStruct}; -use syntax::ast::{ItemTrait, ItemTy, LOCAL_CRATE, Local, Method}; +use syntax::ast::{ItemTrait, ItemTy, LOCAL_CRATE, Local}; use syntax::ast::{MethodImplItem, Mod, Name, NamedField, NodeId}; use syntax::ast::{Pat, PatEnum, PatIdent, PatLit}; use syntax::ast::{PatRange, PatStruct, Path, PathListIdent, PathListMod}; @@ -59,7 +60,6 @@ use syntax::visit::Visitor; use std::collections::{HashMap, HashSet}; use std::cell::{Cell, RefCell}; -use std::gc::GC; use std::mem::replace; use std::rc::{Rc, Weak}; use std::uint; @@ -270,16 +270,16 @@ enum TypeParameters<'a> { RibKind) } -// The rib kind controls the translation of argument or local definitions -// (`def_arg` or `def_local`) to upvars (`def_upvar`). +// The rib kind controls the translation of local +// definitions (`DefLocal`) to upvars (`DefUpvar`). enum RibKind { // No translation needs to be applied. NormalRibKind, - // We passed through a function scope at the given node ID. Translate - // upvars as appropriate. - FunctionRibKind(NodeId /* func id */, NodeId /* body id */), + // We passed through a closure scope at the given node ID. + // Translate upvars as appropriate. + ClosureRibKind(NodeId /* func id */, NodeId /* body id if proc or unboxed */), // We passed through an impl or trait and are now in one of its // methods. Allow references to ty params that impl or trait @@ -891,6 +891,9 @@ struct Resolver<'a> { primitive_type_table: PrimitiveTypeTable, def_map: DefMap, + freevars: RefCell<FreevarMap>, + freevars_seen: RefCell<NodeMap<NodeSet>>, + capture_mode_map: RefCell<CaptureModeMap>, export_map2: ExportMap2, trait_map: TraitMap, external_exports: ExternalExports, @@ -996,6 +999,9 @@ impl<'a> Resolver<'a> { primitive_type_table: PrimitiveTypeTable::new(), def_map: RefCell::new(NodeMap::new()), + freevars: RefCell::new(NodeMap::new()), + freevars_seen: RefCell::new(NodeMap::new()), + capture_mode_map: RefCell::new(NodeMap::new()), export_map2: RefCell::new(NodeMap::new()), trait_map: NodeMap::new(), used_imports: HashSet::new(), @@ -1523,33 +1529,31 @@ impl<'a> Resolver<'a> { } // Constructs the reduced graph for one variant. Variants exist in the - // type and/or value namespaces. + // type and value namespaces. fn build_reduced_graph_for_variant(&mut self, variant: &Variant, item_id: DefId, parent: ReducedGraphParent, is_public: bool) { let ident = variant.node.name; - - match variant.node.kind { - TupleVariantKind(_) => { - let child = self.add_child(ident, parent, ForbidDuplicateValues, variant.span); - child.define_value(DefVariant(item_id, - local_def(variant.node.id), false), - variant.span, is_public); - } + let is_exported = match variant.node.kind { + TupleVariantKind(_) => false, StructVariantKind(_) => { - let child = self.add_child(ident, parent, - ForbidDuplicateTypesAndValues, - variant.span); - child.define_type(DefVariant(item_id, - local_def(variant.node.id), true), - variant.span, is_public); - // Not adding fields for variants as they are not accessed with a self receiver self.structs.insert(local_def(variant.node.id), Vec::new()); + true } - } + }; + + let child = self.add_child(ident, parent, + ForbidDuplicateTypesAndValues, + variant.span); + child.define_value(DefVariant(item_id, + local_def(variant.node.id), is_exported), + variant.span, is_public); + child.define_type(DefVariant(item_id, + local_def(variant.node.id), is_exported), + variant.span, is_public); } /// Constructs the reduced graph for one 'view item'. View items consist @@ -1895,8 +1899,7 @@ impl<'a> Resolver<'a> { ignoring {:?}", def); // Ignored; handled elsewhere. } - DefArg(..) | DefLocal(..) | DefPrimTy(..) | - DefTyParam(..) | DefBinding(..) | + DefLocal(..) | DefPrimTy(..) | DefTyParam(..) | DefUse(..) | DefUpvar(..) | DefRegion(..) | DefTyParamBinder(..) | DefLabel(..) | DefSelfTy(..) => { fail!("didn't expect `{:?}`", def); @@ -3828,130 +3831,143 @@ impl<'a> Resolver<'a> { self.current_module = orig_module; } - /// Wraps the given definition in the appropriate number of `def_upvar` + /// Wraps the given definition in the appropriate number of `DefUpvar` /// wrappers. fn upvarify(&self, ribs: &[Rib], - rib_index: uint, def_like: DefLike, span: Span) -> Option<DefLike> { - let mut def; - let is_ty_param; - match def_like { - DlDef(d @ DefLocal(..)) | DlDef(d @ DefUpvar(..)) | - DlDef(d @ DefArg(..)) | DlDef(d @ DefBinding(..)) => { - def = d; - is_ty_param = false; - } - DlDef(d @ DefTyParam(..)) | - DlDef(d @ DefSelfTy(..)) => { - def = d; - is_ty_param = true; - } - _ => { - return Some(def_like); - } - } + DlDef(d @ DefUpvar(..)) => { + self.session.span_bug(span, + format!("unexpected {} in bindings", d).as_slice()) + } + DlDef(d @ DefLocal(_)) => { + let node_id = d.def_id().node; + let mut def = d; + let mut last_proc_body_id = ast::DUMMY_NODE_ID; + for rib in ribs.iter() { + match rib.kind { + NormalRibKind => { + // Nothing to do. Continue. + } + ClosureRibKind(function_id, maybe_proc_body) => { + let prev_def = def; + if maybe_proc_body != ast::DUMMY_NODE_ID { + last_proc_body_id = maybe_proc_body; + } + def = DefUpvar(node_id, function_id, last_proc_body_id); - let mut rib_index = rib_index + 1; - while rib_index < ribs.len() { - match ribs[rib_index].kind { - NormalRibKind => { - // Nothing to do. Continue. - } - FunctionRibKind(function_id, body_id) => { - if !is_ty_param { - def = DefUpvar(def.def_id().node, - box(GC) def, - function_id, - body_id); - } - } - MethodRibKind(item_id, _) => { - // If the def is a ty param, and came from the parent - // item, it's ok - match def { - DefTyParam(_, did, _) if { - self.def_map.borrow().find(&did.node).map(|x| *x) - == Some(DefTyParamBinder(item_id)) - } => { - // ok - } + let mut seen = self.freevars_seen.borrow_mut(); + let seen = seen.find_or_insert(function_id, NodeSet::new()); + if seen.contains(&node_id) { + continue; + } + self.freevars.borrow_mut().find_or_insert(function_id, vec![]) + .push(Freevar { def: prev_def, span: span }); + seen.insert(node_id); + } + MethodRibKind(item_id, _) => { + // If the def is a ty param, and came from the parent + // item, it's ok + match def { + DefTyParam(_, did, _) if { + self.def_map.borrow().find_copy(&did.node) + == Some(DefTyParamBinder(item_id)) + } => {} // ok + DefSelfTy(did) if did == item_id => {} // ok + _ => { + // This was an attempt to access an upvar inside a + // named function item. This is not allowed, so we + // report an error. - DefSelfTy(did) if { - did == item_id - } => { - // ok - } + self.resolve_error( + span, + "can't capture dynamic environment in a fn item; \ + use the || { ... } closure form instead"); - _ => { - if !is_ty_param { - // This was an attempt to access an upvar inside a - // named function item. This is not allowed, so we - // report an error. + return None; + } + } + } + ItemRibKind => { + // This was an attempt to access an upvar inside a + // named function item. This is not allowed, so we + // report an error. - self.resolve_error( - span, - "can't capture dynamic environment in a fn item; \ - use the || { ... } closure form instead"); - } else { - // This was an attempt to use a type parameter outside - // its scope. + self.resolve_error( + span, + "can't capture dynamic environment in a fn item; \ + use the || { ... } closure form instead"); - self.resolve_error(span, - "can't use type parameters from \ - outer function; try using a local \ - type parameter instead"); - } + return None; + } + ConstantItemRibKind => { + // Still doesn't deal with upvars + self.resolve_error(span, + "attempt to use a non-constant \ + value in a constant"); - return None; + } } - } } - ItemRibKind => { - if !is_ty_param { - // This was an attempt to access an upvar inside a - // named function item. This is not allowed, so we - // report an error. + Some(DlDef(def)) + } + DlDef(def @ DefTyParam(..)) | + DlDef(def @ DefSelfTy(..)) => { + for rib in ribs.iter() { + match rib.kind { + NormalRibKind | ClosureRibKind(..) => { + // Nothing to do. Continue. + } + MethodRibKind(item_id, _) => { + // If the def is a ty param, and came from the parent + // item, it's ok + match def { + DefTyParam(_, did, _) if { + self.def_map.borrow().find_copy(&did.node) + == Some(DefTyParamBinder(item_id)) + } => {} // ok + DefSelfTy(did) if did == item_id => {} // ok - self.resolve_error( - span, - "can't capture dynamic environment in a fn item; \ - use the || { ... } closure form instead"); - } else { - // This was an attempt to use a type parameter outside - // its scope. + _ => { + // This was an attempt to use a type parameter outside + // its scope. - self.resolve_error(span, - "can't use type parameters from \ - outer function; try using a local \ - type parameter instead"); - } + self.resolve_error(span, + "can't use type parameters from \ + outer function; try using a local \ + type parameter instead"); - return None; - } - ConstantItemRibKind => { - if is_ty_param { - // see #9186 - self.resolve_error(span, - "cannot use an outer type \ - parameter in this context"); - } else { - // Still doesn't deal with upvars - self.resolve_error(span, - "attempt to use a non-constant \ - value in a constant"); - } + return None; + } + } + } + ItemRibKind => { + // This was an attempt to use a type parameter outside + // its scope. + + self.resolve_error(span, + "can't use type parameters from \ + outer function; try using a local \ + type parameter instead"); + return None; + } + ConstantItemRibKind => { + // see #9186 + self.resolve_error(span, + "cannot use an outer type \ + parameter in this context"); + + } + } } + Some(DlDef(def)) } - - rib_index += 1; + _ => Some(def_like) } - - return Some(DlDef(def)); } fn search_ribs(&self, @@ -3959,16 +3975,12 @@ impl<'a> Resolver<'a> { name: Name, span: Span) -> Option<DefLike> { - // FIXME #4950: This should not use a while loop. // FIXME #4950: Try caching? - let mut i = ribs.len(); - while i != 0 { - i -= 1; - let binding_opt = ribs[i].bindings.borrow().find_copy(&name); - match binding_opt { + for (i, rib) in ribs.iter().enumerate().rev() { + match rib.bindings.borrow().find_copy(&name) { Some(def_like) => { - return self.upvarify(ribs, i, def_like, span); + return self.upvarify(ribs.slice_from(i + 1), def_like, span); } None => { // Continue. @@ -3976,7 +3988,7 @@ impl<'a> Resolver<'a> { } } - return None; + None } fn resolve_crate(&mut self, krate: &ast::Crate) { @@ -4328,6 +4340,34 @@ impl<'a> Resolver<'a> { self.resolve_trait_reference(id, tref, reference_type) } UnboxedFnTyParamBound(ref unboxed_function) => { + match self.resolve_path(unboxed_function.ref_id, + &unboxed_function.path, + TypeNS, + true) { + None => { + let path_str = self.path_idents_to_string( + &unboxed_function.path); + self.resolve_error(unboxed_function.path.span, + format!("unresolved trait `{}`", + path_str).as_slice()) + } + Some(def) => { + match def { + (DefTrait(_), _) => { + self.record_def(unboxed_function.ref_id, def); + } + _ => { + let msg = + format!("`{}` is not a trait", + self.path_idents_to_string( + &unboxed_function.path)); + self.resolve_error(unboxed_function.path.span, + msg.as_slice()); + } + } + } + } + for argument in unboxed_function.decl.inputs.iter() { self.resolve_type(&*argument.ty); } @@ -4471,7 +4511,7 @@ impl<'a> Resolver<'a> { // to be NormalRibKind? fn resolve_method(&mut self, rib_kind: RibKind, - method: &Method) { + method: &ast::Method) { let method_generics = method.pe_generics(); let type_parameters = HasTypeParameters(method_generics, FnSpace, @@ -4942,22 +4982,7 @@ impl<'a> Resolver<'a> { debug!("(resolving pattern) binding `{}`", token::get_name(renamed)); - let def = match mode { - RefutableMode => { - // For pattern arms, we must use - // `def_binding` definitions. - - DefBinding(pattern.id, binding_mode) - } - LocalIrrefutableMode => { - // But for locals, we use `def_local`. - DefLocal(pattern.id, binding_mode) - } - ArgumentIrrefutableMode => { - // And for function arguments, `def_arg`. - DefArg(pattern.id, binding_mode) - } - }; + let def = DefLocal(pattern.id); // Record the definition so that later passes // will be able to distinguish variants from @@ -5775,10 +5800,24 @@ impl<'a> Resolver<'a> { visit::walk_expr(self, expr); } - ExprFnBlock(_, ref fn_decl, ref block) | - ExprProc(ref fn_decl, ref block) | - ExprUnboxedFn(_, _, ref fn_decl, ref block) => { - self.resolve_function(FunctionRibKind(expr.id, block.id), + ExprFnBlock(_, ref fn_decl, ref block) => { + // NOTE(stage0): After snapshot, change to: + // + //self.capture_mode_map.borrow_mut().insert(expr.id, capture_clause); + self.capture_mode_map.borrow_mut().insert(expr.id, ast::CaptureByRef); + self.resolve_function(ClosureRibKind(expr.id, ast::DUMMY_NODE_ID), + Some(&**fn_decl), NoTypeParameters, + &**block); + } + ExprProc(ref fn_decl, ref block) => { + self.capture_mode_map.borrow_mut().insert(expr.id, ast::CaptureByValue); + self.resolve_function(ClosureRibKind(expr.id, block.id), + Some(&**fn_decl), NoTypeParameters, + &**block); + } + ExprUnboxedFn(capture_clause, _, ref fn_decl, ref block) => { + self.capture_mode_map.borrow_mut().insert(expr.id, capture_clause); + self.resolve_function(ClosureRibKind(expr.id, block.id), Some(&**fn_decl), NoTypeParameters, &**block); } @@ -6209,6 +6248,8 @@ impl<'a> Resolver<'a> { pub struct CrateMap { pub def_map: DefMap, + pub freevars: RefCell<FreevarMap>, + pub capture_mode_map: RefCell<CaptureModeMap>, pub exp_map2: ExportMap2, pub trait_map: TraitMap, pub external_exports: ExternalExports, @@ -6222,13 +6263,13 @@ pub fn resolve_crate(session: &Session, -> CrateMap { let mut resolver = Resolver::new(session, krate.span); resolver.resolve(krate); - let Resolver { def_map, export_map2, trait_map, last_private, - external_exports, .. } = resolver; CrateMap { - def_map: def_map, - exp_map2: export_map2, - trait_map: trait_map, - external_exports: external_exports, - last_private_map: last_private, + def_map: resolver.def_map, + freevars: resolver.freevars, + capture_mode_map: resolver.capture_mode_map, + exp_map2: resolver.export_map2, + trait_map: resolver.trait_map, + external_exports: resolver.external_exports, + last_private_map: resolver.last_private, } } diff --git a/src/librustc/middle/save/mod.rs b/src/librustc/middle/save/mod.rs index cab83f4cda2..0f4ed202ec2 100644 --- a/src/librustc/middle/save/mod.rs +++ b/src/librustc/middle/save/mod.rs @@ -71,7 +71,7 @@ fn escape(s: String) -> String { // If the expression is a macro expansion or other generated code, run screaming and don't index. fn generated_code(span: Span) -> bool { - span.expn_info.is_some() || span == DUMMY_SP + span.expn_id != NO_EXPANSION || span == DUMMY_SP } struct DxrVisitor<'l, 'tcx: 'l> { @@ -230,11 +230,9 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { def::DefAssociatedTy(..) | def::DefTrait(_) => Some(recorder::TypeRef), def::DefStatic(_, _) | - def::DefBinding(_, _) | - def::DefArg(_, _) | - def::DefLocal(_, _) | + def::DefLocal(_) | def::DefVariant(_, _, _) | - def::DefUpvar(_, _, _, _) => Some(recorder::VarRef), + def::DefUpvar(..) => Some(recorder::VarRef), def::DefFn(_, _) => Some(recorder::FnRef), @@ -739,20 +737,14 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { let def = def_map.get(&ex.id); let sub_span = self.span.span_for_last_ident(ex.span); match *def { - def::DefLocal(id, _) | - def::DefArg(id, _) | - def::DefUpvar(id, _, _, _) | - def::DefBinding(id, _) => self.fmt.ref_str(recorder::VarRef, - ex.span, - sub_span, - ast_util::local_def(id), - self.cur_scope), - def::DefStatic(def_id,_) | - def::DefVariant(_, def_id, _) => self.fmt.ref_str(recorder::VarRef, - ex.span, - sub_span, - def_id, - self.cur_scope), + def::DefUpvar(..) | + def::DefLocal(..) | + def::DefStatic(..) | + def::DefVariant(..) => self.fmt.ref_str(recorder::VarRef, + ex.span, + sub_span, + def.def_id(), + self.cur_scope), def::DefStruct(def_id) => self.fmt.ref_str(recorder::StructRef, ex.span, sub_span, @@ -813,8 +805,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { def::DefStaticMethod(_, _, _) => { self.write_sub_path_trait_truncated(path); }, - def::DefLocal(_, _) | - def::DefArg(_, _) | + def::DefLocal(_) | def::DefStatic(_,_) | def::DefStruct(_) | def::DefFn(_, _) => self.write_sub_paths_truncated(path), @@ -904,14 +895,14 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { }; (Some(def_id), decl_id) } - typeck::MethodParam(ref mp) => { + typeck::MethodTypeParam(ref mp) => { // method invoked on a type parameter let trait_item = ty::trait_item(&self.analysis.ty_cx, mp.trait_ref.def_id, mp.method_num); (None, Some(trait_item.def_id())) } - typeck::MethodObject(ref mo) => { + typeck::MethodTraitObject(ref mo) => { // method invoked on a trait instance let trait_item = ty::trait_item(&self.analysis.ty_cx, mo.trait_ref.def_id, @@ -1382,12 +1373,12 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { } let def = def_map.get(&id); match *def { - def::DefBinding(id, _) => self.fmt.variable_str(p.span, - sub_span, - id, - path_to_string(p).as_slice(), - value.as_slice(), - ""), + def::DefLocal(id) => self.fmt.variable_str(p.span, + sub_span, + id, + path_to_string(p).as_slice(), + value.as_slice(), + ""), def::DefVariant(_,id,_) => self.fmt.ref_str(ref_kind, p.span, sub_span, diff --git a/src/librustc/middle/save/span_utils.rs b/src/librustc/middle/save/span_utils.rs index 57006d5e72b..1086dc608a3 100644 --- a/src/librustc/middle/save/span_utils.rs +++ b/src/librustc/middle/save/span_utils.rs @@ -57,7 +57,7 @@ impl<'a> SpanUtils<'a> { Some(Span { lo: base + self.sess.codemap().lookup_byte_offset(sub.lo).pos, hi: base + self.sess.codemap().lookup_byte_offset(sub.hi).pos, - expn_info: None, + expn_id: NO_EXPANSION, }) } } diff --git a/src/librustc/middle/traits/fulfill.rs b/src/librustc/middle/traits/fulfill.rs index 22392f3f1c0..e7b1053b358 100644 --- a/src/librustc/middle/traits/fulfill.rs +++ b/src/librustc/middle/traits/fulfill.rs @@ -13,10 +13,10 @@ use middle::typeck::infer::{InferCtxt, skolemize}; use util::nodemap::DefIdMap; use util::ppaux::Repr; -use super::Ambiguity; +use super::CodeAmbiguity; use super::Obligation; use super::FulfillmentError; -use super::SelectionError; +use super::CodeSelectionError; use super::select::SelectionContext; use super::Unimplemented; @@ -78,7 +78,7 @@ impl FulfillmentContext { let errors: Vec<FulfillmentError> = self.trait_obligations .iter() - .map(|o| FulfillmentError::new((*o).clone(), Ambiguity)) + .map(|o| FulfillmentError::new((*o).clone(), CodeAmbiguity)) .collect(); if errors.is_empty() { @@ -129,7 +129,7 @@ impl FulfillmentContext { errors.push(FulfillmentError::new( (*obligation).clone(), - SelectionError(selection_err))); + CodeSelectionError(selection_err))); false } } @@ -237,7 +237,7 @@ impl FulfillmentContext { errors.push( FulfillmentError::new( (*obligation).clone(), - SelectionError(Unimplemented))); + CodeSelectionError(Unimplemented))); } if errors.is_empty() { diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index 62b3c982ccd..dde733a6a3e 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -97,8 +97,8 @@ pub struct FulfillmentError { #[deriving(Clone)] pub enum FulfillmentErrorCode { - SelectionError(SelectionError), - Ambiguity, + CodeSelectionError(SelectionError), + CodeAmbiguity, } /** @@ -110,7 +110,7 @@ pub enum FulfillmentErrorCode { * to inconclusive type inference. * - `Err(e)`: error `e` occurred */ -pub type SelectionResult<T> = Result<Option<T>,SelectionError>; +pub type SelectionResult<T> = Result<Option<T>, SelectionError>; #[deriving(PartialEq,Eq,Show)] pub enum EvaluationResult { @@ -157,12 +157,12 @@ pub enum EvaluationResult { * * ### The type parameter `N` * - * See explanation on `VtableImpl`. + * See explanation on `VtableImplData`. */ #[deriving(Show,Clone)] pub enum Vtable<N> { /// Vtable identifying a particular impl. - VtableImpl(VtableImpl<N>), + VtableImpl(VtableImplData<N>), /// Vtable automatically generated for an unboxed closure. The def /// ID is the ID of the closure expression. This is a `VtableImpl` @@ -172,7 +172,7 @@ pub enum Vtable<N> { /// Successful resolution to an obligation provided by the caller /// for some type parameter. - VtableParam(VtableParam), + VtableParam(VtableParamData), /// Successful resolution for a builtin trait. VtableBuiltin, @@ -191,7 +191,7 @@ pub enum Vtable<N> { * impl, and nested obligations are satisfied later. */ #[deriving(Clone)] -pub struct VtableImpl<N> { +pub struct VtableImplData<N> { pub impl_def_id: ast::DefId, pub substs: subst::Substs, pub nested: subst::VecPerParamSpace<N> @@ -203,7 +203,7 @@ pub struct VtableImpl<N> { * on an instance of `T`, the vtable would be of type `VtableParam`. */ #[deriving(Clone)] -pub struct VtableParam { +pub struct VtableParamData { // In the above example, this would `Eq` pub bound: Rc<ty::TraitRef>, } @@ -274,7 +274,7 @@ pub fn select_inherent_impl(infcx: &InferCtxt, cause: ObligationCause, impl_def_id: ast::DefId, self_ty: ty::t) - -> SelectionResult<VtableImpl<Obligation>> + -> SelectionResult<VtableImplData<Obligation>> { /*! * Matches the self type of the inherent impl `impl_def_id` @@ -398,21 +398,21 @@ impl<N> Vtable<N> { } } -impl<N> VtableImpl<N> { +impl<N> VtableImplData<N> { pub fn map_nested<M>(&self, op: |&N| -> M) - -> VtableImpl<M> + -> VtableImplData<M> { - VtableImpl { + VtableImplData { impl_def_id: self.impl_def_id, substs: self.substs.clone(), nested: self.nested.map(op) } } - pub fn map_move_nested<M>(self, op: |N| -> M) -> VtableImpl<M> { - let VtableImpl { impl_def_id, substs, nested } = self; - VtableImpl { + pub fn map_move_nested<M>(self, op: |N| -> M) -> VtableImplData<M> { + let VtableImplData { impl_def_id, substs, nested } = self; + VtableImplData { impl_def_id: impl_def_id, substs: substs, nested: nested.map_move(op) diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 681e2650f39..e475dc6063d 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -18,6 +18,7 @@ use super::{SelectionError, Unimplemented, Overflow, use super::{Selection}; use super::{SelectionResult}; use super::{VtableBuiltin, VtableImpl, VtableParam, VtableUnboxedClosure}; +use super::{VtableImplData, VtableParamData}; use super::{util}; use middle::subst::{Subst, Substs, VecPerParamSpace}; @@ -82,7 +83,7 @@ enum MatchResult<T> { enum Candidate { MatchedBuiltinCandidate, AmbiguousBuiltinCandidate, - MatchedParamCandidate(VtableParam), + MatchedParamCandidate(VtableParamData), AmbiguousParamCandidate, Impl(ImplCandidate), MatchedUnboxedClosureCandidate(/* closure */ ast::DefId) @@ -142,7 +143,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { impl_def_id: ast::DefId, obligation_cause: ObligationCause, obligation_self_ty: ty::t) - -> SelectionResult<VtableImpl<Obligation>> + -> SelectionResult<VtableImplData<Obligation>> { debug!("select_inherent_impl(impl_def_id={}, obligation_self_ty={})", impl_def_id.repr(self.tcx()), @@ -597,8 +598,8 @@ v */ fn confirm_param_candidate(&self, obligation: &Obligation, - param: VtableParam) - -> Result<VtableParam,SelectionError> + param: VtableParamData) + -> Result<VtableParamData,SelectionError> { debug!("confirm_param_candidate({},{})", obligation.repr(self.tcx()), @@ -613,7 +614,7 @@ v */ fn confirm_impl_candidate(&self, obligation: &Obligation, impl_def_id: ast::DefId) - -> Result<VtableImpl<Obligation>,SelectionError> + -> Result<VtableImplData<Obligation>,SelectionError> { debug!("confirm_impl_candidate({},{})", obligation.repr(self.tcx()), @@ -642,7 +643,7 @@ v */ obligation_cause: ObligationCause, obligation_self_ty: ty::t, obligation_recursion_depth: uint) - -> Result<VtableImpl<Obligation>, + -> Result<VtableImplData<Obligation>, SelectionError> { let substs = match self.match_impl_self_types(impl_def_id, @@ -663,7 +664,7 @@ v */ obligation_recursion_depth, impl_def_id, &substs); - let vtable_impl = VtableImpl { impl_def_id: impl_def_id, + let vtable_impl = VtableImplData { impl_def_id: impl_def_id, substs: substs, nested: impl_obligations }; diff --git a/src/librustc/middle/traits/util.rs b/src/librustc/middle/traits/util.rs index 1eae4ac1932..c48b125ac35 100644 --- a/src/librustc/middle/traits/util.rs +++ b/src/librustc/middle/traits/util.rs @@ -19,7 +19,7 @@ use syntax::ast; use syntax::codemap::Span; use util::ppaux::Repr; -use super::{Obligation, ObligationCause, VtableImpl, VtableParam}; +use super::{Obligation, ObligationCause, VtableImpl, VtableParam, VtableParamData, VtableImplData}; /////////////////////////////////////////////////////////////////////////// // Supertrait iterator @@ -137,13 +137,13 @@ pub fn fresh_substs_for_impl(infcx: &InferCtxt, infcx.fresh_substs_for_generics(span, &impl_generics) } -impl<N> fmt::Show for VtableImpl<N> { +impl<N> fmt::Show for VtableImplData<N> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "VtableImpl({})", self.impl_def_id) } } -impl fmt::Show for VtableParam { +impl fmt::Show for VtableParamData { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "VtableParam(...)") } @@ -239,7 +239,7 @@ pub fn obligation_for_builtin_bound( pub fn search_trait_and_supertraits_from_bound(tcx: &ty::ctxt, caller_bound: Rc<ty::TraitRef>, test: |ast::DefId| -> bool) - -> Option<VtableParam> + -> Option<VtableParamData> { /*! * Starting from a caller obligation `caller_bound` (which has @@ -252,7 +252,7 @@ pub fn search_trait_and_supertraits_from_bound(tcx: &ty::ctxt, for bound in transitive_bounds(tcx, &[caller_bound]) { if test(bound.def_id) { - let vtable_param = VtableParam { bound: bound }; + let vtable_param = VtableParamData { bound: bound }; return Some(vtable_param); } } @@ -287,7 +287,7 @@ impl<N:Repr> Repr for super::Vtable<N> { } } -impl<N:Repr> Repr for super::VtableImpl<N> { +impl<N:Repr> Repr for super::VtableImplData<N> { fn repr(&self, tcx: &ty::ctxt) -> String { format!("VtableImpl(impl_def_id={}, substs={}, nested={})", self.impl_def_id.repr(tcx), @@ -296,7 +296,7 @@ impl<N:Repr> Repr for super::VtableImpl<N> { } } -impl Repr for super::VtableParam { +impl Repr for super::VtableParamData { fn repr(&self, tcx: &ty::ctxt) -> String { format!("VtableParam(bound={})", self.bound.repr(tcx)) @@ -331,8 +331,8 @@ impl Repr for super::FulfillmentError { impl Repr for super::FulfillmentErrorCode { fn repr(&self, tcx: &ty::ctxt) -> String { match *self { - super::SelectionError(ref o) => o.repr(tcx), - super::Ambiguity => format!("Ambiguity") + super::CodeSelectionError(ref o) => o.repr(tcx), + super::CodeAmbiguity => format!("Ambiguity") } } } @@ -340,8 +340,8 @@ impl Repr for super::FulfillmentErrorCode { impl fmt::Show for super::FulfillmentErrorCode { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { - super::SelectionError(ref e) => write!(f, "{}", e), - super::Ambiguity => write!(f, "Ambiguity") + super::CodeSelectionError(ref e) => write!(f, "{}", e), + super::CodeAmbiguity => write!(f, "Ambiguity") } } } diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 51023d03c23..68d0bb2d8b4 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -1226,8 +1226,7 @@ pub fn trans_match<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, fn is_discr_reassigned(bcx: Block, discr: &ast::Expr, body: &ast::Expr) -> bool { match discr.node { ast::ExprPath(..) => match bcx.def(discr.id) { - def::DefArg(vid, _) | def::DefBinding(vid, _) | - def::DefLocal(vid, _) | def::DefUpvar(vid, _, _, _) => { + def::DefLocal(vid) | def::DefUpvar(vid, _, _) => { let mut rc = ReassignmentChecker { node: vid, reassigned: false @@ -1259,7 +1258,7 @@ impl euv::Delegate for ReassignmentChecker { fn mutate(&mut self, _: ast::NodeId, _: Span, cmt: mc::cmt, _: euv::MutateMode) { match cmt.cat { mc::cat_copied_upvar(mc::CopiedUpvar { upvar_id: vid, .. }) | - mc::cat_arg(vid) | mc::cat_local(vid) => self.reassigned = self.node == vid, + mc::cat_local(vid) => self.reassigned = self.node == vid, _ => {} } } @@ -1391,13 +1390,6 @@ fn trans_match_inner<'blk, 'tcx>(scope_cx: Block<'blk, 'tcx>, return bcx; } -enum IrrefutablePatternBindingMode { - // Stores the association between node ID and LLVM value in `lllocals`. - BindLocal, - // Stores the association between node ID and LLVM value in `llargs`. - BindArgument -} - pub fn store_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, local: &ast::Local) -> Block<'blk, 'tcx> { @@ -1419,7 +1411,7 @@ pub fn store_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pat_bindings(&tcx.def_map, pat, |_, p_id, _, path1| { let scope = cleanup::var_scope(tcx, p_id); bcx = mk_binding_alloca( - bcx, p_id, &path1.node, BindLocal, scope, (), + bcx, p_id, &path1.node, scope, (), |(), bcx, llval, ty| { zero_mem(bcx, llval, ty); bcx }); }); bcx @@ -1441,7 +1433,7 @@ pub fn store_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, Some(ident) => { let var_scope = cleanup::var_scope(tcx, local.id); return mk_binding_alloca( - bcx, pat.id, ident, BindLocal, var_scope, (), + bcx, pat.id, ident, var_scope, (), |(), bcx, v, _| expr::trans_into(bcx, &**init_expr, expr::SaveIn(v))); } @@ -1459,7 +1451,7 @@ pub fn store_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, add_comment(bcx, "creating zeroable ref llval"); } let var_scope = cleanup::var_scope(tcx, local.id); - bind_irrefutable_pat(bcx, pat, init_datum.val, BindLocal, var_scope) + bind_irrefutable_pat(bcx, pat, init_datum.val, var_scope) } } None => { @@ -1475,7 +1467,7 @@ pub fn store_arg<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, -> Block<'blk, 'tcx> { /*! * Generates code for argument patterns like `fn foo(<pat>: T)`. - * Creates entries in the `llargs` map for each of the bindings + * Creates entries in the `lllocals` map for each of the bindings * in `pat`. * * # Arguments @@ -1499,12 +1491,12 @@ pub fn store_arg<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, // already put it in a temporary alloca and gave it up, unless // we emit extra-debug-info, which requires local allocas :(. let arg_val = arg.add_clean(bcx.fcx, arg_scope); - bcx.fcx.llargs.borrow_mut() + bcx.fcx.lllocals.borrow_mut() .insert(pat.id, Datum::new(arg_val, arg_ty, Lvalue)); bcx } else { mk_binding_alloca( - bcx, pat.id, ident, BindArgument, arg_scope, arg, + bcx, pat.id, ident, arg_scope, arg, |arg, bcx, llval, _| arg.store_to(bcx, llval)) } } @@ -1514,8 +1506,7 @@ pub fn store_arg<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, // pattern. let arg = unpack_datum!( bcx, arg.to_lvalue_datum_in_scope(bcx, "__arg", arg_scope)); - bind_irrefutable_pat(bcx, pat, arg.val, - BindArgument, arg_scope) + bind_irrefutable_pat(bcx, pat, arg.val, arg_scope) } } } @@ -1541,13 +1532,12 @@ pub fn store_for_loop_binding<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, } // General path. Copy out the values that are used in the pattern. - bind_irrefutable_pat(bcx, pat, llvalue, BindLocal, body_scope) + bind_irrefutable_pat(bcx, pat, llvalue, body_scope) } fn mk_binding_alloca<'blk, 'tcx, A>(bcx: Block<'blk, 'tcx>, p_id: ast::NodeId, ident: &ast::Ident, - binding_mode: IrrefutablePatternBindingMode, cleanup_scope: cleanup::ScopeId, arg: A, populate: |A, Block<'blk, 'tcx>, ValueRef, ty::t| @@ -1567,18 +1557,13 @@ fn mk_binding_alloca<'blk, 'tcx, A>(bcx: Block<'blk, 'tcx>, // Now that memory is initialized and has cleanup scheduled, // create the datum and insert into the local variable map. let datum = Datum::new(llval, var_ty, Lvalue); - let mut llmap = match binding_mode { - BindLocal => bcx.fcx.lllocals.borrow_mut(), - BindArgument => bcx.fcx.llargs.borrow_mut() - }; - llmap.insert(p_id, datum); + bcx.fcx.lllocals.borrow_mut().insert(p_id, datum); bcx } fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pat: &ast::Pat, val: ValueRef, - binding_mode: IrrefutablePatternBindingMode, cleanup_scope: cleanup::ScopeId) -> Block<'blk, 'tcx> { /*! @@ -1594,13 +1579,11 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, * - bcx: starting basic block context * - pat: the irrefutable pattern being matched. * - val: the value being matched -- must be an lvalue (by ref, with cleanup) - * - binding_mode: is this for an argument or a local variable? */ - debug!("bind_irrefutable_pat(bcx={}, pat={}, binding_mode={:?})", + debug!("bind_irrefutable_pat(bcx={}, pat={})", bcx.to_str(), - pat.repr(bcx.tcx()), - binding_mode); + pat.repr(bcx.tcx())); if bcx.sess().asm_comments() { add_comment(bcx, format!("bind_irrefutable_pat(pat={})", @@ -1620,7 +1603,7 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // binding will live and place it into the appropriate // map. bcx = mk_binding_alloca( - bcx, pat.id, &path1.node, binding_mode, cleanup_scope, (), + bcx, pat.id, &path1.node, cleanup_scope, (), |(), bcx, llval, ty| { match pat_binding_mode { ast::BindByValue(_) => { @@ -1641,8 +1624,7 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, } for inner_pat in inner.iter() { - bcx = bind_irrefutable_pat(bcx, &**inner_pat, val, - binding_mode, cleanup_scope); + bcx = bind_irrefutable_pat(bcx, &**inner_pat, val, cleanup_scope); } } ast::PatEnum(_, ref sub_pats) => { @@ -1660,8 +1642,7 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, for sub_pat in sub_pats.iter() { for (i, &argval) in args.vals.iter().enumerate() { bcx = bind_irrefutable_pat(bcx, &**sub_pat.get(i), - argval, binding_mode, - cleanup_scope); + argval, cleanup_scope); } } } @@ -1678,8 +1659,7 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let fldptr = adt::trans_field_ptr(bcx, &*repr, val, 0, i); bcx = bind_irrefutable_pat(bcx, &**elem, - fldptr, binding_mode, - cleanup_scope); + fldptr, cleanup_scope); } } } @@ -1698,8 +1678,7 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let ix = ty::field_idx_strict(tcx, f.ident.name, field_tys); let fldptr = adt::trans_field_ptr(bcx, &*pat_repr, val, discr, ix); - bcx = bind_irrefutable_pat(bcx, &*f.pat, fldptr, - binding_mode, cleanup_scope); + bcx = bind_irrefutable_pat(bcx, &*f.pat, fldptr, cleanup_scope); } }) } @@ -1707,17 +1686,16 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let repr = adt::represent_node(bcx, pat.id); for (i, elem) in elems.iter().enumerate() { let fldptr = adt::trans_field_ptr(bcx, &*repr, val, 0, i); - bcx = bind_irrefutable_pat(bcx, &**elem, fldptr, - binding_mode, cleanup_scope); + bcx = bind_irrefutable_pat(bcx, &**elem, fldptr, cleanup_scope); } } ast::PatBox(ref inner) => { let llbox = Load(bcx, val); - bcx = bind_irrefutable_pat(bcx, &**inner, llbox, binding_mode, cleanup_scope); + bcx = bind_irrefutable_pat(bcx, &**inner, llbox, cleanup_scope); } ast::PatRegion(ref inner) => { let loaded_val = Load(bcx, val); - bcx = bind_irrefutable_pat(bcx, &**inner, loaded_val, binding_mode, cleanup_scope); + bcx = bind_irrefutable_pat(bcx, &**inner, loaded_val, cleanup_scope); } ast::PatVec(ref before, ref slice, ref after) => { let pat_ty = node_id_type(bcx, pat.id); @@ -1737,7 +1715,7 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, .chain(after.iter()) .zip(extracted.vals.into_iter()) .fold(bcx, |bcx, (inner, elem)| - bind_irrefutable_pat(bcx, &**inner, elem, binding_mode, cleanup_scope) + bind_irrefutable_pat(bcx, &**inner, elem, cleanup_scope) ); } ast::PatMac(..) => { diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index a814c9d624c..72e0401e7ab 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -191,21 +191,13 @@ pub fn decl_fn(ccx: &CrateContext, name: &str, cc: llvm::CallConv, match ty::get(output).sty { // functions returning bottom may unwind, but can never return normally ty::ty_bot => { - unsafe { - llvm::LLVMAddFunctionAttribute(llfn, - llvm::FunctionIndex as c_uint, - llvm::NoReturnAttribute as uint64_t) - } + llvm::SetFunctionAttribute(llfn, llvm::NoReturnAttribute) } _ => {} } if ccx.tcx().sess.opts.cg.no_redzone { - unsafe { - llvm::LLVMAddFunctionAttribute(llfn, - llvm::FunctionIndex as c_uint, - llvm::NoRedZoneAttribute as uint64_t) - } + llvm::SetFunctionAttribute(llfn, llvm::NoRedZoneAttribute) } llvm::SetFunctionCallConv(llfn, cc); @@ -1468,7 +1460,6 @@ pub fn new_fn_ctxt<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>, needs_ret_allocas: nested_returns, personality: Cell::new(None), caller_expects_out_pointer: uses_outptr, - llargs: RefCell::new(NodeMap::new()), lllocals: RefCell::new(NodeMap::new()), llupvars: RefCell::new(NodeMap::new()), id: id, diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index c54a446c455..53c13f56284 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -196,9 +196,7 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr) } } def::DefStatic(..) | - def::DefArg(..) | def::DefLocal(..) | - def::DefBinding(..) | def::DefUpvar(..) => { datum_callee(bcx, ref_expr) } @@ -860,10 +858,10 @@ pub enum CallArgs<'a> { // value. ArgVals(&'a [ValueRef]), - // For overloaded operators: `(lhs, Option(rhs, rhs_id))`. `lhs` + // For overloaded operators: `(lhs, Vec(rhs, rhs_id))`. `lhs` // is the left-hand-side and `rhs/rhs_id` is the datum/expr-id of - // the right-hand-side (if any). - ArgOverloadedOp(Datum<Expr>, Option<(Datum<Expr>, ast::NodeId)>), + // the right-hand-side arguments (if any). + ArgOverloadedOp(Datum<Expr>, Vec<(Datum<Expr>, ast::NodeId)>), // Supply value of arguments as a list of expressions that must be // translated, for overloaded call operators. @@ -1047,17 +1045,13 @@ pub fn trans_args<'blk, 'tcx>(cx: Block<'blk, 'tcx>, DontAutorefArg) })); - match rhs { - Some((rhs, rhs_id)) => { - assert_eq!(arg_tys.len(), 2); - - llargs.push(unpack_result!(bcx, { - trans_arg_datum(bcx, *arg_tys.get(1), rhs, - arg_cleanup_scope, - DoAutorefArg(rhs_id)) - })); - } - None => assert_eq!(arg_tys.len(), 1) + assert_eq!(arg_tys.len(), 1 + rhs.len()); + for (rhs, rhs_id) in rhs.move_iter() { + llargs.push(unpack_result!(bcx, { + trans_arg_datum(bcx, *arg_tys.get(1), rhs, + arg_cleanup_scope, + DoAutorefArg(rhs_id)) + })); } } ArgVals(vs) => { diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index 6ab344ff69e..fa8c6b8b448 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -14,7 +14,7 @@ use back::link::mangle_internal_name_by_path_and_seq; use driver::config::FullDebugInfo; use llvm::ValueRef; use middle::def; -use middle::freevars; +use middle::mem_categorization::Typer; use middle::trans::adt; use middle::trans::base::*; use middle::trans::build::*; @@ -100,7 +100,7 @@ use syntax::ast_util; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pub struct EnvValue { - action: freevars::CaptureMode, + action: ast::CaptureClause, datum: Datum<Lvalue> } @@ -120,8 +120,8 @@ pub fn mk_closure_tys(tcx: &ty::ctxt, // converted to ptrs. let bound_tys = bound_values.iter().map(|bv| { match bv.action { - freevars::CaptureByValue => bv.datum.ty, - freevars::CaptureByRef => ty::mk_mut_ptr(tcx, bv.datum.ty) + ast::CaptureByValue => bv.datum.ty, + ast::CaptureByRef => ty::mk_mut_ptr(tcx, bv.datum.ty) } }).collect(); let cdata_ty = ty::mk_tup(tcx, bound_tys); @@ -208,10 +208,10 @@ pub fn store_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let bound_data = GEPi(bcx, llbox, [0u, abi::box_field_body, i]); match bv.action { - freevars::CaptureByValue => { + ast::CaptureByValue => { bcx = bv.datum.store_to(bcx, bound_data); } - freevars::CaptureByRef => { + ast::CaptureByRef => { Store(bcx, bv.datum.to_llref(), bound_data); } } @@ -223,8 +223,8 @@ pub fn store_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // Given a context and a list of upvars, build a closure. This just // collects the upvars and packages them up for store_environment. fn build_closure<'blk, 'tcx>(bcx0: Block<'blk, 'tcx>, - freevar_mode: freevars::CaptureMode, - freevars: &Vec<freevars::freevar_entry>, + freevar_mode: ast::CaptureClause, + freevars: &Vec<ty::Freevar>, store: ty::TraitStore) -> ClosureResult<'blk, 'tcx> { let _icx = push_ctxt("closure::build_closure"); @@ -247,7 +247,7 @@ fn build_closure<'blk, 'tcx>(bcx0: Block<'blk, 'tcx>, // with the upvars and type descriptors. fn load_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, cdata_ty: ty::t, - freevars: &Vec<freevars::freevar_entry>, + freevars: &Vec<ty::Freevar>, store: ty::TraitStore) -> Block<'blk, 'tcx> { let _icx = push_ctxt("closure::load_environment"); @@ -301,7 +301,7 @@ fn load_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, fn load_unboxed_closure_environment<'blk, 'tcx>( bcx: Block<'blk, 'tcx>, arg_scope_id: ScopeId, - freevars: &Vec<freevars::freevar_entry>, + freevars: &Vec<ty::Freevar>, closure_id: ast::DefId) -> Block<'blk, 'tcx> { let _icx = push_ctxt("closure::load_environment"); @@ -386,11 +386,9 @@ pub fn trans_expr_fn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // set an inline hint for all closures set_inline_hint(llfn); - let freevar_mode = freevars::get_capture_mode(tcx, id); - let freevars: Vec<freevars::freevar_entry> = - freevars::with_freevars(tcx, - id, - |fv| fv.iter().map(|&fv| fv).collect()); + let freevar_mode = tcx.capture_mode(id); + let freevars: Vec<ty::Freevar> = + ty::with_freevars(tcx, id, |fv| fv.iter().map(|&fv| fv).collect()); let ClosureResult { llbox, @@ -476,10 +474,8 @@ pub fn trans_unboxed_closure<'blk, 'tcx>( .clone(); let function_type = ty::mk_closure(bcx.tcx(), function_type); - let freevars: Vec<freevars::freevar_entry> = - freevars::with_freevars(bcx.tcx(), - id, - |fv| fv.iter().map(|&fv| fv).collect()); + let freevars: Vec<ty::Freevar> = + ty::with_freevars(bcx.tcx(), id, |fv| fv.iter().map(|&fv| fv).collect()); let freevars_ptr = &freevars; trans_closure(bcx.ccx(), diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 60ae26439b4..a5a9d685176 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -17,7 +17,6 @@ use llvm; use llvm::{ValueRef, BasicBlockRef, BuilderRef, ContextRef}; use llvm::{True, False, Bool}; use middle::def; -use middle::freevars; use middle::lang_items::LangItem; use middle::mem_categorization as mc; use middle::subst; @@ -267,10 +266,7 @@ pub struct FunctionContext<'a, 'tcx: 'a> { // points to, but if this value is false, that slot will be a local alloca. pub caller_expects_out_pointer: bool, - // Maps arguments to allocas created for them in llallocas. - pub llargs: RefCell<NodeMap<LvalueDatum>>, - - // Maps the def_ids for local variables to the allocas created for + // Maps the DefId's for local variables to the allocas created for // them in llallocas. pub lllocals: RefCell<NodeMap<LvalueDatum>>, @@ -528,7 +524,7 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> { } fn capture_mode(&self, closure_expr_id: ast::NodeId) - -> freevars::CaptureMode { + -> ast::CaptureClause { self.tcx().capture_modes.borrow().get_copy(&closure_expr_id) } } diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index 576031500b9..d39fe4a1e70 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -207,7 +207,7 @@ pub fn const_expr(cx: &CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef None => { } Some(adj) => { match adj { - ty::AutoAddEnv(ty::RegionTraitStore(ty::ReStatic, _)) => { + ty::AdjustAddEnv(ty::RegionTraitStore(ty::ReStatic, _)) => { let def = ty::resolve_expr(cx.tcx(), e); let wrapper = closure::get_wrapper_for_bare_fn(cx, ety_adjusted, @@ -216,13 +216,13 @@ pub fn const_expr(cx: &CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef is_local); llconst = C_struct(cx, [wrapper, C_null(Type::i8p(cx))], false) } - ty::AutoAddEnv(store) => { + ty::AdjustAddEnv(store) => { cx.sess() .span_bug(e.span, format!("unexpected static function: {:?}", store).as_slice()) } - ty::AutoDerefRef(ref adj) => { + ty::AdjustDerefRef(ref adj) => { let mut ty = ety; // Save the last autoderef in case we can avoid it. if adj.autoderefs > 0 { diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 62571ef9f9b..1980d67fc47 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -664,7 +664,7 @@ pub struct FunctionDebugContext { } enum FunctionDebugContextRepr { - FunctionDebugContext(Box<FunctionDebugContextData>), + DebugInfo(Box<FunctionDebugContextData>), DebugInfoDisabled, FunctionWithoutDebugInfo, } @@ -675,7 +675,7 @@ impl FunctionDebugContext { span: Span) -> &'a FunctionDebugContextData { match self.repr { - FunctionDebugContext(box ref data) => data, + DebugInfo(box ref data) => data, DebugInfoDisabled => { cx.sess().span_bug(span, FunctionDebugContext::debuginfo_disabled_message()); @@ -999,11 +999,11 @@ pub fn create_argument_metadata(bcx: Block, arg: &ast::Arg) { let scope_metadata = bcx.fcx.debug_context.get_ref(cx, arg.pat.span).fn_metadata; pat_util::pat_bindings(def_map, &*arg.pat, |_, node_id, span, path1| { - let llarg = match bcx.fcx.llargs.borrow().find_copy(&node_id) { + let llarg = match bcx.fcx.lllocals.borrow().find_copy(&node_id) { Some(v) => v, None => { bcx.sess().span_bug(span, - format!("no entry in llargs table for {:?}", + format!("no entry in lllocals table for {:?}", node_id).as_slice()); } }; @@ -1044,7 +1044,7 @@ pub fn set_source_location(fcx: &FunctionContext, set_debug_location(fcx.ccx, UnknownLocation); return; } - FunctionDebugContext(box ref function_debug_context) => { + DebugInfo(box ref function_debug_context) => { let cx = fcx.ccx; debug!("set_source_location: {}", cx.sess().codemap().span_to_string(span)); @@ -1082,7 +1082,7 @@ pub fn clear_source_location(fcx: &FunctionContext) { /// first real statement/expression of the function is translated. pub fn start_emitting_source_locations(fcx: &FunctionContext) { match fcx.debug_context.repr { - FunctionDebugContext(box ref data) => { + DebugInfo(box ref data) => { data.source_locations_enabled.set(true) }, _ => { /* safe to ignore */ } @@ -1291,7 +1291,7 @@ pub fn create_function_debug_context(cx: &CrateContext, fn_metadata, &mut *fn_debug_context.scope_map.borrow_mut()); - return FunctionDebugContext { repr: FunctionDebugContext(fn_debug_context) }; + return FunctionDebugContext { repr: DebugInfo(fn_debug_context) }; fn get_function_signature(cx: &CrateContext, fn_ast_id: ast::NodeId, @@ -3134,7 +3134,7 @@ fn DIB(cx: &CrateContext) -> DIBuilderRef { fn fn_should_be_ignored(fcx: &FunctionContext) -> bool { match fcx.debug_context.repr { - FunctionDebugContext(_) => false, + DebugInfo(_) => false, _ => true } } @@ -3479,6 +3479,12 @@ fn populate_scope_map(cx: &CrateContext, walk_expr(cx, &**rhs, scope_stack, scope_map); } + ast::ExprSlice(ref base, ref start, ref end, _) => { + walk_expr(cx, &**base, scope_stack, scope_map); + start.as_ref().map(|x| walk_expr(cx, &**x, scope_stack, scope_map)); + end.as_ref().map(|x| walk_expr(cx, &**x, scope_stack, scope_map)); + } + ast::ExprVec(ref init_expressions) | ast::ExprTup(ref init_expressions) => { for ie in init_expressions.iter() { diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 77712570185..75c28477414 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -64,14 +64,13 @@ use middle::trans::inline; use middle::trans::tvec; use middle::trans::type_of; use middle::ty::{struct_fields, tup_fields}; -use middle::ty::{AutoDerefRef, AutoAddEnv, AutoUnsafe}; +use middle::ty::{AdjustDerefRef, AdjustAddEnv, AutoUnsafe}; use middle::ty::{AutoPtr}; use middle::ty; use middle::typeck; use middle::typeck::MethodCall; use util::common::indenter; use util::ppaux::Repr; -use util::nodemap::NodeMap; use middle::trans::machine::{llsize_of, llsize_of_alloc}; use middle::trans::type_::Type; @@ -190,10 +189,10 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, debug!("unadjusted datum for expr {}: {}", expr.id, datum.to_string(bcx.ccx())); match adjustment { - AutoAddEnv(..) => { + AdjustAddEnv(..) => { datum = unpack_datum!(bcx, add_env(bcx, expr, datum)); } - AutoDerefRef(ref adj) => { + AdjustDerefRef(ref adj) => { let (autoderefs, use_autoref) = match adj.autoref { // Extracting a value from a box counts as a deref, but if we are // just converting Box<[T, ..n]> to Box<[T]> we aren't really doing @@ -590,6 +589,34 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ast::ExprIndex(ref base, ref idx) => { trans_index(bcx, expr, &**base, &**idx, MethodCall::expr(expr.id)) } + ast::ExprSlice(ref base, ref start, ref end, _) => { + let _icx = push_ctxt("trans_slice"); + let ccx = bcx.ccx(); + + let method_call = MethodCall::expr(expr.id); + let method_ty = ccx.tcx() + .method_map + .borrow() + .find(&method_call) + .map(|method| method.ty); + let base_datum = unpack_datum!(bcx, trans(bcx, &**base)); + + let mut args = vec![]; + start.as_ref().map(|e| args.push((unpack_datum!(bcx, trans(bcx, &**e)), e.id))); + end.as_ref().map(|e| args.push((unpack_datum!(bcx, trans(bcx, &**e)), e.id))); + + let result_ty = ty::ty_fn_ret(monomorphize_type(bcx, method_ty.unwrap())); + let scratch = rvalue_scratch_datum(bcx, result_ty, "trans_slice"); + + unpack_result!(bcx, + trans_overloaded_op(bcx, + expr, + method_call, + base_datum, + args, + Some(SaveIn(scratch.val)))); + DatumBlock::new(bcx, scratch.to_expr_datum()) + } ast::ExprBox(_, ref contents) => { // Special case for `Box<T>` and `Gc<T>` let box_ty = expr_ty(bcx, expr); @@ -725,7 +752,7 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, index_expr, method_call, base_datum, - Some((ix_datum, idx.id)), + vec![(ix_datum, idx.id)], None)); let ref_ty = ty::ty_fn_ret(monomorphize_type(bcx, method_ty)); let elt_ty = match ty::deref(ref_ty, true) { @@ -1044,20 +1071,20 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let lhs = unpack_datum!(bcx, trans(bcx, &**lhs)); let rhs_datum = unpack_datum!(bcx, trans(bcx, &**rhs)); trans_overloaded_op(bcx, expr, MethodCall::expr(expr.id), lhs, - Some((rhs_datum, rhs.id)), Some(dest)).bcx + vec![(rhs_datum, rhs.id)], Some(dest)).bcx } ast::ExprUnary(_, ref subexpr) => { // if not overloaded, would be RvalueDatumExpr let arg = unpack_datum!(bcx, trans(bcx, &**subexpr)); trans_overloaded_op(bcx, expr, MethodCall::expr(expr.id), - arg, None, Some(dest)).bcx + arg, Vec::new(), Some(dest)).bcx } ast::ExprIndex(ref base, ref idx) => { // if not overloaded, would be RvalueDatumExpr let base = unpack_datum!(bcx, trans(bcx, &**base)); let idx_datum = unpack_datum!(bcx, trans(bcx, &**idx)); trans_overloaded_op(bcx, expr, MethodCall::expr(expr.id), base, - Some((idx_datum, idx.id)), Some(dest)).bcx + vec![(idx_datum, idx.id)], Some(dest)).bcx } ast::ExprCast(ref val, _) => { // DPS output mode means this is a trait cast: @@ -1176,8 +1203,8 @@ pub fn trans_local_var<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let _icx = push_ctxt("trans_local_var"); - return match def { - def::DefUpvar(nid, _, _, _) => { + match def { + def::DefUpvar(nid, _, _) => { // Can't move upvars, so this is never a ZeroMemLastUse. let local_ty = node_id_type(bcx, nid); match bcx.fcx.llupvars.borrow().find(&nid) { @@ -1189,34 +1216,24 @@ pub fn trans_local_var<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, } } } - def::DefArg(nid, _) => { - take_local(bcx, &*bcx.fcx.llargs.borrow(), nid) - } - def::DefLocal(nid, _) | def::DefBinding(nid, _) => { - take_local(bcx, &*bcx.fcx.lllocals.borrow(), nid) + def::DefLocal(nid) => { + let datum = match bcx.fcx.lllocals.borrow().find(&nid) { + Some(&v) => v, + None => { + bcx.sess().bug(format!( + "trans_local_var: no datum for local/arg {:?} found", + nid).as_slice()); + } + }; + debug!("take_local(nid={:?}, v={}, ty={})", + nid, bcx.val_to_string(datum.val), bcx.ty_to_string(datum.ty)); + datum } _ => { bcx.sess().unimpl(format!( "unsupported def type in trans_local_var: {:?}", def).as_slice()); } - }; - - fn take_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, - table: &NodeMap<Datum<Lvalue>>, - nid: ast::NodeId) - -> Datum<Lvalue> { - let datum = match table.find(&nid) { - Some(&v) => v, - None => { - bcx.sess().bug(format!( - "trans_local_var: no datum for local/arg {:?} found", - nid).as_slice()); - } - }; - debug!("take_local(nid={:?}, v={}, ty={})", - nid, bcx.val_to_string(datum.val), bcx.ty_to_string(datum.ty)); - datum } } @@ -1751,7 +1768,7 @@ fn trans_overloaded_op<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr, method_call: MethodCall, lhs: Datum<Expr>, - rhs: Option<(Datum<Expr>, ast::NodeId)>, + rhs: Vec<(Datum<Expr>, ast::NodeId)>, dest: Option<Dest>) -> Result<'blk, 'tcx> { let method_ty = bcx.tcx().method_map.borrow().get(&method_call).ty; @@ -2074,7 +2091,7 @@ fn deref_once<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let scratch = rvalue_scratch_datum(bcx, ref_ty, "overloaded_deref"); unpack_result!(bcx, trans_overloaded_op(bcx, expr, method_call, - datum, None, Some(SaveIn(scratch.val)))); + datum, Vec::new(), Some(SaveIn(scratch.val)))); scratch.to_expr_datum() } None => { diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index f3049dcee50..9cff7261806 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -998,7 +998,7 @@ fn add_argument_attributes(tys: &ForeignTypes, match tys.fn_ty.ret_ty.attr { Some(attr) => unsafe { - llvm::LLVMAddFunctionAttribute(llfn, i as c_uint, attr as u64); + llvm::LLVMAddFunctionAttribute(llfn, i as c_uint, attr.bits() as u64); }, None => {} } @@ -1014,7 +1014,7 @@ fn add_argument_attributes(tys: &ForeignTypes, match arg_ty.attr { Some(attr) => unsafe { - llvm::LLVMAddFunctionAttribute(llfn, i as c_uint, attr as u64); + llvm::LLVMAddFunctionAttribute(llfn, i as c_uint, attr.bits() as u64); }, None => () } diff --git a/src/librustc/middle/trans/intrinsic.rs b/src/librustc/middle/trans/intrinsic.rs index 36184b2eed3..3b3d7d02a2c 100644 --- a/src/librustc/middle/trans/intrinsic.rs +++ b/src/librustc/middle/trans/intrinsic.rs @@ -11,7 +11,7 @@ #![allow(non_uppercase_statics)] use llvm; -use llvm::{SequentiallyConsistent, Acquire, Release, Xchg, ValueRef}; +use llvm::{SequentiallyConsistent, Acquire, Release, AtomicXchg, ValueRef}; use middle::subst; use middle::subst::FnSpace; use middle::trans::base::*; @@ -510,17 +510,17 @@ pub fn trans_intrinsic_call<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, node: ast::N // These are all AtomicRMW ops op => { let atom_op = match op { - "xchg" => llvm::Xchg, - "xadd" => llvm::Add, - "xsub" => llvm::Sub, - "and" => llvm::And, - "nand" => llvm::Nand, - "or" => llvm::Or, - "xor" => llvm::Xor, - "max" => llvm::Max, - "min" => llvm::Min, - "umax" => llvm::UMax, - "umin" => llvm::UMin, + "xchg" => llvm::AtomicXchg, + "xadd" => llvm::AtomicAdd, + "xsub" => llvm::AtomicSub, + "and" => llvm::AtomicAnd, + "nand" => llvm::AtomicNand, + "or" => llvm::AtomicOr, + "xor" => llvm::AtomicXor, + "max" => llvm::AtomicMax, + "min" => llvm::AtomicMin, + "umax" => llvm::AtomicUMax, + "umin" => llvm::AtomicUMin, _ => ccx.sess().fatal("unknown atomic operation") }; diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index f1276387745..844ee0a60c6 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -131,7 +131,7 @@ pub fn trans_method_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, } } - typeck::MethodParam(typeck::MethodParam { + typeck::MethodTypeParam(typeck::MethodParam { trait_ref: ref trait_ref, method_num: method_num }) => { @@ -147,7 +147,7 @@ pub fn trans_method_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, method_num, origin) } - typeck::MethodObject(ref mt) => { + typeck::MethodTraitObject(ref mt) => { let self_expr = match self_expr { Some(self_expr) => self_expr, None => { @@ -243,7 +243,7 @@ pub fn trans_static_method_callee(bcx: Block, // Now that we know which impl is being used, we can dispatch to // the actual function: match vtbl { - traits::VtableImpl(traits::VtableImpl { + traits::VtableImpl(traits::VtableImplData { impl_def_id: impl_did, substs: impl_substs, nested: _ }) => @@ -562,7 +562,7 @@ pub fn get_vtable(bcx: Block, trait_ref.clone()); match vtable { traits::VtableImpl( - traits::VtableImpl { + traits::VtableImplData { impl_def_id: id, substs: substs, nested: _ }) => { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 897bc4517f4..33ade80afd3 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -17,8 +17,6 @@ use metadata::csearch; use middle::const_eval; use middle::def; use middle::dependency_format; -use middle::freevars::CaptureModeMap; -use middle::freevars; use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem}; use middle::lang_items::{FnOnceTraitLangItem, OpaqueStructLangItem}; use middle::lang_items::{TyDescStructLangItem, TyVisitorTraitLangItem}; @@ -279,8 +277,8 @@ pub enum Variance { #[deriving(Clone)] pub enum AutoAdjustment { - AutoAddEnv(ty::TraitStore), - AutoDerefRef(AutoDerefRef) + AdjustAddEnv(ty::TraitStore), + AdjustDerefRef(AutoDerefRef) } #[deriving(Clone, PartialEq)] @@ -352,7 +350,7 @@ fn autoref_object_region(autoref: &AutoRef) -> (bool, bool, Option<Region>) { // returns the region of the borrowed reference. pub fn adjusted_object_region(adj: &AutoAdjustment) -> Option<Region> { match adj { - &AutoDerefRef(AutoDerefRef{autoref: Some(ref autoref), ..}) => { + &AdjustDerefRef(AutoDerefRef{autoref: Some(ref autoref), ..}) => { let (b, _, r) = autoref_object_region(autoref); if b { r @@ -367,7 +365,7 @@ pub fn adjusted_object_region(adj: &AutoAdjustment) -> Option<Region> { // Returns true if there is a trait cast at the bottom of the adjustment. pub fn adjust_is_object(adj: &AutoAdjustment) -> bool { match adj { - &AutoDerefRef(AutoDerefRef{autoref: Some(ref autoref), ..}) => { + &AdjustDerefRef(AutoDerefRef{autoref: Some(ref autoref), ..}) => { let (b, _, _) = autoref_object_region(autoref); b } @@ -409,7 +407,7 @@ pub fn type_of_adjust(cx: &ctxt, adj: &AutoAdjustment) -> Option<t> { } match adj { - &AutoDerefRef(AutoDerefRef{autoref: Some(ref autoref), ..}) => { + &AdjustDerefRef(AutoDerefRef{autoref: Some(ref autoref), ..}) => { type_of_autoref(cx, autoref) } _ => None @@ -480,7 +478,7 @@ pub struct ctxt<'tcx> { pub map: ast_map::Map<'tcx>, pub intrinsic_defs: RefCell<DefIdMap<t>>, - pub freevars: RefCell<freevars::freevar_map>, + pub freevars: RefCell<FreevarMap>, pub tcache: type_cache, pub rcache: creader_cache, pub short_names_cache: RefCell<HashMap<t, String>>, @@ -1463,8 +1461,8 @@ pub fn mk_ctxt<'tcx>(s: Session, dm: resolve::DefMap, named_region_map: resolve_lifetime::NamedRegionMap, map: ast_map::Map<'tcx>, - freevars: freevars::freevar_map, - capture_modes: freevars::CaptureModeMap, + freevars: RefCell<FreevarMap>, + capture_modes: RefCell<CaptureModeMap>, region_maps: middle::region::RegionMaps, lang_items: middle::lang_items::LanguageItems, stability: stability::Index) -> ctxt<'tcx> { @@ -1485,7 +1483,7 @@ pub fn mk_ctxt<'tcx>(s: Session, object_cast_map: RefCell::new(NodeMap::new()), map: map, intrinsic_defs: RefCell::new(DefIdMap::new()), - freevars: RefCell::new(freevars), + freevars: freevars, tcache: RefCell::new(DefIdMap::new()), rcache: RefCell::new(HashMap::new()), short_names_cache: RefCell::new(HashMap::new()), @@ -1522,7 +1520,7 @@ pub fn mk_ctxt<'tcx>(s: Session, node_lint_levels: RefCell::new(HashMap::new()), transmute_restrictions: RefCell::new(Vec::new()), stability: RefCell::new(stability), - capture_modes: RefCell::new(capture_modes), + capture_modes: capture_modes, associated_types: RefCell::new(DefIdMap::new()), trait_associated_types: RefCell::new(DefIdMap::new()), } @@ -3425,7 +3423,7 @@ pub fn adjust_ty(cx: &ctxt, return match adjustment { Some(adjustment) => { match *adjustment { - AutoAddEnv(store) => { + AdjustAddEnv(store) => { match ty::get(unadjusted_ty).sty { ty::ty_bare_fn(ref b) => { let bounds = ty::ExistentialBounds { @@ -3451,7 +3449,7 @@ pub fn adjust_ty(cx: &ctxt, } } - AutoDerefRef(ref adj) => { + AdjustDerefRef(ref adj) => { let mut adjusted_ty = unadjusted_ty; if !ty::type_is_error(adjusted_ty) { @@ -3584,12 +3582,12 @@ pub fn method_call_type_param_defs<'tcx, T>(typer: &T, .trait_did(typer.tcx()); lookup_trait_def(typer.tcx(), def_id).generics.types.clone() } - typeck::MethodParam(typeck::MethodParam{ + typeck::MethodTypeParam(typeck::MethodParam{ trait_ref: ref trait_ref, method_num: n_mth, .. }) | - typeck::MethodObject(typeck::MethodObject{ + typeck::MethodTraitObject(typeck::MethodObject{ trait_ref: ref trait_ref, method_num: n_mth, .. @@ -3648,6 +3646,9 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind { // the index method invoked for `a[i]` always yields an `&T` ast::ExprIndex(..) => LvalueExpr, + // the slice method invoked for `a[..]` always yields an `&T` + ast::ExprSlice(..) => LvalueExpr, + // `for` loops are statements ast::ExprForLoop(..) => RvalueStmtExpr, @@ -3684,9 +3685,7 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind { // DefArg's, particularly those of immediate type, ought to // considered rvalues. def::DefStatic(..) | - def::DefBinding(..) | def::DefUpvar(..) | - def::DefArg(..) | def::DefLocal(..) => LvalueExpr, def => { @@ -3702,7 +3701,8 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind { ast::ExprUnary(ast::UnDeref, _) | ast::ExprField(..) | ast::ExprTupField(..) | - ast::ExprIndex(..) => { + ast::ExprIndex(..) | + ast::ExprSlice(..) => { LvalueExpr } @@ -4759,7 +4759,7 @@ pub fn unboxed_closure_upvars(tcx: &ctxt, closure_id: ast::DefId) -> Vec<UnboxedClosureUpvar> { if closure_id.krate == ast::LOCAL_CRATE { match tcx.freevars.borrow().find(&closure_id.node) { - None => tcx.sess.bug("no freevars for unboxed closure?!"), + None => vec![], Some(ref freevars) => { freevars.iter().map(|freevar| { let freevar_def_id = freevar.def.def_id(); @@ -5617,7 +5617,7 @@ impl<'tcx> mc::Typer<'tcx> for ty::ctxt<'tcx> { } fn capture_mode(&self, closure_expr_id: ast::NodeId) - -> freevars::CaptureMode { + -> ast::CaptureClause { self.capture_modes.borrow().get_copy(&closure_expr_id) } @@ -5688,3 +5688,24 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>, } }) } + +/// A free variable referred to in a function. +#[deriving(Encodable, Decodable)] +pub struct Freevar { + /// The variable being accessed free. + pub def: def::Def, + + // First span where it is accessed (there can be multiple). + pub span: Span +} + +pub type FreevarMap = NodeMap<Vec<Freevar>>; + +pub type CaptureModeMap = NodeMap<ast::CaptureClause>; + +pub fn with_freevars<T>(tcx: &ty::ctxt, fid: ast::NodeId, f: |&[Freevar]| -> T) -> T { + match tcx.freevars.borrow().find(&fid) { + None => f(&[]), + Some(d) => f(d.as_slice()) + } +} diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs index 3b08ccd5a7b..2e964c457bf 100644 --- a/src/librustc/middle/ty_fold.rs +++ b/src/librustc/middle/ty_fold.rs @@ -353,9 +353,9 @@ impl TypeFoldable for traits::Obligation { } } -impl<N:TypeFoldable> TypeFoldable for traits::VtableImpl<N> { - fn fold_with<'tcx, F:TypeFolder<'tcx>>(&self, folder: &mut F) -> traits::VtableImpl<N> { - traits::VtableImpl { +impl<N:TypeFoldable> TypeFoldable for traits::VtableImplData<N> { + fn fold_with<'tcx, F:TypeFolder<'tcx>>(&self, folder: &mut F) -> traits::VtableImplData<N> { + traits::VtableImplData { impl_def_id: self.impl_def_id, substs: self.substs.fold_with(folder), nested: self.nested.fold_with(folder), @@ -374,9 +374,9 @@ impl<N:TypeFoldable> TypeFoldable for traits::Vtable<N> { } } -impl TypeFoldable for traits::VtableParam { - fn fold_with<'tcx, F:TypeFolder<'tcx>>(&self, folder: &mut F) -> traits::VtableParam { - traits::VtableParam { +impl TypeFoldable for traits::VtableParamData { + fn fold_with<'tcx, F:TypeFolder<'tcx>>(&self, folder: &mut F) -> traits::VtableParamData { + traits::VtableParamData { bound: self.bound.fold_with(folder), } } diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 8f60be8f7fb..2503fb2541b 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -585,32 +585,29 @@ pub fn trait_ref_for_unboxed_function<'tcx, AC: AstConv<'tcx>, RS:RegionScope>( this: &AC, rscope: &RS, - unboxed_function: &ast::UnboxedFnTy, + kind: ast::UnboxedClosureKind, + decl: &ast::FnDecl, self_ty: Option<ty::t>) -> ty::TraitRef { - let lang_item = match unboxed_function.kind { + let lang_item = match kind { ast::FnUnboxedClosureKind => FnTraitLangItem, ast::FnMutUnboxedClosureKind => FnMutTraitLangItem, ast::FnOnceUnboxedClosureKind => FnOnceTraitLangItem, }; let trait_did = this.tcx().lang_items.require(lang_item).unwrap(); - let input_types = - unboxed_function.decl - .inputs - .iter() - .map(|input| { + let input_types = decl.inputs + .iter() + .map(|input| { ast_ty_to_ty(this, rscope, &*input.ty) - }).collect::<Vec<_>>(); + }).collect::<Vec<_>>(); let input_tuple = if input_types.len() == 0 { ty::mk_nil() } else { ty::mk_tup(this.tcx(), input_types) }; - let output_type = ast_ty_to_ty(this, - rscope, - &*unboxed_function.decl.output); + let output_type = ast_ty_to_ty(this, rscope, &*decl.output); let mut substs = Substs::new_type(vec!(input_tuple, output_type), - Vec::new()); + Vec::new()); match self_ty { Some(s) => substs.types.push(SelfSpace, s), @@ -648,7 +645,8 @@ fn mk_pointer<'tcx, AC: AstConv<'tcx>, RS: RegionScope>( substs } = trait_ref_for_unboxed_function(this, rscope, - &**unboxed_function, + unboxed_function.kind, + &*unboxed_function.decl, None); let r = ptr_ty.default_region(); let tr = ty::mk_trait(this.tcx(), @@ -1510,7 +1508,7 @@ fn compute_region_bound<'tcx, AC: AstConv<'tcx>, RS:RegionScope>( pub struct PartitionedBounds<'a> { pub builtin_bounds: ty::BuiltinBounds, pub trait_bounds: Vec<&'a ast::TraitRef>, - pub unboxed_fn_ty_bounds: Vec<&'a ast::UnboxedFnTy>, + pub unboxed_fn_ty_bounds: Vec<&'a ast::UnboxedFnBound>, pub region_bounds: Vec<&'a ast::Lifetime>, } @@ -1574,7 +1572,7 @@ pub fn partition_bounds<'a>(tcx: &ty::ctxt, region_bounds.push(l); } ast::UnboxedFnTyParamBound(ref unboxed_function) => { - unboxed_fn_ty_bounds.push(unboxed_function); + unboxed_fn_ty_bounds.push(&**unboxed_function); } } } diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 5d2ce7b080e..7d28a63d935 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -90,8 +90,8 @@ use middle::typeck::check::{FnCtxt, PreferMutLvalue, impl_self_ty}; use middle::typeck::check; use middle::typeck::infer; use middle::typeck::MethodCallee; -use middle::typeck::{MethodOrigin, MethodParam}; -use middle::typeck::{MethodStatic, MethodStaticUnboxedClosure, MethodObject}; +use middle::typeck::{MethodOrigin, MethodParam, MethodTypeParam}; +use middle::typeck::{MethodStatic, MethodStaticUnboxedClosure, MethodObject, MethodTraitObject}; use middle::typeck::check::regionmanip::replace_late_bound_regions_in_fn_sig; use middle::typeck::TypeAndSubsts; use util::common::indenter; @@ -636,7 +636,7 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> { rcvr_match_condition: RcvrMatchesIfObject(did), rcvr_substs: new_trait_ref.substs.clone(), method_ty: Rc::new(m), - origin: MethodObject(MethodObject { + origin: MethodTraitObject(MethodObject { trait_ref: new_trait_ref, object_trait_id: did, method_num: method_num, @@ -702,7 +702,7 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> { rcvr_match_condition: condition, rcvr_substs: trait_ref.substs.clone(), method_ty: m, - origin: MethodParam(MethodParam { + origin: MethodTypeParam(MethodParam { trait_ref: trait_ref, method_num: method_num, }) @@ -874,7 +874,7 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> { } let (self_ty, auto_deref_ref) = self.consider_reborrow(self_ty, autoderefs); - let adjustment = Some((self.self_expr.unwrap().id, ty::AutoDerefRef(auto_deref_ref))); + let adjustment = Some((self.self_expr.unwrap().id, ty::AdjustDerefRef(auto_deref_ref))); match self.search_for_method(self_ty) { None => None, @@ -1159,7 +1159,7 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> { self.fcx.write_adjustment( self_expr_id, self.span, - ty::AutoDerefRef(ty::AutoDerefRef { + ty::AdjustDerefRef(ty::AutoDerefRef { autoderefs: autoderefs, autoref: Some(kind(region, *mutbl)) })); @@ -1245,7 +1245,7 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> { candidate_a.repr(self.tcx()), candidate_b.repr(self.tcx())); match (&candidate_a.origin, &candidate_b.origin) { - (&MethodParam(ref p1), &MethodParam(ref p2)) => { + (&MethodTypeParam(ref p1), &MethodTypeParam(ref p2)) => { let same_trait = p1.trait_ref.def_id == p2.trait_ref.def_id; let same_method = @@ -1330,7 +1330,7 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> { let fn_sig = &bare_fn_ty.sig; let inputs = match candidate.origin { - MethodObject(..) => { + MethodTraitObject(..) => { // For annoying reasons, we've already handled the // substitution of self for object calls. let args = fn_sig.inputs.slice_from(1).iter().map(|t| { @@ -1403,11 +1403,11 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> { match candidate.origin { MethodStatic(..) | - MethodParam(..) | + MethodTypeParam(..) | MethodStaticUnboxedClosure(..) => { return; // not a call to a trait instance } - MethodObject(..) => {} + MethodTraitObject(..) => {} } match candidate.method_ty.explicit_self { @@ -1463,8 +1463,8 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> { MethodStaticUnboxedClosure(_) => bad = false, // FIXME: does this properly enforce this on everything now // that self has been merged in? -sully - MethodParam(MethodParam { trait_ref: ref trait_ref, .. }) | - MethodObject(MethodObject { trait_ref: ref trait_ref, .. }) => { + MethodTypeParam(MethodParam { trait_ref: ref trait_ref, .. }) | + MethodTraitObject(MethodObject { trait_ref: ref trait_ref, .. }) => { bad = self.tcx().destructor_for_type.borrow() .contains_key(&trait_ref.def_id); } @@ -1612,10 +1612,10 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> { MethodStaticUnboxedClosure(did) => { self.report_static_candidate(idx, did) } - MethodParam(ref mp) => { + MethodTypeParam(ref mp) => { self.report_param_candidate(idx, mp.trait_ref.def_id) } - MethodObject(ref mo) => { + MethodTraitObject(ref mo) => { self.report_trait_candidate(idx, mo.trait_ref.def_id) } } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index c8728d375f6..a8b2e0bbff2 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -79,7 +79,6 @@ type parameter). use middle::const_eval; use middle::def; -use middle::freevars; use middle::lang_items::IteratorItem; use middle::mem_categorization::McResult; use middle::mem_categorization; @@ -110,7 +109,7 @@ use middle::typeck::rscope::RegionScope; use middle::typeck::{lookup_def_ccx}; use middle::typeck::no_params; use middle::typeck::{require_same_types}; -use middle::typeck::{MethodCall, MethodMap, ObjectCastMap}; +use middle::typeck::{MethodCall, MethodCallee, MethodMap, ObjectCastMap}; use middle::typeck::{TypeAndSubsts}; use middle::typeck; use middle::lang_items::TypeIdLangItem; @@ -124,7 +123,6 @@ use std::cell::{Cell, RefCell}; use std::collections::HashMap; use std::mem::replace; use std::rc::Rc; -use std::slice; use syntax::abi; use syntax::ast::{ProvidedMethod, RequiredMethod, TypeTraitItem}; use syntax::ast; @@ -318,7 +316,7 @@ impl<'a, 'tcx> mem_categorization::Typer<'tcx> for FnCtxt<'a, 'tcx> { self.ccx.tcx.upvar_borrow(upvar_id) } fn capture_mode(&self, closure_expr_id: ast::NodeId) - -> freevars::CaptureMode { + -> ast::CaptureClause { self.ccx.tcx.capture_mode(closure_expr_id) } fn unboxed_closures<'a>(&'a self) @@ -1704,7 +1702,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.write_adjustment( node_id, span, - ty::AutoDerefRef(ty::AutoDerefRef { + ty::AdjustDerefRef(ty::AutoDerefRef { autoderefs: derefs, autoref: None }) ); @@ -1730,8 +1728,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, adj: &ty::AutoAdjustment) { match *adj { - ty::AutoAddEnv(..) => { } - ty::AutoDerefRef(ref d_r) => { + ty::AdjustAddEnv(..) => { } + ty::AdjustDerefRef(ref d_r) => { match d_r.autoref { Some(ref a_r) => { self.register_autoref_obligations(span, a_r); @@ -2188,12 +2186,12 @@ pub fn autoderef<T>(fcx: &FnCtxt, sp: Span, base_ty: ty::t, } /// Attempts to resolve a call expression as an overloaded call. -fn try_overloaded_call(fcx: &FnCtxt, - call_expression: &ast::Expr, - callee: &ast::Expr, - callee_type: ty::t, - args: &[P<ast::Expr>]) - -> bool { +fn try_overloaded_call<'a>(fcx: &FnCtxt, + call_expression: &ast::Expr, + callee: &ast::Expr, + callee_type: ty::t, + args: &[&'a P<ast::Expr>]) + -> bool { // Bail out if the callee is a bare function or a closure. We check those // manually. match *structure_of(fcx, callee.span, callee_type) { @@ -2276,18 +2274,125 @@ fn try_overloaded_deref(fcx: &FnCtxt, (method, _) => method }; + make_return_type(fcx, method_call, method) +} + +fn get_method_ty(method: &Option<MethodCallee>) -> ty::t { + match method { + &Some(ref method) => method.ty, + &None => ty::mk_err() + } +} + +fn make_return_type(fcx: &FnCtxt, + method_call: Option<MethodCall>, + method: Option<MethodCallee>) + -> Option<ty::mt> { match method { Some(method) => { let ref_ty = ty::ty_fn_ret(method.ty); match method_call { Some(method_call) => { - fcx.inh.method_map.borrow_mut().insert(method_call, method); + fcx.inh.method_map.borrow_mut().insert(method_call, + method); } None => {} } ty::deref(ref_ty, true) } - None => None + None => None, + } +} + +fn try_overloaded_slice(fcx: &FnCtxt, + method_call: Option<MethodCall>, + expr: &ast::Expr, + base_expr: &ast::Expr, + base_ty: ty::t, + start_expr: &Option<P<ast::Expr>>, + end_expr: &Option<P<ast::Expr>>, + mutbl: &ast::Mutability) + -> Option<ty::mt> { + let method = if mutbl == &ast::MutMutable { + // Try `SliceMut` first, if preferred. + match fcx.tcx().lang_items.slice_mut_trait() { + Some(trait_did) => { + let method_name = match (start_expr, end_expr) { + (&Some(_), &Some(_)) => "slice_mut_", + (&Some(_), &None) => "slice_from_mut_", + (&None, &Some(_)) => "slice_to_mut_", + (&None, &None) => "as_mut_slice_", + }; + + method::lookup_in_trait(fcx, + expr.span, + Some(&*base_expr), + token::intern(method_name), + trait_did, + base_ty, + [], + DontAutoderefReceiver, + IgnoreStaticMethods) + } + _ => None, + } + } else { + // Otherwise, fall back to `Slice`. + // FIXME(#17293) this will not coerce base_expr, so we miss the Slice + // trait for `&mut [T]`. + match fcx.tcx().lang_items.slice_trait() { + Some(trait_did) => { + let method_name = match (start_expr, end_expr) { + (&Some(_), &Some(_)) => "slice_", + (&Some(_), &None) => "slice_from_", + (&None, &Some(_)) => "slice_to_", + (&None, &None) => "as_slice_", + }; + + method::lookup_in_trait(fcx, + expr.span, + Some(&*base_expr), + token::intern(method_name), + trait_did, + base_ty, + [], + DontAutoderefReceiver, + IgnoreStaticMethods) + } + _ => None, + } + }; + + + // Regardless of whether the lookup succeeds, check the method arguments + // so that we have *some* type for each argument. + let method_type = get_method_ty(&method); + + let mut args = vec![]; + start_expr.as_ref().map(|x| args.push(x)); + end_expr.as_ref().map(|x| args.push(x)); + + check_method_argument_types(fcx, + expr.span, + method_type, + expr, + args.as_slice(), + DoDerefArgs, + DontTupleArguments); + + match method { + Some(method) => { + let result_ty = ty::ty_fn_ret(method.ty); + match method_call { + Some(method_call) => { + fcx.inh.method_map.borrow_mut().insert(method_call, + method); + } + None => {} + } + Some(ty::mt { ty: result_ty, mutbl: ast::MutImmutable }) + } + None => None, } } @@ -2333,32 +2438,16 @@ fn try_overloaded_index(fcx: &FnCtxt, // Regardless of whether the lookup succeeds, check the method arguments // so that we have *some* type for each argument. - let method_type = match method { - Some(ref method) => method.ty, - None => ty::mk_err() - }; + let method_type = get_method_ty(&method); check_method_argument_types(fcx, expr.span, method_type, expr, - slice::ref_slice(index_expr), + &[index_expr], DoDerefArgs, DontTupleArguments); - match method { - Some(method) => { - let ref_ty = ty::ty_fn_ret(method.ty); - match method_call { - Some(method_call) => { - fcx.inh.method_map.borrow_mut().insert(method_call, - method); - } - None => {} - } - ty::deref(ref_ty, true) - } - None => None, - } + make_return_type(fcx, method_call, method) } /// Given the head of a `for` expression, looks up the `next` method in the @@ -2442,14 +2531,14 @@ fn lookup_method_for_for_loop(fcx: &FnCtxt, } } -fn check_method_argument_types(fcx: &FnCtxt, - sp: Span, - method_fn_ty: ty::t, - callee_expr: &ast::Expr, - args_no_rcvr: &[P<ast::Expr>], - deref_args: DerefArgs, - tuple_arguments: TupleArgumentsFlag) - -> ty::t { +fn check_method_argument_types<'a>(fcx: &FnCtxt, + sp: Span, + method_fn_ty: ty::t, + callee_expr: &ast::Expr, + args_no_rcvr: &[&'a P<ast::Expr>], + deref_args: DerefArgs, + tuple_arguments: TupleArgumentsFlag) + -> ty::t { if ty::type_is_error(method_fn_ty) { let err_inputs = err_args(args_no_rcvr.len()); check_argument_types(fcx, @@ -2483,14 +2572,14 @@ fn check_method_argument_types(fcx: &FnCtxt, } } -fn check_argument_types(fcx: &FnCtxt, - sp: Span, - fn_inputs: &[ty::t], - _callee_expr: &ast::Expr, - args: &[P<ast::Expr>], - deref_args: DerefArgs, - variadic: bool, - tuple_arguments: TupleArgumentsFlag) { +fn check_argument_types<'a>(fcx: &FnCtxt, + sp: Span, + fn_inputs: &[ty::t], + _callee_expr: &ast::Expr, + args: &[&'a P<ast::Expr>], + deref_args: DerefArgs, + variadic: bool, + tuple_arguments: TupleArgumentsFlag) { /*! * * Generic function that factors out common logic from @@ -2627,7 +2716,7 @@ fn check_argument_types(fcx: &FnCtxt, DontDerefArgs => {} } - check_expr_coercable_to_type(fcx, &**arg, formal_ty); + check_expr_coercable_to_type(fcx, &***arg, formal_ty); } } } @@ -2636,12 +2725,12 @@ fn check_argument_types(fcx: &FnCtxt, // arguments which we skipped above. if variadic { for arg in args.iter().skip(expected_arg_count) { - check_expr(fcx, &**arg); + check_expr(fcx, &***arg); // There are a few types which get autopromoted when passed via varargs // in C but we just error out instead and require explicit casts. let arg_ty = structurally_resolved_type(fcx, arg.span, - fcx.expr_ty(&**arg)); + fcx.expr_ty(&***arg)); match ty::get(arg_ty).sty { ty::ty_float(ast::TyF32) => { fcx.type_error_message(arg.span, @@ -2877,10 +2966,10 @@ fn check_expr_with_unifier(fcx: &FnCtxt, expr.repr(fcx.tcx()), expected.repr(fcx.tcx())); // A generic function for doing all of the checking for call expressions - fn check_call(fcx: &FnCtxt, - call_expr: &ast::Expr, - f: &ast::Expr, - args: &[P<ast::Expr>]) { + fn check_call<'a>(fcx: &FnCtxt, + call_expr: &ast::Expr, + f: &ast::Expr, + args: &[&'a P<ast::Expr>]) { // Store the type of `f` as the type of the callee let fn_ty = fcx.expr_ty(f); @@ -2990,11 +3079,12 @@ fn check_expr_with_unifier(fcx: &FnCtxt, }; // Call the generic checker. + let args: Vec<_> = args.slice_from(1).iter().map(|x| x).collect(); let ret_ty = check_method_argument_types(fcx, method_name.span, fn_ty, expr, - args.slice_from(1), + args.as_slice(), DontDerefArgs, DontTupleArguments); @@ -3085,12 +3175,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt, None => None }; let args = match rhs { - Some(rhs) => slice::ref_slice(rhs), - None => { - // Work around the lack of coercion. - let empty: &[_] = &[]; - empty - } + Some(rhs) => vec![rhs], + None => vec![] }; match method { Some(method) => { @@ -3102,7 +3188,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt, op_ex.span, method_ty, op_ex, - args, + args.as_slice(), DoDerefArgs, DontTupleArguments) } @@ -3115,7 +3201,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt, op_ex.span, expected_ty, op_ex, - args, + args.as_slice(), DoDerefArgs, DontTupleArguments); ty::mk_err() @@ -4136,12 +4222,13 @@ fn check_expr_with_unifier(fcx: &FnCtxt, check_expr(fcx, &**f); let f_ty = fcx.expr_ty(&**f); + let args: Vec<_> = args.iter().map(|x| x).collect(); if !try_overloaded_call(fcx, expr, &**f, f_ty, args.as_slice()) { check_call(fcx, expr, &**f, args.as_slice()); let (args_bot, args_err) = args.iter().fold((false, false), |(rest_bot, rest_err), a| { // is this not working? - let a_ty = fcx.expr_ty(&**a); + let a_ty = fcx.expr_ty(&***a); (rest_bot || ty::type_is_bot(a_ty), rest_err || ty::type_is_error(a_ty))}); if ty::type_is_error(f_ty) || args_err { @@ -4427,6 +4514,61 @@ fn check_expr_with_unifier(fcx: &FnCtxt, } } } + ast::ExprSlice(ref base, ref start, ref end, ref mutbl) => { + check_expr_with_lvalue_pref(fcx, &**base, lvalue_pref); + let raw_base_t = fcx.expr_ty(&**base); + + let mut some_err = false; + if ty::type_is_error(raw_base_t) || ty::type_is_bot(raw_base_t) { + fcx.write_ty(id, raw_base_t); + some_err = true; + } + + { + let check_slice_idx = |e: &ast::Expr| { + check_expr(fcx, e); + let e_t = fcx.expr_ty(e); + if ty::type_is_error(e_t) || ty::type_is_bot(e_t) { + fcx.write_ty(id, e_t); + some_err = true; + } + }; + start.as_ref().map(|e| check_slice_idx(&**e)); + end.as_ref().map(|e| check_slice_idx(&**e)); + } + + if !some_err { + let base_t = structurally_resolved_type(fcx, + expr.span, + raw_base_t); + let method_call = MethodCall::expr(expr.id); + match try_overloaded_slice(fcx, + Some(method_call), + expr, + &**base, + base_t, + start, + end, + mutbl) { + Some(mt) => fcx.write_ty(id, mt.ty), + None => { + fcx.type_error_message(expr.span, + |actual| { + format!("cannot take a {}slice of a value with type `{}`", + if mutbl == &ast::MutMutable { + "mutable " + } else { + "" + }, + actual) + }, + base_t, + None); + fcx.write_ty(id, ty::mk_err()) + } + } + } + } } debug!("type of expr({}) {} is...", expr.id, @@ -5027,8 +5169,7 @@ pub fn polytype_for_def(fcx: &FnCtxt, defn: def::Def) -> Polytype { match defn { - def::DefArg(nid, _) | def::DefLocal(nid, _) | - def::DefBinding(nid, _) => { + def::DefLocal(nid) | def::DefUpvar(nid, _, _) => { let typ = fcx.local_ty(sp, nid); return no_params(typ); } @@ -5037,9 +5178,6 @@ pub fn polytype_for_def(fcx: &FnCtxt, def::DefStruct(id) => { return ty::lookup_item_type(fcx.ccx.tcx, id); } - def::DefUpvar(_, inner, _, _) => { - return polytype_for_def(fcx, sp, *inner); - } def::DefTrait(_) | def::DefTy(..) | def::DefAssociatedTy(..) | @@ -5183,10 +5321,8 @@ pub fn instantiate_path(fcx: &FnCtxt, // elsewhere. (I hope) def::DefMod(..) | def::DefForeignMod(..) | - def::DefArg(..) | def::DefLocal(..) | def::DefMethod(..) | - def::DefBinding(..) | def::DefUse(..) | def::DefRegion(..) | def::DefLabel(..) | diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index a8f2a8f6f1d..d0791191c0f 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -119,8 +119,6 @@ and report an error, and it just seems like more mess in the end.) */ use middle::def; -use middle::def::{DefArg, DefBinding, DefLocal, DefUpvar}; -use middle::freevars; use middle::mem_categorization as mc; use middle::ty::{ReScope}; use middle::ty; @@ -243,14 +241,14 @@ fn region_of_def(fcx: &FnCtxt, def: def::Def) -> ty::Region { let tcx = fcx.tcx(); match def { - DefLocal(node_id, _) | DefArg(node_id, _) | - DefBinding(node_id, _) => { + def::DefLocal(node_id) => { tcx.region_maps.var_region(node_id) } - DefUpvar(_, subdef, closure_id, body_id) => { - match ty::ty_closure_store(fcx.node_ty(closure_id)) { - ty::RegionTraitStore(..) => region_of_def(fcx, *subdef), - ty::UniqTraitStore => ReScope(body_id) + def::DefUpvar(node_id, _, body_id) => { + if body_id == ast::DUMMY_NODE_ID { + tcx.region_maps.var_region(node_id) + } else { + ReScope(body_id) } } _ => { @@ -479,7 +477,7 @@ impl<'fcx, 'tcx> mc::Typer<'tcx> for Rcx<'fcx, 'tcx> { } fn capture_mode(&self, closure_expr_id: ast::NodeId) - -> freevars::CaptureMode { + -> ast::CaptureClause { self.tcx().capture_modes.borrow().get_copy(&closure_expr_id) } @@ -592,7 +590,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) { for &adjustment in rcx.fcx.inh.adjustments.borrow().find(&expr.id).iter() { debug!("adjustment={:?}", adjustment); match *adjustment { - ty::AutoDerefRef(ty::AutoDerefRef {autoderefs, autoref: ref opt_autoref}) => { + ty::AdjustDerefRef(ty::AutoDerefRef {autoderefs, autoref: ref opt_autoref}) => { let expr_ty = rcx.resolve_node_type(expr.id); constrain_autoderefs(rcx, expr, autoderefs, expr_ty); for autoref in opt_autoref.iter() { @@ -852,7 +850,7 @@ fn check_expr_fn_block(rcx: &mut Rcx, ..}) => { // For closure, ensure that the variables outlive region // bound, since they are captured by reference. - freevars::with_freevars(tcx, expr.id, |freevars| { + ty::with_freevars(tcx, expr.id, |freevars| { if freevars.is_empty() { // No free variables means that the environment // will be NULL at runtime and hence the closure @@ -875,13 +873,13 @@ fn check_expr_fn_block(rcx: &mut Rcx, ..}) => { // For proc, ensure that the *types* of the variables // outlive region bound, since they are captured by value. - freevars::with_freevars(tcx, expr.id, |freevars| { + ty::with_freevars(tcx, expr.id, |freevars| { ensure_free_variable_types_outlive_closure_bound( rcx, bounds.region_bound, expr, freevars); }); } ty::ty_unboxed_closure(_, region) => { - freevars::with_freevars(tcx, expr.id, |freevars| { + ty::with_freevars(tcx, expr.id, |freevars| { // No free variables means that there is no environment and // hence the closure has static lifetime. Otherwise, the // closure must not outlive the variables it closes over @@ -907,7 +905,7 @@ fn check_expr_fn_block(rcx: &mut Rcx, store: ty::RegionTraitStore(..), .. }) => { - freevars::with_freevars(tcx, expr.id, |freevars| { + ty::with_freevars(tcx, expr.id, |freevars| { propagate_upupvar_borrow_kind(rcx, expr, freevars); }) } @@ -918,7 +916,7 @@ fn check_expr_fn_block(rcx: &mut Rcx, rcx: &mut Rcx, region_bound: ty::Region, expr: &ast::Expr, - freevars: &[freevars::freevar_entry]) + freevars: &[ty::Freevar]) { /*! * Make sure that the type of all free variables referenced @@ -951,7 +949,7 @@ fn check_expr_fn_block(rcx: &mut Rcx, rcx: &mut Rcx, region_bound: ty::Region, expr: &ast::Expr, - freevars: &[freevars::freevar_entry]) + freevars: &[ty::Freevar]) { /*! * Make sure that all free variables referenced inside the @@ -1001,7 +999,7 @@ fn check_expr_fn_block(rcx: &mut Rcx, fn propagate_upupvar_borrow_kind(rcx: &mut Rcx, expr: &ast::Expr, - freevars: &[freevars::freevar_entry]) { + freevars: &[ty::Freevar]) { let tcx = rcx.fcx.ccx.tcx; debug!("propagate_upupvar_borrow_kind({})", expr.repr(tcx)); for freevar in freevars.iter() { @@ -1031,7 +1029,7 @@ fn check_expr_fn_block(rcx: &mut Rcx, // determining the final borrow_kind) and propagate that as // a constraint on the outer closure. match freevar.def { - def::DefUpvar(var_id, _, outer_closure_id, _) => { + def::DefUpvar(var_id, outer_closure_id, _) => { // thing being captured is itself an upvar: let outer_upvar_id = ty::UpvarId { var_id: var_id, @@ -1475,7 +1473,6 @@ fn link_region(rcx: &Rcx, mc::cat_static_item | mc::cat_copied_upvar(..) | mc::cat_local(..) | - mc::cat_arg(..) | mc::cat_upvar(..) | mc::cat_rvalue(..) => { // These are all "base cases" with independent lifetimes @@ -1701,7 +1698,6 @@ fn adjust_upvar_borrow_kind_for_mut(rcx: &Rcx, mc::cat_rvalue(_) | mc::cat_copied_upvar(_) | mc::cat_local(_) | - mc::cat_arg(_) | mc::cat_upvar(..) => { return; } @@ -1753,7 +1749,6 @@ fn adjust_upvar_borrow_kind_for_unique(rcx: &Rcx, cmt: mc::cmt) { mc::cat_rvalue(_) | mc::cat_copied_upvar(_) | mc::cat_local(_) | - mc::cat_arg(_) | mc::cat_upvar(..) => { return; } diff --git a/src/librustc/middle/typeck/check/vtable2.rs b/src/librustc/middle/typeck/check/vtable2.rs index f75d2622fdb..0022efd845e 100644 --- a/src/librustc/middle/typeck/check/vtable2.rs +++ b/src/librustc/middle/typeck/check/vtable2.rs @@ -13,7 +13,7 @@ use middle::traits; use middle::traits::{SelectionError, Overflow, OutputTypeParameterMismatch, Unimplemented}; use middle::traits::{Obligation, obligation_for_builtin_bound}; -use middle::traits::{FulfillmentError, Ambiguity}; +use middle::traits::{FulfillmentError, CodeSelectionError, CodeAmbiguity}; use middle::traits::{ObligationCause}; use middle::ty; use middle::typeck::check::{FnCtxt, @@ -244,10 +244,10 @@ pub fn report_fulfillment_errors(fcx: &FnCtxt, pub fn report_fulfillment_error(fcx: &FnCtxt, error: &FulfillmentError) { match error.code { - SelectionError(ref e) => { + CodeSelectionError(ref e) => { report_selection_error(fcx, &error.obligation, e); } - Ambiguity => { + CodeAmbiguity => { maybe_report_ambiguity(fcx, &error.obligation); } } diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs index ffe019b314a..e2a04116f90 100644 --- a/src/librustc/middle/typeck/check/writeback.rs +++ b/src/librustc/middle/typeck/check/writeback.rs @@ -282,7 +282,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { Some(adjustment) => { let adj_object = ty::adjust_is_object(&adjustment); let resolved_adjustment = match adjustment { - ty::AutoAddEnv(store) => { + ty::AdjustAddEnv(store) => { // FIXME(eddyb) #2190 Allow only statically resolved // bare functions to coerce to a closure to avoid // constructing (slower) indirect call wrappers. @@ -298,10 +298,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } } - ty::AutoAddEnv(self.resolve(&store, reason)) + ty::AdjustAddEnv(self.resolve(&store, reason)) } - ty::AutoDerefRef(adj) => { + ty::AdjustDerefRef(adj) => { for autoderef in range(0, adj.autoderefs) { let method_call = MethodCall::autoderef(id, autoderef); self.visit_method_map_entry(reason, method_call); @@ -312,7 +312,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { self.visit_method_map_entry(reason, method_call); } - ty::AutoDerefRef(ty::AutoDerefRef { + ty::AdjustDerefRef(ty::AutoDerefRef { autoderefs: adj.autoderefs, autoref: self.resolve(&adj.autoref, reason), }) diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index b7aa7656ae9..40c52fd36b9 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -1427,7 +1427,8 @@ pub fn instantiate_unboxed_fn_ty<'tcx,AC>(this: &AC, let param_ty = param_ty.to_ty(this.tcx()); Rc::new(astconv::trait_ref_for_unboxed_function(this, &rscope, - unboxed_function, + unboxed_function.kind, + &*unboxed_function.decl, Some(param_ty))) } @@ -2165,9 +2166,42 @@ fn conv_param_bounds<'tcx,AC>(this: &AC, region_bounds, unboxed_fn_ty_bounds } = astconv::partition_bounds(this.tcx(), span, all_bounds.as_slice()); - let unboxed_fn_ty_bounds = - unboxed_fn_ty_bounds.into_iter() - .map(|b| instantiate_unboxed_fn_ty(this, b, param_ty)); + + let unboxed_fn_ty_bounds = unboxed_fn_ty_bounds.move_iter().map(|b| { + let trait_id = this.tcx().def_map.borrow().get(&b.ref_id).def_id(); + let mut kind = None; + for &(lang_item, this_kind) in [ + (this.tcx().lang_items.fn_trait(), ast::FnUnboxedClosureKind), + (this.tcx().lang_items.fn_mut_trait(), + ast::FnMutUnboxedClosureKind), + (this.tcx().lang_items.fn_once_trait(), + ast::FnOnceUnboxedClosureKind) + ].iter() { + if Some(trait_id) == lang_item { + kind = Some(this_kind); + break + } + } + + let kind = match kind { + Some(kind) => kind, + None => { + this.tcx().sess.span_err(b.path.span, + "unboxed function trait must be one \ + of `Fn`, `FnMut`, or `FnOnce`"); + ast::FnMutUnboxedClosureKind + } + }; + + let rscope = ExplicitRscope; + let param_ty = param_ty.to_ty(this.tcx()); + Rc::new(astconv::trait_ref_for_unboxed_function(this, + &rscope, + kind, + &*b.decl, + Some(param_ty))) + }); + let trait_bounds: Vec<Rc<ty::TraitRef>> = trait_bounds.into_iter() .map(|b| { diff --git a/src/librustc/middle/typeck/infer/coercion.rs b/src/librustc/middle/typeck/infer/coercion.rs index e0a35dc72a3..7f9f569c37e 100644 --- a/src/librustc/middle/typeck/infer/coercion.rs +++ b/src/librustc/middle/typeck/infer/coercion.rs @@ -65,7 +65,7 @@ we may want to adjust precisely when coercions occur. */ use middle::subst; -use middle::ty::{AutoPtr, AutoDerefRef, AutoUnsize, AutoUnsafe}; +use middle::ty::{AutoPtr, AutoDerefRef, AdjustDerefRef, AutoUnsize, AutoUnsafe}; use middle::ty::{mt}; use middle::ty; use middle::typeck::infer::{CoerceResult, resolve_type, Coercion}; @@ -270,7 +270,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { mt {ty: inner_ty, mutbl: mutbl_b}); try!(sub.tys(a_borrowed, b)); - Ok(Some(AutoDerefRef(AutoDerefRef { + Ok(Some(AdjustDerefRef(AutoDerefRef { autoderefs: 1, autoref: Some(AutoPtr(r_borrow, mutbl_b, None)) }))) @@ -295,7 +295,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { let unsized_ty = ty::mk_slice(self.get_ref().infcx.tcx, r_borrow, mt {ty: t_a, mutbl: mutbl_b}); try!(self.get_ref().infcx.try(|| sub.tys(unsized_ty, b))); - Ok(Some(AutoDerefRef(AutoDerefRef { + Ok(Some(AdjustDerefRef(AutoDerefRef { autoderefs: 0, autoref: Some(ty::AutoPtr(r_borrow, mutbl_b, @@ -343,7 +343,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { try!(self.get_ref().infcx.try(|| sub.tys(ty, b))); debug!("Success, coerced with AutoDerefRef(1, \ AutoPtr(AutoUnsize({:?})))", kind); - Ok(Some(AutoDerefRef(AutoDerefRef { + Ok(Some(AdjustDerefRef(AutoDerefRef { autoderefs: 1, autoref: Some(ty::AutoPtr(r_borrow, mt_b.mutbl, Some(box AutoUnsize(kind)))) @@ -366,7 +366,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { try!(self.get_ref().infcx.try(|| sub.tys(ty, b))); debug!("Success, coerced with AutoDerefRef(1, \ AutoPtr(AutoUnsize({:?})))", kind); - Ok(Some(AutoDerefRef(AutoDerefRef { + Ok(Some(AdjustDerefRef(AutoDerefRef { autoderefs: 1, autoref: Some(ty::AutoUnsafe(mt_b.mutbl, Some(box AutoUnsize(kind)))) @@ -384,7 +384,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { try!(self.get_ref().infcx.try(|| sub.tys(ty, b))); debug!("Success, coerced with AutoDerefRef(1, \ AutoUnsizeUniq({:?}))", kind); - Ok(Some(AutoDerefRef(AutoDerefRef { + Ok(Some(AdjustDerefRef(AutoDerefRef { autoderefs: 1, autoref: Some(ty::AutoUnsizeUniq(kind)) }))) @@ -537,7 +537,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { let tr = ty::mk_trait(tcx, def_id, substs.clone(), bounds); try!(self.subtype(mk_ty(tr), b)); - Ok(Some(AutoDerefRef(AutoDerefRef { + Ok(Some(AdjustDerefRef(AutoDerefRef { autoderefs: 1, autoref: Some(mk_adjust()) }))) @@ -593,7 +593,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { _ => return self.subtype(a, b) }; - let adj = ty::AutoAddEnv(fn_ty_b.store); + let adj = ty::AdjustAddEnv(fn_ty_b.store); let a_closure = ty::mk_closure(self.get_ref().infcx.tcx, ty::ClosureTy { sig: fn_ty_a.sig.clone(), @@ -630,7 +630,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // Although references and unsafe ptrs have the same // representation, we still register an AutoDerefRef so that // regionck knows that the region for `a` must be valid here. - Ok(Some(AutoDerefRef(AutoDerefRef { + Ok(Some(AdjustDerefRef(AutoDerefRef { autoderefs: 1, autoref: Some(ty::AutoUnsafe(mutbl_b, None)) }))) diff --git a/src/librustc/middle/typeck/infer/test.rs b/src/librustc/middle/typeck/infer/test.rs index c0236cefca3..29cd2e77e8b 100644 --- a/src/librustc/middle/typeck/infer/test.rs +++ b/src/librustc/middle/typeck/infer/test.rs @@ -22,7 +22,6 @@ use driver::diagnostic; use driver::diagnostic::Emitter; use driver::driver; use driver::session; -use middle::freevars; use middle::lang_items; use middle::region; use middle::resolve; @@ -125,10 +124,8 @@ fn test_env(_test_name: &str, // run just enough stuff to build a tcx: let lang_items = lang_items::collect_language_items(krate, &sess); - let resolve::CrateMap { def_map: def_map, .. } = + let resolve::CrateMap { def_map, freevars, capture_mode_map, .. } = resolve::resolve_crate(&sess, &lang_items, krate); - let (freevars_map, captures_map) = freevars::annotate_freevars(&def_map, - krate); let named_region_map = resolve_lifetime::krate(&sess, krate); let region_map = region::resolve_crate(&sess, krate); let stability_index = stability::Index::build(krate); @@ -138,8 +135,8 @@ fn test_env(_test_name: &str, def_map, named_region_map, ast_map, - freevars_map, - captures_map, + freevars, + capture_mode_map, region_map, lang_items, stability_index); diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs index 7a913699280..e93ad056051 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -102,10 +102,10 @@ pub enum MethodOrigin { MethodStaticUnboxedClosure(ast::DefId), // method invoked on a type parameter with a bounded trait - MethodParam(MethodParam), + MethodTypeParam(MethodParam), // method invoked on a trait instance - MethodObject(MethodObject), + MethodTraitObject(MethodObject), } diff --git a/src/librustc/plugin/registry.rs b/src/librustc/plugin/registry.rs index be31e81d29b..88e6f0ad186 100644 --- a/src/librustc/plugin/registry.rs +++ b/src/librustc/plugin/registry.rs @@ -13,7 +13,7 @@ use lint::{LintPassObject, LintId, Lint}; use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT}; -use syntax::ext::base::{IdentTT, LetSyntaxTT, ItemDecorator, ItemModifier}; +use syntax::ext::base::{IdentTT, LetSyntaxTT, Decorator, Modifier}; use syntax::ext::base::{MacroExpanderFn}; use syntax::codemap::Span; use syntax::parse::token; @@ -61,8 +61,8 @@ impl Registry { self.syntax_exts.push((name, match extension { NormalTT(ext, _) => NormalTT(ext, Some(self.krate_span)), IdentTT(ext, _) => IdentTT(ext, Some(self.krate_span)), - ItemDecorator(ext) => ItemDecorator(ext), - ItemModifier(ext) => ItemModifier(ext), + Decorator(ext) => Decorator(ext), + Modifier(ext) => Modifier(ext), // there's probably a nicer way to signal this: LetSyntaxTT(_, _) => fail!("can't register a new LetSyntax!"), })); diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 2083aa52bec..5b83f024309 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -962,10 +962,10 @@ impl Repr for typeck::MethodOrigin { &typeck::MethodStaticUnboxedClosure(def_id) => { format!("MethodStaticUnboxedClosure({})", def_id.repr(tcx)) } - &typeck::MethodParam(ref p) => { + &typeck::MethodTypeParam(ref p) => { p.repr(tcx) } - &typeck::MethodObject(ref p) => { + &typeck::MethodTraitObject(ref p) => { p.repr(tcx) } } diff --git a/src/librustc_back/svh.rs b/src/librustc_back/svh.rs index 415141c0b94..f98a2dac084 100644 --- a/src/librustc_back/svh.rs +++ b/src/librustc_back/svh.rs @@ -245,6 +245,7 @@ mod svh_visitor { SawExprAssign, SawExprAssignOp(ast::BinOp), SawExprIndex, + SawExprSlice, SawExprPath, SawExprAddrOf(ast::Mutability), SawExprRet, @@ -279,6 +280,7 @@ mod svh_visitor { ExprField(_, id, _) => SawExprField(content(id.node)), ExprTupField(_, id, _) => SawExprTupField(id.node), ExprIndex(..) => SawExprIndex, + ExprSlice(..) => SawExprSlice, ExprPath(..) => SawExprPath, ExprAddrOf(m, _) => SawExprAddrOf(m), ExprBreak(id) => SawExprBreak(id.map(content)), diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 690b288043d..22e7ec6124f 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -91,34 +91,35 @@ pub enum DiagnosticSeverity { Note, } -#[deriving(Clone)] -pub enum Attribute { - ZExtAttribute = 1 << 0, - SExtAttribute = 1 << 1, - NoReturnAttribute = 1 << 2, - InRegAttribute = 1 << 3, - StructRetAttribute = 1 << 4, - NoUnwindAttribute = 1 << 5, - NoAliasAttribute = 1 << 6, - ByValAttribute = 1 << 7, - NestAttribute = 1 << 8, - ReadNoneAttribute = 1 << 9, - ReadOnlyAttribute = 1 << 10, - NoInlineAttribute = 1 << 11, - AlwaysInlineAttribute = 1 << 12, - OptimizeForSizeAttribute = 1 << 13, - StackProtectAttribute = 1 << 14, - StackProtectReqAttribute = 1 << 15, - AlignmentAttribute = 31 << 16, - NoCaptureAttribute = 1 << 21, - NoRedZoneAttribute = 1 << 22, - NoImplicitFloatAttribute = 1 << 23, - NakedAttribute = 1 << 24, - InlineHintAttribute = 1 << 25, - StackAttribute = 7 << 26, - ReturnsTwiceAttribute = 1 << 29, - UWTableAttribute = 1 << 30, - NonLazyBindAttribute = 1 << 31, +bitflags! { + flags Attribute : u32 { + static ZExtAttribute = 1 << 0, + static SExtAttribute = 1 << 1, + static NoReturnAttribute = 1 << 2, + static InRegAttribute = 1 << 3, + static StructRetAttribute = 1 << 4, + static NoUnwindAttribute = 1 << 5, + static NoAliasAttribute = 1 << 6, + static ByValAttribute = 1 << 7, + static NestAttribute = 1 << 8, + static ReadNoneAttribute = 1 << 9, + static ReadOnlyAttribute = 1 << 10, + static NoInlineAttribute = 1 << 11, + static AlwaysInlineAttribute = 1 << 12, + static OptimizeForSizeAttribute = 1 << 13, + static StackProtectAttribute = 1 << 14, + static StackProtectReqAttribute = 1 << 15, + static AlignmentAttribute = 31 << 16, + static NoCaptureAttribute = 1 << 21, + static NoRedZoneAttribute = 1 << 22, + static NoImplicitFloatAttribute = 1 << 23, + static NakedAttribute = 1 << 24, + static InlineHintAttribute = 1 << 25, + static StackAttribute = 7 << 26, + static ReturnsTwiceAttribute = 1 << 29, + static UWTableAttribute = 1 << 30, + static NonLazyBindAttribute = 1 << 31, + } } #[repr(u64)] @@ -160,13 +161,13 @@ trait AttrHelper { impl AttrHelper for Attribute { fn apply_llfn(&self, idx: c_uint, llfn: ValueRef) { unsafe { - LLVMAddFunctionAttribute(llfn, idx, *self as uint64_t); + LLVMAddFunctionAttribute(llfn, idx, self.bits() as uint64_t); } } fn apply_callsite(&self, idx: c_uint, callsite: ValueRef) { unsafe { - LLVMAddCallSiteAttribute(callsite, idx, *self as uint64_t); + LLVMAddCallSiteAttribute(callsite, idx, self.bits() as uint64_t); } } } @@ -296,17 +297,17 @@ pub enum TypeKind { #[repr(C)] pub enum AtomicBinOp { - Xchg = 0, - Add = 1, - Sub = 2, - And = 3, - Nand = 4, - Or = 5, - Xor = 6, - Max = 7, - Min = 8, - UMax = 9, - UMin = 10, + AtomicXchg = 0, + AtomicAdd = 1, + AtomicSub = 2, + AtomicAnd = 3, + AtomicNand = 4, + AtomicOr = 5, + AtomicXor = 6, + AtomicMax = 7, + AtomicMin = 8, + AtomicUMax = 9, + AtomicUMin = 10, } #[repr(C)] @@ -324,11 +325,11 @@ pub enum AtomicOrdering { // Consts for the LLVMCodeGenFileType type (in include/llvm/c/TargetMachine.h) #[repr(C)] pub enum FileType { - AssemblyFile = 0, - ObjectFile = 1 + AssemblyFileType = 0, + ObjectFileType = 1 } -pub enum Metadata { +pub enum MetadataType { MD_dbg = 0, MD_tbaa = 1, MD_prof = 2, @@ -2009,7 +2010,7 @@ pub fn ConstFCmp(pred: RealPredicate, v1: ValueRef, v2: ValueRef) -> ValueRef { pub fn SetFunctionAttribute(fn_: ValueRef, attr: Attribute) { unsafe { - LLVMAddFunctionAttribute(fn_, FunctionIndex as c_uint, attr as uint64_t) + LLVMAddFunctionAttribute(fn_, FunctionIndex as c_uint, attr.bits() as uint64_t) } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 9e05382fa55..b4d44aab239 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -99,7 +99,7 @@ pub struct Crate { pub name: String, pub module: Option<Item>, pub externs: Vec<(ast::CrateNum, ExternalCrate)>, - pub primitives: Vec<Primitive>, + pub primitives: Vec<PrimitiveType>, } impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> { @@ -147,7 +147,7 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> { ModuleItem(ref mut m) => m, _ => continue, }; - let prim = match Primitive::find(child.attrs.as_slice()) { + let prim = match PrimitiveType::find(child.attrs.as_slice()) { Some(prim) => prim, None => continue, }; @@ -187,7 +187,7 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> { pub struct ExternalCrate { pub name: String, pub attrs: Vec<Attribute>, - pub primitives: Vec<Primitive>, + pub primitives: Vec<PrimitiveType>, } impl Clean<ExternalCrate> for cstore::crate_metadata { @@ -202,7 +202,7 @@ impl Clean<ExternalCrate> for cstore::crate_metadata { _ => return }; let attrs = inline::load_attrs(cx, tcx, did); - Primitive::find(attrs.as_slice()).map(|prim| primitives.push(prim)); + PrimitiveType::find(attrs.as_slice()).map(|prim| primitives.push(prim)); }) }); ExternalCrate { @@ -316,7 +316,7 @@ pub enum ItemEnum { /// `static`s from an extern block ForeignStaticItem(Static), MacroItem(Macro), - PrimitiveItem(Primitive), + PrimitiveItem(PrimitiveType), AssociatedTypeItem, } @@ -901,7 +901,7 @@ impl Clean<RetStyle> for ast::RetStyle { #[deriving(Clone, Encodable, Decodable)] pub struct Trait { - pub items: Vec<TraitItem>, + pub items: Vec<TraitMethod>, pub generics: Generics, pub bounds: Vec<TyParamBound>, } @@ -931,13 +931,13 @@ impl Clean<Type> for ast::TraitRef { } #[deriving(Clone, Encodable, Decodable)] -pub enum TraitItem { +pub enum TraitMethod { RequiredMethod(Item), ProvidedMethod(Item), TypeTraitItem(Item), } -impl TraitItem { +impl TraitMethod { pub fn is_req(&self) -> bool { match self { &RequiredMethod(..) => true, @@ -959,8 +959,8 @@ impl TraitItem { } } -impl Clean<TraitItem> for ast::TraitItem { - fn clean(&self, cx: &DocContext) -> TraitItem { +impl Clean<TraitMethod> for ast::TraitItem { + fn clean(&self, cx: &DocContext) -> TraitMethod { match self { &ast::RequiredMethod(ref t) => RequiredMethod(t.clean(cx)), &ast::ProvidedMethod(ref t) => ProvidedMethod(t.clean(cx)), @@ -970,13 +970,13 @@ impl Clean<TraitItem> for ast::TraitItem { } #[deriving(Clone, Encodable, Decodable)] -pub enum ImplItem { +pub enum ImplMethod { MethodImplItem(Item), TypeImplItem(Item), } -impl Clean<ImplItem> for ast::ImplItem { - fn clean(&self, cx: &DocContext) -> ImplItem { +impl Clean<ImplMethod> for ast::ImplItem { + fn clean(&self, cx: &DocContext) -> ImplMethod { match self { &ast::MethodImplItem(ref t) => MethodImplItem(t.clean(cx)), &ast::TypeImplItem(ref t) => TypeImplItem(t.clean(cx)), @@ -1058,7 +1058,7 @@ pub enum Type { /// For references to self Self(ast::DefId), /// Primitives are just the fixed-size numeric types (plus int/uint/float), and char. - Primitive(Primitive), + Primitive(PrimitiveType), Closure(Box<ClosureDecl>), Proc(Box<ClosureDecl>), /// extern "ABI" fn @@ -1080,7 +1080,7 @@ pub enum Type { } #[deriving(Clone, Encodable, Decodable, PartialEq, Eq, Hash)] -pub enum Primitive { +pub enum PrimitiveType { Int, I8, I16, I32, I64, Uint, U8, U16, U32, U64, F32, F64, @@ -1104,8 +1104,8 @@ pub enum TypeKind { TypeTypedef, } -impl Primitive { - fn from_str(s: &str) -> Option<Primitive> { +impl PrimitiveType { + fn from_str(s: &str) -> Option<PrimitiveType> { match s.as_slice() { "int" => Some(Int), "i8" => Some(I8), @@ -1129,7 +1129,7 @@ impl Primitive { } } - fn find(attrs: &[Attribute]) -> Option<Primitive> { + fn find(attrs: &[Attribute]) -> Option<PrimitiveType> { for attr in attrs.iter() { let list = match *attr { List(ref k, ref l) if k.as_slice() == "doc" => l, @@ -1141,7 +1141,7 @@ impl Primitive { if k.as_slice() == "primitive" => v.as_slice(), _ => continue, }; - match Primitive::from_str(value) { + match PrimitiveType::from_str(value) { Some(p) => return Some(p), None => {} } diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs index 54e9c29e11d..b771473473c 100644 --- a/src/librustdoc/fold.rs +++ b/src/librustdoc/fold.rs @@ -40,8 +40,8 @@ pub trait DocFolder { EnumItem(i) }, TraitItem(mut i) => { - fn vtrm<T: DocFolder>(this: &mut T, trm: TraitItem) - -> Option<TraitItem> { + fn vtrm<T: DocFolder>(this: &mut T, trm: TraitMethod) + -> Option<TraitMethod> { match trm { RequiredMethod(it) => { match this.fold_item(it) { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index e526286ef46..c807c180e64 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -277,7 +277,7 @@ fn path(w: &mut fmt::Formatter, path: &clean::Path, print_all: bool, } fn primitive_link(f: &mut fmt::Formatter, - prim: clean::Primitive, + prim: clean::PrimitiveType, name: &str) -> fmt::Result { let m = cache_key.get().unwrap(); let mut needs_termination = false; diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 2107854c52b..cf625d4ddfc 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -177,7 +177,7 @@ pub struct Cache { pub extern_locations: HashMap<ast::CrateNum, ExternalLocation>, /// Cache of where documentation for primitives can be found. - pub primitive_locations: HashMap<clean::Primitive, ast::CrateNum>, + pub primitive_locations: HashMap<clean::PrimitiveType, ast::CrateNum>, /// Set of definitions which have been inlined from external crates. pub inlined: HashSet<ast::DefId>, @@ -1637,7 +1637,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, _ => false, } }) - .collect::<Vec<&clean::TraitItem>>(); + .collect::<Vec<&clean::TraitMethod>>(); let provided = t.items.iter() .filter(|m| { match **m { @@ -1645,7 +1645,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, _ => false, } }) - .collect::<Vec<&clean::TraitItem>>(); + .collect::<Vec<&clean::TraitMethod>>(); if t.items.len() == 0 { try!(write!(w, "{{ }}")); @@ -1671,7 +1671,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, // Trait documentation try!(document(w, it)); - fn trait_item(w: &mut fmt::Formatter, m: &clean::TraitItem) + fn trait_item(w: &mut fmt::Formatter, m: &clean::TraitMethod) -> fmt::Result { try!(write!(w, "<h3 id='{}.{}' class='method'>{}<code>", shortty(m.item()), @@ -2180,7 +2180,7 @@ fn item_macro(w: &mut fmt::Formatter, it: &clean::Item, fn item_primitive(w: &mut fmt::Formatter, it: &clean::Item, - _p: &clean::Primitive) -> fmt::Result { + _p: &clean::PrimitiveType) -> fmt::Result { try!(document(w, it)); render_methods(w, it) } diff --git a/src/librustdoc/stability_summary.rs b/src/librustdoc/stability_summary.rs index 02dc4e9bdb6..f7d43037723 100644 --- a/src/librustdoc/stability_summary.rs +++ b/src/librustdoc/stability_summary.rs @@ -21,7 +21,7 @@ use syntax::attr::{Deprecated, Experimental, Unstable, Stable, Frozen, Locked}; use syntax::ast::Public; use clean::{Crate, Item, ModuleItem, Module, StructItem, Struct, EnumItem, Enum}; -use clean::{ImplItem, Impl, Trait, TraitItem, ProvidedMethod, RequiredMethod}; +use clean::{ImplItem, Impl, Trait, TraitItem, TraitMethod, ProvidedMethod, RequiredMethod}; use clean::{TypeTraitItem, ViewItemItem, PrimitiveItem}; #[deriving(Zero, Encodable, Decodable, PartialEq, Eq)] @@ -128,7 +128,7 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) { items: ref trait_items, .. }) => { - fn extract_item<'a>(trait_item: &'a TraitItem) -> &'a Item { + fn extract_item<'a>(trait_item: &'a TraitMethod) -> &'a Item { match *trait_item { ProvidedMethod(ref item) | RequiredMethod(ref item) | diff --git a/src/librustrt/c_str.rs b/src/librustrt/c_str.rs index 5e0004f2a2a..04a4e96ecc4 100644 --- a/src/librustrt/c_str.rs +++ b/src/librustrt/c_str.rs @@ -36,6 +36,12 @@ not tied to the lifetime of the original string/data buffer). If C strings are heavily used in applications, then caching may be advisable to prevent unnecessary amounts of allocations. +Be carefull to remember that the memory is managed by C allocator API and not +by Rust allocator API. +That means that the CString pointers should be freed with C allocator API +if you intend to do that on your own, as the behaviour if you free them with +Rust's allocator API is not well defined + An example of creating and using a C string would be: ```rust @@ -91,8 +97,8 @@ pub struct CString { impl Clone for CString { /// Clone this CString into a new, uniquely owned CString. For safety - /// reasons, this is always a deep clone, rather than the usual shallow - /// clone. + /// reasons, this is always a deep clone with the memory allocated + /// with C's allocator API, rather than the usual shallow clone. fn clone(&self) -> CString { let len = self.len() + 1; let buf = unsafe { malloc_raw(len) } as *mut libc::c_char; @@ -131,7 +137,9 @@ impl<S: hash::Writer> hash::Hash<S> for CString { } impl CString { - /// Create a C String from a pointer. + /// Create a C String from a pointer, with memory managed by C's allocator + /// API, so avoid calling it with a pointer to memory managed by Rust's + /// allocator API, as the behaviour would not be well defined. /// ///# Failure /// @@ -265,7 +273,8 @@ impl CString { /// forgotten, meaning that the backing allocation of this /// `CString` is not automatically freed if it owns the /// allocation. In this case, a user of `.unwrap()` should ensure - /// the allocation is freed, to avoid leaking memory. + /// the allocation is freed, to avoid leaking memory. You should + /// use libc's memory allocator in this case. /// /// Prefer `.as_ptr()` when just retrieving a pointer to the /// string data, as that does not relinquish ownership. diff --git a/src/librustrt/local_data.rs b/src/librustrt/local_data.rs index c71f86bb063..ba5a4dc3f21 100644 --- a/src/librustrt/local_data.rs +++ b/src/librustrt/local_data.rs @@ -67,7 +67,7 @@ use task::{Task, LocalStorage}; pub type Key<T> = &'static KeyValue<T>; #[allow(missing_doc)] -pub enum KeyValue<T> { Key } +pub enum KeyValue<T> { KeyValueKey } // The task-local-map stores all TLD information for the currently running // task. It is stored as an owned pointer into the runtime, and it's only @@ -417,7 +417,7 @@ mod tests { #[test] fn test_tls_multitask() { - static my_key: Key<String> = &Key; + static my_key: Key<String> = &KeyValueKey; my_key.replace(Some("parent data".to_string())); task::spawn(proc() { // TLD shouldn't carry over. @@ -435,7 +435,7 @@ mod tests { #[test] fn test_tls_overwrite() { - static my_key: Key<String> = &Key; + static my_key: Key<String> = &KeyValueKey; my_key.replace(Some("first data".to_string())); my_key.replace(Some("next data".to_string())); // Shouldn't leak. assert!(my_key.get().unwrap().as_slice() == "next data"); @@ -443,7 +443,7 @@ mod tests { #[test] fn test_tls_pop() { - static my_key: Key<String> = &Key; + static my_key: Key<String> = &KeyValueKey; my_key.replace(Some("weasel".to_string())); assert!(my_key.replace(None).unwrap() == "weasel".to_string()); // Pop must remove the data from the map. @@ -458,7 +458,7 @@ mod tests { // to get recorded as something within a rust stack segment. Then a // subsequent upcall (esp. for logging, think vsnprintf) would run on // a stack smaller than 1 MB. - static my_key: Key<String> = &Key; + static my_key: Key<String> = &KeyValueKey; task::spawn(proc() { my_key.replace(Some("hax".to_string())); }); @@ -466,9 +466,9 @@ mod tests { #[test] fn test_tls_multiple_types() { - static str_key: Key<String> = &Key; - static box_key: Key<Gc<()>> = &Key; - static int_key: Key<int> = &Key; + static str_key: Key<String> = &KeyValueKey; + static box_key: Key<Gc<()>> = &KeyValueKey; + static int_key: Key<int> = &KeyValueKey; task::spawn(proc() { str_key.replace(Some("string data".to_string())); box_key.replace(Some(box(GC) ())); @@ -478,9 +478,9 @@ mod tests { #[test] fn test_tls_overwrite_multiple_types() { - static str_key: Key<String> = &Key; - static box_key: Key<Gc<()>> = &Key; - static int_key: Key<int> = &Key; + static str_key: Key<String> = &KeyValueKey; + static box_key: Key<Gc<()>> = &KeyValueKey; + static int_key: Key<int> = &KeyValueKey; task::spawn(proc() { str_key.replace(Some("string data".to_string())); str_key.replace(Some("string data 2".to_string())); @@ -497,9 +497,9 @@ mod tests { #[test] #[should_fail] fn test_tls_cleanup_on_failure() { - static str_key: Key<String> = &Key; - static box_key: Key<Gc<()>> = &Key; - static int_key: Key<int> = &Key; + static str_key: Key<String> = &KeyValueKey; + static box_key: Key<Gc<()>> = &KeyValueKey; + static int_key: Key<int> = &KeyValueKey; str_key.replace(Some("parent data".to_string())); box_key.replace(Some(box(GC) ())); task::spawn(proc() { @@ -524,7 +524,7 @@ mod tests { self.tx.send(()); } } - static key: Key<Dropper> = &Key; + static key: Key<Dropper> = &KeyValueKey; let _ = task::try(proc() { key.replace(Some(Dropper{ tx: tx })); }); @@ -535,14 +535,14 @@ mod tests { #[test] fn test_static_pointer() { - static key: Key<&'static int> = &Key; + static key: Key<&'static int> = &KeyValueKey; static VALUE: int = 0; key.replace(Some(&VALUE)); } #[test] fn test_owned() { - static key: Key<Box<int>> = &Key; + static key: Key<Box<int>> = &KeyValueKey; key.replace(Some(box 1)); { @@ -559,11 +559,11 @@ mod tests { #[test] fn test_same_key_type() { - static key1: Key<int> = &Key; - static key2: Key<int> = &Key; - static key3: Key<int> = &Key; - static key4: Key<int> = &Key; - static key5: Key<int> = &Key; + static key1: Key<int> = &KeyValueKey; + static key2: Key<int> = &KeyValueKey; + static key3: Key<int> = &KeyValueKey; + static key4: Key<int> = &KeyValueKey; + static key5: Key<int> = &KeyValueKey; key1.replace(Some(1)); key2.replace(Some(2)); key3.replace(Some(3)); @@ -580,7 +580,7 @@ mod tests { #[test] #[should_fail] fn test_nested_get_set1() { - static key: Key<int> = &Key; + static key: Key<int> = &KeyValueKey; assert_eq!(key.replace(Some(4)), None); let _k = key.get(); @@ -602,7 +602,7 @@ mod tests { #[bench] fn bench_replace_none(b: &mut test::Bencher) { - static key: Key<uint> = &Key; + static key: Key<uint> = &KeyValueKey; let _clear = ClearKey(key); key.replace(None); b.iter(|| { @@ -612,7 +612,7 @@ mod tests { #[bench] fn bench_replace_some(b: &mut test::Bencher) { - static key: Key<uint> = &Key; + static key: Key<uint> = &KeyValueKey; let _clear = ClearKey(key); key.replace(Some(1u)); b.iter(|| { @@ -622,7 +622,7 @@ mod tests { #[bench] fn bench_replace_none_some(b: &mut test::Bencher) { - static key: Key<uint> = &Key; + static key: Key<uint> = &KeyValueKey; let _clear = ClearKey(key); key.replace(Some(0u)); b.iter(|| { @@ -634,7 +634,7 @@ mod tests { #[bench] fn bench_100_keys_replace_last(b: &mut test::Bencher) { - static keys: [KeyValue<uint>, ..100] = [Key, ..100]; + static keys: [KeyValue<uint>, ..100] = [KeyValueKey, ..100]; let _clear = keys.iter().map(ClearKey).collect::<Vec<ClearKey<uint>>>(); for (i, key) in keys.iter().enumerate() { key.replace(Some(i)); @@ -647,7 +647,7 @@ mod tests { #[bench] fn bench_1000_keys_replace_last(b: &mut test::Bencher) { - static keys: [KeyValue<uint>, ..1000] = [Key, ..1000]; + static keys: [KeyValue<uint>, ..1000] = [KeyValueKey, ..1000]; let _clear = keys.iter().map(ClearKey).collect::<Vec<ClearKey<uint>>>(); for (i, key) in keys.iter().enumerate() { key.replace(Some(i)); @@ -661,7 +661,7 @@ mod tests { #[bench] fn bench_get(b: &mut test::Bencher) { - static key: Key<uint> = &Key; + static key: Key<uint> = &KeyValueKey; let _clear = ClearKey(key); key.replace(Some(42)); b.iter(|| { @@ -671,7 +671,7 @@ mod tests { #[bench] fn bench_100_keys_get_last(b: &mut test::Bencher) { - static keys: [KeyValue<uint>, ..100] = [Key, ..100]; + static keys: [KeyValue<uint>, ..100] = [KeyValueKey, ..100]; let _clear = keys.iter().map(ClearKey).collect::<Vec<ClearKey<uint>>>(); for (i, key) in keys.iter().enumerate() { key.replace(Some(i)); @@ -684,7 +684,7 @@ mod tests { #[bench] fn bench_1000_keys_get_last(b: &mut test::Bencher) { - static keys: [KeyValue<uint>, ..1000] = [Key, ..1000]; + static keys: [KeyValue<uint>, ..1000] = [KeyValueKey, ..1000]; let _clear = keys.iter().map(ClearKey).collect::<Vec<ClearKey<uint>>>(); for (i, key) in keys.iter().enumerate() { key.replace(Some(i)); diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 833c5cd0f98..14274ef9f9b 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -28,7 +28,7 @@ Data types that can be encoded are JavaScript types (see the `Json` enum for mor * `Boolean`: equivalent to rust's `bool` * `Number`: equivalent to rust's `f64` * `String`: equivalent to rust's `String` -* `Array`: equivalent to rust's `Vec<T>`, but also allowing objects of different types in the same +* `List`: equivalent to rust's `Vec<T>`, but also allowing objects of different types in the same array * `Object`: equivalent to rust's `Treemap<String, json::Json>` * `Null` @@ -201,7 +201,7 @@ use std::io::MemWriter; use std::mem::{swap, transmute}; use std::num::{FPNaN, FPInfinite}; use std::str::ScalarValue; -use std::string::String; +use std::string; use std::vec::Vec; use Encodable; @@ -212,15 +212,15 @@ pub enum Json { I64(i64), U64(u64), F64(f64), - String(String), + String(string::String), Boolean(bool), - List(List), - Object(Object), + List(JsonList), + Object(JsonObject), Null, } -pub type List = Vec<Json>; -pub type Object = TreeMap<String, Json>; +pub type JsonList = Vec<Json>; +pub type JsonObject = TreeMap<string::String, Json>; /// The errors that can arise while parsing a JSON stream. #[deriving(Clone, PartialEq)] @@ -257,10 +257,10 @@ pub type BuilderError = ParserError; #[deriving(Clone, PartialEq, Show)] pub enum DecoderError { ParseError(ParserError), - ExpectedError(String, String), - MissingFieldError(String), - UnknownVariantError(String), - ApplicationError(String) + ExpectedError(string::String, string::String), + MissingFieldError(string::String), + UnknownVariantError(string::String), + ApplicationError(string::String) } /// Returns a readable error string for a given error code. @@ -298,9 +298,9 @@ pub fn decode<T: ::Decodable<Decoder, DecoderError>>(s: &str) -> DecodeResult<T> } /// Shortcut function to encode a `T` into a JSON `String` -pub fn encode<'a, T: Encodable<Encoder<'a>, io::IoError>>(object: &T) -> String { +pub fn encode<'a, T: Encodable<Encoder<'a>, io::IoError>>(object: &T) -> string::String { let buff = Encoder::buffer_encode(object); - String::from_utf8(buff).unwrap() + string::String::from_utf8(buff).unwrap() } impl fmt::Show for ErrorCode { @@ -375,9 +375,9 @@ fn spaces(wr: &mut io::Writer, mut n: uint) -> Result<(), io::IoError> { } } -fn fmt_number_or_null(v: f64) -> String { +fn fmt_number_or_null(v: f64) -> string::String { match v.classify() { - FPNaN | FPInfinite => String::from_str("null"), + FPNaN | FPInfinite => string::String::from_str("null"), _ => f64::to_str_digits(v, 6u) } } @@ -411,7 +411,7 @@ impl<'a> Encoder<'a> { /// /// Note: this function is deprecated. Consider using `json::encode` instead. #[deprecated = "Replaced by `json::encode`"] - pub fn str_encode<T: Encodable<Encoder<'a>, io::IoError>>(object: &T) -> String { + pub fn str_encode<T: Encodable<Encoder<'a>, io::IoError>>(object: &T) -> string::String { encode(object) } } @@ -877,15 +877,15 @@ impl Json { } /// Encodes a json value into a string - pub fn to_pretty_str(&self) -> String { + pub fn to_pretty_str(&self) -> string::String { let mut s = MemWriter::new(); self.to_pretty_writer(&mut s as &mut io::Writer).unwrap(); - String::from_utf8(s.unwrap()).unwrap() + string::String::from_utf8(s.unwrap()).unwrap() } /// If the Json value is an Object, returns the value associated with the provided key. /// Otherwise, returns None. - pub fn find<'a>(&'a self, key: &String) -> Option<&'a Json>{ + pub fn find<'a>(&'a self, key: &string::String) -> Option<&'a Json>{ match self { &Object(ref map) => map.find(key), _ => None @@ -895,7 +895,7 @@ impl Json { /// Attempts to get a nested Json Object for each key in `keys`. /// If any key is found not to exist, find_path will return None. /// Otherwise, it will return the Json value associated with the final key. - pub fn find_path<'a>(&'a self, keys: &[&String]) -> Option<&'a Json>{ + pub fn find_path<'a>(&'a self, keys: &[&string::String]) -> Option<&'a Json>{ let mut target = self; for key in keys.iter() { match target.find(*key) { @@ -909,7 +909,7 @@ impl Json { /// If the Json value is an Object, performs a depth-first search until /// a value associated with the provided key is found. If no value is found /// or the Json value is not an Object, returns None. - pub fn search<'a>(&'a self, key: &String) -> Option<&'a Json> { + pub fn search<'a>(&'a self, key: &string::String) -> Option<&'a Json> { match self { &Object(ref map) => { match map.find(key) { @@ -937,7 +937,7 @@ impl Json { /// If the Json value is an Object, returns the associated TreeMap. /// Returns None otherwise. - pub fn as_object<'a>(&'a self) -> Option<&'a Object> { + pub fn as_object<'a>(&'a self) -> Option<&'a JsonObject> { match self { &Object(ref map) => Some(map), _ => None @@ -951,7 +951,7 @@ impl Json { /// If the Json value is a List, returns the associated vector. /// Returns None otherwise. - pub fn as_list<'a>(&'a self) -> Option<&'a List> { + pub fn as_list<'a>(&'a self) -> Option<&'a JsonList> { match self { &List(ref list) => Some(&*list), _ => None @@ -1075,7 +1075,7 @@ pub enum JsonEvent { I64Value(i64), U64Value(u64), F64Value(f64), - StringValue(String), + StringValue(string::String), NullValue, Error(ParserError), } @@ -1083,7 +1083,7 @@ pub enum JsonEvent { #[deriving(PartialEq, Show)] enum ParserState { // Parse a value in a list, true means first element. - ParseList(bool), + ParseArray(bool), // Parse ',' or ']' after an element in a list. ParseListComma, // Parse a key:value in an object, true means first element. @@ -1191,7 +1191,7 @@ impl Stack { } // Used by Parser to insert Key elements at the top of the stack. - fn push_key(&mut self, key: String) { + fn push_key(&mut self, key: string::String) { self.stack.push(InternalKey(self.str_buffer.len() as u16, key.len() as u16)); for c in key.as_bytes().iter() { self.str_buffer.push(*c); @@ -1502,9 +1502,9 @@ impl<T: Iterator<char>> Parser<T> { Ok(n) } - fn parse_str(&mut self) -> Result<String, ParserError> { + fn parse_str(&mut self) -> Result<string::String, ParserError> { let mut escape = false; - let mut res = String::new(); + let mut res = string::String::new(); loop { self.bump(); @@ -1574,7 +1574,7 @@ impl<T: Iterator<char>> Parser<T> { // The only paths where the loop can spin a new iteration // are in the cases ParseListComma and ParseObjectComma if ',' // is parsed. In these cases the state is set to (respectively) - // ParseList(false) and ParseObject(false), which always return, + // ParseArray(false) and ParseObject(false), which always return, // so there is no risk of getting stuck in an infinite loop. // All other paths return before the end of the loop's iteration. self.parse_whitespace(); @@ -1583,7 +1583,7 @@ impl<T: Iterator<char>> Parser<T> { ParseStart => { return self.parse_start(); } - ParseList(first) => { + ParseArray(first) => { return self.parse_list(first); } ParseListComma => { @@ -1615,7 +1615,7 @@ impl<T: Iterator<char>> Parser<T> { let val = self.parse_value(); self.state = match val { Error(_) => { ParseFinished } - ListStart => { ParseList(true) } + ListStart => { ParseArray(true) } ObjectStart => { ParseObject(true) } _ => { ParseBeforeFinish } }; @@ -1647,7 +1647,7 @@ impl<T: Iterator<char>> Parser<T> { self.state = match val { Error(_) => { ParseFinished } - ListStart => { ParseList(true) } + ListStart => { ParseArray(true) } ObjectStart => { ParseObject(true) } _ => { ParseListComma } }; @@ -1657,7 +1657,7 @@ impl<T: Iterator<char>> Parser<T> { fn parse_list_comma_or_end(&mut self) -> Option<JsonEvent> { if self.ch_is(',') { self.stack.bump_index(); - self.state = ParseList(false); + self.state = ParseArray(false); self.bump(); return None; } else if self.ch_is(']') { @@ -1728,7 +1728,7 @@ impl<T: Iterator<char>> Parser<T> { self.state = match val { Error(_) => { ParseFinished } - ListStart => { ParseList(true) } + ListStart => { ParseArray(true) } ObjectStart => { ParseObject(true) } _ => { ParseObjectComma } }; @@ -1830,7 +1830,7 @@ impl<T: Iterator<char>> Builder<T> { Some(F64Value(n)) => { Ok(F64(n)) } Some(BooleanValue(b)) => { Ok(Boolean(b)) } Some(StringValue(ref mut s)) => { - let mut temp = String::new(); + let mut temp = string::String::new(); swap(s, &mut temp); Ok(String(temp)) } @@ -2034,7 +2034,7 @@ impl ::Decoder<DecoderError> for Decoder { Err(ExpectedError("single character string".to_string(), format!("{}", s))) } - fn read_str(&mut self) -> DecodeResult<String> { + fn read_str(&mut self) -> DecodeResult<string::String> { debug!("read_str"); expect!(self.pop(), String) } @@ -2284,7 +2284,7 @@ impl ToJson for bool { fn to_json(&self) -> Json { Boolean(*self) } } -impl ToJson for String { +impl ToJson for string::String { fn to_json(&self) -> Json { String((*self).clone()) } } @@ -2328,7 +2328,7 @@ impl<A: ToJson> ToJson for Vec<A> { fn to_json(&self) -> Json { List(self.iter().map(|elt| elt.to_json()).collect()) } } -impl<A: ToJson> ToJson for TreeMap<String, A> { +impl<A: ToJson> ToJson for TreeMap<string::String, A> { fn to_json(&self) -> Json { let mut d = TreeMap::new(); for (key, value) in self.iter() { @@ -2338,7 +2338,7 @@ impl<A: ToJson> ToJson for TreeMap<String, A> { } } -impl<A: ToJson> ToJson for HashMap<String, A> { +impl<A: ToJson> ToJson for HashMap<string::String, A> { fn to_json(&self) -> Json { let mut d = TreeMap::new(); for (key, value) in self.iter() { @@ -2375,7 +2375,7 @@ mod tests { extern crate test; use self::test::Bencher; use {Encodable, Decodable}; - use super::{Encoder, Decoder, Error, Boolean, I64, U64, F64, List, String, Null, + use super::{List, Encoder, Decoder, Error, Boolean, I64, U64, F64, String, Null, PrettyEncoder, Object, Json, from_str, ParseError, ExpectedError, MissingFieldError, UnknownVariantError, DecodeResult, DecoderError, JsonEvent, Parser, StackElement, @@ -2386,6 +2386,7 @@ mod tests { TrailingCharacters, TrailingComma}; use std::{i64, u64, f32, f64, io}; use std::collections::TreeMap; + use std::string; #[deriving(Decodable, Eq, PartialEq, Show)] struct OptionData { @@ -2417,14 +2418,14 @@ mod tests { #[deriving(PartialEq, Encodable, Decodable, Show)] enum Animal { Dog, - Frog(String, int) + Frog(string::String, int) } #[deriving(PartialEq, Encodable, Decodable, Show)] struct Inner { a: (), b: uint, - c: Vec<String>, + c: Vec<string::String>, } #[deriving(PartialEq, Encodable, Decodable, Show)] @@ -2432,7 +2433,7 @@ mod tests { inner: Vec<Inner>, } - fn mk_object(items: &[(String, Json)]) -> Json { + fn mk_object(items: &[(string::String, Json)]) -> Json { let mut d = TreeMap::new(); for item in items.iter() { @@ -2610,7 +2611,7 @@ mod tests { from_str(a.to_pretty_str().as_slice()).unwrap()); } - fn with_str_writer(f: |&mut io::Writer|) -> String { + fn with_str_writer(f: |&mut io::Writer|) -> string::String { use std::io::MemWriter; use std::str; @@ -2678,7 +2679,7 @@ mod tests { #[test] fn test_write_none() { - let value: Option<String> = None; + let value: Option<string::String> = None; let s = with_str_writer(|writer| { let mut encoder = Encoder::new(writer); value.encode(&mut encoder).unwrap(); @@ -2825,7 +2826,7 @@ mod tests { ("\"\\uAB12\"", "\uAB12")]; for &(i, o) in s.iter() { - let v: String = super::decode(i).unwrap(); + let v: string::String = super::decode(i).unwrap(); assert_eq!(v.as_slice(), o); } } @@ -2959,10 +2960,10 @@ mod tests { #[test] fn test_decode_option() { - let value: Option<String> = super::decode("null").unwrap(); + let value: Option<string::String> = super::decode("null").unwrap(); assert_eq!(value, None); - let value: Option<String> = super::decode("\"jodhpurs\"").unwrap(); + let value: Option<string::String> = super::decode("\"jodhpurs\"").unwrap(); assert_eq!(value, Some("jodhpurs".to_string())); } @@ -2980,7 +2981,7 @@ mod tests { fn test_decode_map() { let s = "{\"a\": \"Dog\", \"b\": {\"variant\":\"Frog\",\ \"fields\":[\"Henry\", 349]}}"; - let mut map: TreeMap<String, Animal> = super::decode(s).unwrap(); + let mut map: TreeMap<string::String, Animal> = super::decode(s).unwrap(); assert_eq!(map.pop(&"a".to_string()), Some(Dog)); assert_eq!(map.pop(&"b".to_string()), Some(Frog("Henry".to_string(), 349))); @@ -2997,13 +2998,13 @@ mod tests { struct DecodeStruct { x: f64, y: bool, - z: String, + z: string::String, w: Vec<DecodeStruct> } #[deriving(Decodable)] enum DecodeEnum { A(f64), - B(String) + B(string::String) } fn check_err<T: Decodable<Decoder, DecoderError>>(to_parse: &'static str, expected: DecoderError) { @@ -3709,7 +3710,7 @@ mod tests { }); } - fn big_json() -> String { + fn big_json() -> string::String { let mut src = "[\n".to_string(); for _ in range(0i, 500) { src.push_str(r#"{ "a": true, "b": null, "c":3.1415, "d": "Hello world", "e": \ diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index e1f2f43673f..86c03708e40 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -304,10 +304,10 @@ macro_rules! println( #[macro_export] macro_rules! local_data_key( ($name:ident: $ty:ty) => ( - static $name: ::std::local_data::Key<$ty> = &::std::local_data::Key; + static $name: ::std::local_data::Key<$ty> = &::std::local_data::KeyValueKey; ); (pub $name:ident: $ty:ty) => ( - pub static $name: ::std::local_data::Key<$ty> = &::std::local_data::Key; + pub static $name: ::std::local_data::Key<$ty> = &::std::local_data::KeyValueKey; ); ) diff --git a/src/libstd/rt/backtrace.rs b/src/libstd/rt/backtrace.rs index 5557ef9943b..f4887a143d1 100644 --- a/src/libstd/rt/backtrace.rs +++ b/src/libstd/rt/backtrace.rs @@ -831,9 +831,11 @@ mod imp { mod arch { use libc::{c_longlong, c_ulonglong}; use libc::types::os::arch::extra::{WORD, DWORD, DWORDLONG}; + use simd; #[repr(C)] pub struct CONTEXT { + _align_hack: [simd::u64x2, ..0], // FIXME align on 16-byte P1Home: DWORDLONG, P2Home: DWORDLONG, P3Home: DWORDLONG, @@ -892,12 +894,14 @@ mod imp { #[repr(C)] pub struct M128A { + _align_hack: [simd::u64x2, ..0], // FIXME align on 16-byte Low: c_ulonglong, High: c_longlong } #[repr(C)] pub struct FLOATING_SAVE_AREA { + _align_hack: [simd::u64x2, ..0], // FIXME align on 16-byte _Dummy: [u8, ..512] // FIXME: Fill this out } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index eac158e664c..5c84745c20c 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -213,13 +213,20 @@ pub static DUMMY_NODE_ID: NodeId = -1; #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum TyParamBound { TraitTyParamBound(TraitRef), - UnboxedFnTyParamBound(UnboxedFnTy), + UnboxedFnTyParamBound(P<UnboxedFnBound>), RegionTyParamBound(Lifetime) } pub type TyParamBounds = OwnedSlice<TyParamBound>; #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] +pub struct UnboxedFnBound { + pub path: Path, + pub decl: P<FnDecl>, + pub ref_id: NodeId, +} + +#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub struct TyParam { pub ident: Ident, pub id: NodeId, @@ -531,6 +538,7 @@ pub enum Expr_ { ExprField(P<Expr>, SpannedIdent, Vec<P<Ty>>), ExprTupField(P<Expr>, Spanned<uint>, Vec<P<Ty>>), ExprIndex(P<Expr>, P<Expr>), + ExprSlice(P<Expr>, Option<P<Expr>>, Option<P<Expr>>, Mutability), /// Variable reference, possibly containing `::` and/or /// type parameters, e.g. foo::bar::<baz> @@ -1363,7 +1371,7 @@ mod test { inner: Span { lo: BytePos(11), hi: BytePos(19), - expn_info: None, + expn_id: NO_EXPANSION, }, view_items: Vec::new(), items: Vec::new(), @@ -1373,7 +1381,7 @@ mod test { span: Span { lo: BytePos(10), hi: BytePos(20), - expn_info: None, + expn_id: NO_EXPANSION, }, exported_macros: Vec::new(), }; diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 2f30108c27b..9072889463c 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -25,7 +25,6 @@ source code snippets, etc. use serialize::{Encodable, Decodable, Encoder, Decoder}; use std::cell::RefCell; -use std::gc::Gc; use std::rc::Rc; pub trait Pos { @@ -93,10 +92,10 @@ pub struct Span { pub hi: BytePos, /// Information about where the macro came from, if this piece of /// code was created by a macro expansion. - pub expn_info: Option<Gc<ExpnInfo>> + pub expn_id: ExpnId } -pub static DUMMY_SP: Span = Span { lo: BytePos(0), hi: BytePos(0), expn_info: None }; +pub static DUMMY_SP: Span = Span { lo: BytePos(0), hi: BytePos(0), expn_id: NO_EXPANSION }; #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub struct Spanned<T> { @@ -140,17 +139,19 @@ pub fn dummy_spanned<T>(t: T) -> Spanned<T> { /* assuming that we're not in macro expansion */ pub fn mk_sp(lo: BytePos, hi: BytePos) -> Span { - Span {lo: lo, hi: hi, expn_info: None} + Span {lo: lo, hi: hi, expn_id: NO_EXPANSION} } /// Return the span itself if it doesn't come from a macro expansion, /// otherwise return the call site span up to the `enclosing_sp` by /// following the `expn_info` chain. -pub fn original_sp(sp: Span, enclosing_sp: Span) -> Span { - match (sp.expn_info, enclosing_sp.expn_info) { +pub fn original_sp(cm: &CodeMap, sp: Span, enclosing_sp: Span) -> Span { + let call_site1 = cm.with_expn_info(sp.expn_id, |ei| ei.map(|ei| ei.call_site)); + let call_site2 = cm.with_expn_info(enclosing_sp.expn_id, |ei| ei.map(|ei| ei.call_site)); + match (call_site1, call_site2) { (None, _) => sp, - (Some(expn1), Some(expn2)) if expn1.call_site == expn2.call_site => sp, - (Some(expn1), _) => original_sp(expn1.call_site, enclosing_sp), + (Some(call_site1), Some(call_site2)) if call_site1 == call_site2 => sp, + (Some(call_site1), _) => original_sp(cm, call_site1, enclosing_sp), } } @@ -222,6 +223,11 @@ pub struct ExpnInfo { pub callee: NameAndSpan } +#[deriving(PartialEq, Eq, Clone, Show, Hash)] +pub struct ExpnId(u32); + +pub static NO_EXPANSION: ExpnId = ExpnId(-1); + pub type FileName = String; pub struct FileLines { @@ -299,13 +305,15 @@ impl FileMap { } pub struct CodeMap { - pub files: RefCell<Vec<Rc<FileMap>>> + pub files: RefCell<Vec<Rc<FileMap>>>, + expansions: RefCell<Vec<ExpnInfo>> } impl CodeMap { pub fn new() -> CodeMap { CodeMap { files: RefCell::new(Vec::new()), + expansions: RefCell::new(Vec::new()), } } @@ -527,6 +535,19 @@ impl CodeMap { col: chpos - linechpos } } + + pub fn record_expansion(&self, expn_info: ExpnInfo) -> ExpnId { + let mut expansions = self.expansions.borrow_mut(); + expansions.push(expn_info); + ExpnId(expansions.len().to_u32().expect("too many ExpnInfo's!") - 1) + } + + pub fn with_expn_info<T>(&self, id: ExpnId, f: |Option<&ExpnInfo>| -> T) -> T { + match id { + NO_EXPANSION => f(None), + ExpnId(i) => f(Some(&(*self.expansions.borrow())[i as uint])) + } + } } #[cfg(test)] @@ -665,7 +686,7 @@ mod test { fn t7() { // Test span_to_lines for a span ending at the end of filemap let cm = init_code_map(); - let span = Span {lo: BytePos(12), hi: BytePos(23), expn_info: None}; + let span = Span {lo: BytePos(12), hi: BytePos(23), expn_id: NO_EXPANSION}; let file_lines = cm.span_to_lines(span); assert_eq!(file_lines.file.name, "blork.rs".to_string()); @@ -677,7 +698,7 @@ mod test { fn t8() { // Test span_to_snippet for a span ending at the end of filemap let cm = init_code_map(); - let span = Span {lo: BytePos(12), hi: BytePos(23), expn_info: None}; + let span = Span {lo: BytePos(12), hi: BytePos(23), expn_id: NO_EXPANSION}; let snippet = cm.span_to_snippet(span); assert_eq!(snippet, Some("second line".to_string())); @@ -687,7 +708,7 @@ mod test { fn t9() { // Test span_to_str for a span ending at the end of filemap let cm = init_code_map(); - let span = Span {lo: BytePos(12), hi: BytePos(23), expn_info: None}; + let span = Span {lo: BytePos(12), hi: BytePos(23), expn_id: NO_EXPANSION}; let sstr = cm.span_to_string(span); assert_eq!(sstr, "blork.rs:2:1: 2:12".to_string()); diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index faa3946b74d..f33c768d647 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -389,7 +389,7 @@ fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan, // we want to tell compiletest/runtest to look at the last line of the // span (since `custom_highlight_lines` displays an arrow to the end of // the span) - let span_end = Span { lo: sp.hi, hi: sp.hi, expn_info: sp.expn_info}; + let span_end = Span { lo: sp.hi, hi: sp.hi, expn_id: sp.expn_id}; let ses = cm.span_to_string(span_end); try!(print_diagnostic(dst, ses.as_slice(), lvl, msg, code)); if rsp.is_full_span() { @@ -523,24 +523,24 @@ fn print_macro_backtrace(w: &mut EmitterWriter, cm: &codemap::CodeMap, sp: Span) -> io::IoResult<()> { - for ei in sp.expn_info.iter() { - let ss = ei.callee - .span - .as_ref() - .map_or("".to_string(), |span| cm.span_to_string(*span)); - let (pre, post) = match ei.callee.format { - codemap::MacroAttribute => ("#[", "]"), - codemap::MacroBang => ("", "!") - }; - try!(print_diagnostic(w, ss.as_slice(), Note, - format!("in expansion of {}{}{}", pre, - ei.callee.name, - post).as_slice(), None)); - let ss = cm.span_to_string(ei.call_site); - try!(print_diagnostic(w, ss.as_slice(), Note, "expansion site", None)); - try!(print_macro_backtrace(w, cm, ei.call_site)); - } - Ok(()) + let cs = try!(cm.with_expn_info(sp.expn_id, |expn_info| match expn_info { + Some(ei) => { + let ss = ei.callee.span.map_or(String::new(), |span| cm.span_to_string(span)); + let (pre, post) = match ei.callee.format { + codemap::MacroAttribute => ("#[", "]"), + codemap::MacroBang => ("", "!") + }; + try!(print_diagnostic(w, ss.as_slice(), Note, + format!("in expansion of {}{}{}", pre, + ei.callee.name, + post).as_slice(), None)); + let ss = cm.span_to_string(ei.call_site); + try!(print_diagnostic(w, ss.as_slice(), Note, "expansion site", None)); + Ok(Some(ei.call_site)) + } + None => Ok(None) + })); + cs.map_or(Ok(()), |call_site| print_macro_backtrace(w, cm, call_site)) } pub fn expect<T>(diag: &SpanHandler, opt: Option<T>, msg: || -> String) -> T { diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index 132b59c89b2..d3c39284f55 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -13,7 +13,7 @@ use std::collections::HashMap; use ast; use ast::{Ident, Name, TokenTree}; use codemap::Span; -use ext::base::{ExtCtxt, MacExpr, MacItem, MacResult}; +use ext::base::{ExtCtxt, MacExpr, MacResult, MacItems}; use ext::build::AstBuilder; use parse::token; use ptr::P; @@ -102,7 +102,7 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt, let sym = Ident::new(token::gensym(( "__register_diagnostic_".to_string() + token::get_ident(*code).get() ).as_slice())); - MacItem::new(quote_item!(ecx, mod $sym {}).unwrap()) + MacItems::new(vec![quote_item!(ecx, mod $sym {}).unwrap()].into_iter()) } pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt, @@ -133,7 +133,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt, (descriptions.len(), ecx.expr_vec(span, descriptions)) }) }); - MacItem::new(quote_item!(ecx, + MacItems::new(vec![quote_item!(ecx, pub static $name: [(&'static str, &'static str), ..$count] = $expr; - ).unwrap()) + ).unwrap()].into_iter()) } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 773daa4a4c5..b35a9456757 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -11,7 +11,7 @@ use ast; use ast::Name; use codemap; -use codemap::{CodeMap, Span, ExpnInfo}; +use codemap::{CodeMap, Span, ExpnId, ExpnInfo, NO_EXPANSION}; use ext; use ext::expand; use parse; @@ -24,7 +24,6 @@ use ext::mtwt; use fold::Folder; use std::collections::HashMap; -use std::gc::{Gc, GC}; use std::rc::Rc; // new-style macro! tt code: @@ -203,25 +202,20 @@ impl MacResult for MacPat { Some(self.p) } } -/// A convenience type for macros that return a single item. -pub struct MacItem { - i: P<ast::Item> +/// A type for macros that return multiple items. +pub struct MacItems { + items: SmallVector<P<ast::Item>> } -impl MacItem { - pub fn new(i: P<ast::Item>) -> Box<MacResult+'static> { - box MacItem { i: i } as Box<MacResult+'static> + +impl MacItems { + pub fn new<I: Iterator<P<ast::Item>>>(mut it: I) -> Box<MacResult+'static> { + box MacItems { items: it.collect() } as Box<MacResult+'static> } } -impl MacResult for MacItem { - fn make_items(self: Box<MacItem>) -> Option<SmallVector<P<ast::Item>>> { - Some(SmallVector::one(self.i)) - } - fn make_stmt(self: Box<MacItem>) -> Option<P<ast::Stmt>> { - Some(P(codemap::respan( - self.i.span, - ast::StmtDecl( - P(codemap::respan(self.i.span, ast::DeclItem(self.i))), - ast::DUMMY_NODE_ID)))) + +impl MacResult for MacItems { + fn make_items(self: Box<MacItems>) -> Option<SmallVector<P<ast::Item>>> { + Some(self.items) } } @@ -305,11 +299,11 @@ pub enum SyntaxExtension { /// based upon it. /// /// `#[deriving(...)]` is an `ItemDecorator`. - ItemDecorator(Box<ItemDecorator + 'static>), + Decorator(Box<ItemDecorator + 'static>), /// A syntax extension that is attached to an item and modifies it /// in-place. - ItemModifier(Box<ItemModifier + 'static>), + Modifier(Box<ItemModifier + 'static>), /// A normal, function-like syntax extension. /// @@ -387,7 +381,7 @@ fn initial_syntax_expander_table() -> SyntaxEnv { builtin_normal_expander( ext::log_syntax::expand_syntax_ext)); syntax_expanders.insert(intern("deriving"), - ItemDecorator(box ext::deriving::expand_meta_deriving)); + Decorator(box ext::deriving::expand_meta_deriving)); // Quasi-quoting expanders syntax_expanders.insert(intern("quote_tokens"), @@ -457,7 +451,7 @@ fn initial_syntax_expander_table() -> SyntaxEnv { pub struct ExtCtxt<'a> { pub parse_sess: &'a parse::ParseSess, pub cfg: ast::CrateConfig, - pub backtrace: Option<Gc<ExpnInfo>>, + pub backtrace: ExpnId, pub ecfg: expand::ExpansionConfig, pub mod_path: Vec<ast::Ident> , @@ -473,7 +467,7 @@ impl<'a> ExtCtxt<'a> { ExtCtxt { parse_sess: parse_sess, cfg: cfg, - backtrace: None, + backtrace: NO_EXPANSION, mod_path: Vec::new(), ecfg: ecfg, trace_mac: false, @@ -501,13 +495,49 @@ impl<'a> ExtCtxt<'a> { pub fn parse_sess(&self) -> &'a parse::ParseSess { self.parse_sess } pub fn cfg(&self) -> ast::CrateConfig { self.cfg.clone() } pub fn call_site(&self) -> Span { - match self.backtrace { + self.codemap().with_expn_info(self.backtrace, |ei| match ei { Some(expn_info) => expn_info.call_site, None => self.bug("missing top span") - } + }) } pub fn print_backtrace(&self) { } - pub fn backtrace(&self) -> Option<Gc<ExpnInfo>> { self.backtrace } + pub fn backtrace(&self) -> ExpnId { self.backtrace } + pub fn original_span(&self) -> Span { + let mut expn_id = self.backtrace; + let mut call_site = None; + loop { + match self.codemap().with_expn_info(expn_id, |ei| ei.map(|ei| ei.call_site)) { + None => break, + Some(cs) => { + call_site = Some(cs); + expn_id = cs.expn_id; + } + } + } + call_site.expect("missing expansion backtrace") + } + pub fn original_span_in_file(&self) -> Span { + let mut expn_id = self.backtrace; + let mut call_site = None; + loop { + let expn_info = self.codemap().with_expn_info(expn_id, |ei| { + ei.map(|ei| (ei.call_site, ei.callee.name.as_slice() == "include")) + }); + match expn_info { + None => break, + Some((cs, is_include)) => { + if is_include { + // Don't recurse into file using "include!". + break; + } + call_site = Some(cs); + expn_id = cs.expn_id; + } + } + } + call_site.expect("missing expansion backtrace") + } + pub fn mod_push(&mut self, i: ast::Ident) { self.mod_path.push(i); } pub fn mod_pop(&mut self) { self.mod_path.pop().unwrap(); } pub fn mod_path(&self) -> Vec<ast::Ident> { @@ -516,22 +546,22 @@ impl<'a> ExtCtxt<'a> { v.extend(self.mod_path.iter().map(|a| *a)); return v; } - pub fn bt_push(&mut self, ei: codemap::ExpnInfo) { - match ei { - ExpnInfo {call_site: cs, callee: ref callee} => { - self.backtrace = - Some(box(GC) ExpnInfo { - call_site: Span {lo: cs.lo, hi: cs.hi, - expn_info: self.backtrace.clone()}, - callee: (*callee).clone() - }); - } - } + pub fn bt_push(&mut self, ei: ExpnInfo) { + let mut call_site = ei.call_site; + call_site.expn_id = self.backtrace; + self.backtrace = self.codemap().record_expansion(ExpnInfo { + call_site: call_site, + callee: ei.callee + }); } pub fn bt_pop(&mut self) { match self.backtrace { - Some(expn_info) => self.backtrace = expn_info.call_site.expn_info, - _ => self.bug("tried to pop without a push") + NO_EXPANSION => self.bug("tried to pop without a push"), + expn_id => { + self.backtrace = self.codemap().with_expn_info(expn_id, |expn_info| { + expn_info.map_or(NO_EXPANSION, |ei| ei.call_site.expn_id) + }); + } } } /// Emit `msg` attached to `sp`, and stop compilation immediately. diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 7b2613d4e8b..16ecd83180e 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -573,7 +573,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { let field_span = Span { lo: sp.lo - Pos::from_uint(field_name.get().len()), hi: sp.hi, - expn_info: sp.expn_info, + expn_id: sp.expn_id, }; let id = Spanned { node: ident, span: field_span }; @@ -583,7 +583,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { let field_span = Span { lo: sp.lo - Pos::from_uint(idx.to_string().len()), hi: sp.hi, - expn_info: sp.expn_info, + expn_id: sp.expn_id, }; let id = Spanned { node: idx, span: field_span }; diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index ff249495bd7..142adc9b721 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -181,7 +181,6 @@ //! ~~~ use std::cell::RefCell; -use std::gc::GC; use std::vec; use abi::Abi; @@ -1169,7 +1168,7 @@ impl<'a> TraitDef<'a> { None => cx.span_bug(self.span, "trait with empty path in generic `deriving`"), Some(name) => *name }; - to_set.expn_info = Some(box(GC) codemap::ExpnInfo { + to_set.expn_id = cx.codemap().record_expansion(codemap::ExpnInfo { call_site: to_set, callee: codemap::NameAndSpan { name: format!("deriving({})", trait_name), diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 4ff9912645a..e173b93e468 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -30,8 +30,6 @@ use util::small_vector::SmallVector; use visit; use visit::Visitor; -use std::gc::Gc; - enum Either<L,R> { Left(L), Right(R) @@ -161,11 +159,11 @@ fn expand_mac_invoc<T>(mac: ast::Mac, span: codemap::Span, // be the root of the call stack. That's the most // relevant span and it's the actual invocation of // the macro. - let mac_span = original_span(fld.cx); + let mac_span = fld.cx.original_span(); let opt_parsed = { let expanded = expandfun.expand(fld.cx, - mac_span.call_site, + mac_span, marked_before.as_slice()); parse_thunk(expanded) }; @@ -254,7 +252,7 @@ pub fn expand_item(it: P<ast::Item>, fld: &mut MacroExpander) match fld.cx.syntax_env.find(&intern(mname.get())) { Some(rc) => match *rc { - ItemDecorator(ref dec) => { + Decorator(ref dec) => { attr::mark_used(attr); fld.cx.bt_push(ExpnInfo { @@ -311,7 +309,7 @@ fn expand_item_modifiers(mut it: P<ast::Item>, fld: &mut MacroExpander) // partition the attributes into ItemModifiers and others let (modifiers, other_attrs) = it.attrs.partitioned(|attr| { match fld.cx.syntax_env.find(&intern(attr.name().get())) { - Some(rc) => match *rc { ItemModifier(_) => true, _ => false }, + Some(rc) => match *rc { Modifier(_) => true, _ => false }, _ => false } }); @@ -330,7 +328,7 @@ fn expand_item_modifiers(mut it: P<ast::Item>, fld: &mut MacroExpander) match fld.cx.syntax_env.find(&intern(mname.get())) { Some(rc) => match *rc { - ItemModifier(ref mac) => { + Modifier(ref mac) => { attr::mark_used(attr); fld.cx.bt_push(ExpnInfo { call_site: attr.span, @@ -759,9 +757,9 @@ fn expand_pat(p: P<ast::Pat>, fld: &mut MacroExpander) -> P<ast::Pat> { let fm = fresh_mark(); let marked_before = mark_tts(tts.as_slice(), fm); - let mac_span = original_span(fld.cx); + let mac_span = fld.cx.original_span(); let expanded = match expander.expand(fld.cx, - mac_span.call_site, + mac_span, marked_before.as_slice()).make_pat() { Some(e) => e, None => { @@ -969,7 +967,7 @@ fn new_span(cx: &ExtCtxt, sp: Span) -> Span { Span { lo: sp.lo, hi: sp.hi, - expn_info: cx.backtrace(), + expn_id: cx.backtrace(), } } @@ -1083,21 +1081,6 @@ fn mark_method(expr: P<ast::Method>, m: Mrk) -> P<ast::Method> { .expect_one("marking an item didn't return exactly one method") } -fn original_span(cx: &ExtCtxt) -> Gc<codemap::ExpnInfo> { - let mut relevant_info = cx.backtrace(); - let mut einfo = relevant_info.unwrap(); - loop { - match relevant_info { - None => { break } - Some(e) => { - einfo = e; - relevant_info = einfo.call_site.expn_info; - } - } - } - return einfo; -} - /// Check that there are no macro invocations left in the AST: pub fn check_for_macros(sess: &parse::ParseSess, krate: &ast::Crate) { visit::walk_crate(&mut MacroExterminator{sess:sess}, krate); diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index 26586684309..b760c893a10 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -19,17 +19,18 @@ use parse::token; use ptr::P; use std::collections::HashMap; +use std::string; #[deriving(PartialEq)] enum ArgumentType { - Known(String), + Known(string::String), Unsigned, String, } enum Position { Exact(uint), - Named(String), + Named(string::String), } struct Context<'a, 'b:'a> { @@ -44,12 +45,12 @@ struct Context<'a, 'b:'a> { /// Note that we keep a side-array of the ordering of the named arguments /// found to be sure that we can translate them in the same order that they /// were declared in. - names: HashMap<String, P<ast::Expr>>, - name_types: HashMap<String, ArgumentType>, - name_ordering: Vec<String>, + names: HashMap<string::String, P<ast::Expr>>, + name_types: HashMap<string::String, ArgumentType>, + name_ordering: Vec<string::String>, /// The latest consecutive literal strings, or empty if there weren't any. - literal: String, + literal: string::String, /// Collection of the compiled `rt::Argument` structures pieces: Vec<P<ast::Expr>>, @@ -58,7 +59,7 @@ struct Context<'a, 'b:'a> { /// Stays `true` if all formatting parameters are default (as in "{}{}"). all_pieces_simple: bool, - name_positions: HashMap<String, uint>, + name_positions: HashMap<string::String, uint>, method_statics: Vec<P<ast::Item>>, /// Updated as arguments are consumed or methods are entered @@ -81,10 +82,10 @@ pub enum Invocation { /// named arguments)) fn parse_args(ecx: &mut ExtCtxt, sp: Span, allow_method: bool, tts: &[ast::TokenTree]) - -> (Invocation, Option<(P<ast::Expr>, Vec<P<ast::Expr>>, Vec<String>, - HashMap<String, P<ast::Expr>>)>) { + -> (Invocation, Option<(P<ast::Expr>, Vec<P<ast::Expr>>, Vec<string::String>, + HashMap<string::String, P<ast::Expr>>)>) { let mut args = Vec::new(); - let mut names = HashMap::<String, P<ast::Expr>>::new(); + let mut names = HashMap::<string::String, P<ast::Expr>>::new(); let mut order = Vec::new(); let mut p = ecx.new_parser_from_tts(tts); @@ -167,7 +168,7 @@ impl<'a, 'b> Context<'a, 'b> { fn verify_piece(&mut self, p: &parse::Piece) { match *p { parse::String(..) => {} - parse::Argument(ref arg) => { + parse::NextArgument(ref arg) => { // width/precision first, if they have implicit positional // parameters it makes more sense to consume them first. self.verify_count(arg.format.width); @@ -222,7 +223,7 @@ impl<'a, 'b> Context<'a, 'b> { } } - fn describe_num_args(&self) -> String { + fn describe_num_args(&self) -> string::String { match self.args.len() { 0 => "no arguments given".to_string(), 1 => "there is 1 argument".to_string(), @@ -391,7 +392,7 @@ impl<'a, 'b> Context<'a, 'b> { self.literal.push_str(s); None } - parse::Argument(ref arg) => { + parse::NextArgument(ref arg) => { // Translate the position let pos = match arg.position { // These two have a direct mapping @@ -747,8 +748,8 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span, invocation: Invocation, efmt: P<ast::Expr>, args: Vec<P<ast::Expr>>, - name_ordering: Vec<String>, - names: HashMap<String, P<ast::Expr>>) + name_ordering: Vec<string::String>, + names: HashMap<string::String, P<ast::Expr>>) -> P<ast::Expr> { let arg_types = Vec::from_fn(args.len(), |_| None); let mut cx = Context { @@ -761,7 +762,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span, name_ordering: name_ordering, nest_level: 0, next_arg: 0, - literal: String::new(), + literal: string::String::new(), pieces: Vec::new(), str_pieces: Vec::new(), all_pieces_simple: true, diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 5cc0ec4a122..41967b0680c 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -11,7 +11,6 @@ use ast; use codemap; use codemap::{Pos, Span}; -use codemap::{ExpnInfo, NameAndSpan}; use ext::base::*; use ext::base; use ext::build::AstBuilder; @@ -19,7 +18,6 @@ use parse; use parse::token; use print::pprust; -use std::gc::Gc; use std::io::File; use std::rc::Rc; @@ -32,10 +30,10 @@ pub fn expand_line(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> Box<base::MacResult+'static> { base::check_zero_tts(cx, sp, tts, "line!"); - let topmost = topmost_expn_info(cx.backtrace().unwrap()); - let loc = cx.codemap().lookup_char_pos(topmost.call_site.lo); + let topmost = cx.original_span_in_file(); + let loc = cx.codemap().lookup_char_pos(topmost.lo); - base::MacExpr::new(cx.expr_uint(topmost.call_site, loc.line)) + base::MacExpr::new(cx.expr_uint(topmost, loc.line)) } /* col!(): expands to the current column number */ @@ -43,9 +41,9 @@ pub fn expand_col(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> Box<base::MacResult+'static> { base::check_zero_tts(cx, sp, tts, "col!"); - let topmost = topmost_expn_info(cx.backtrace().unwrap()); - let loc = cx.codemap().lookup_char_pos(topmost.call_site.lo); - base::MacExpr::new(cx.expr_uint(topmost.call_site, loc.col.to_uint())) + let topmost = cx.original_span_in_file(); + let loc = cx.codemap().lookup_char_pos(topmost.lo); + base::MacExpr::new(cx.expr_uint(topmost, loc.col.to_uint())) } /// file!(): expands to the current filename */ @@ -55,10 +53,10 @@ pub fn expand_file(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> Box<base::MacResult+'static> { base::check_zero_tts(cx, sp, tts, "file!"); - let topmost = topmost_expn_info(cx.backtrace().unwrap()); - let loc = cx.codemap().lookup_char_pos(topmost.call_site.lo); + let topmost = cx.original_span_in_file(); + let loc = cx.codemap().lookup_char_pos(topmost.lo); let filename = token::intern_and_get_ident(loc.file.name.as_slice()); - base::MacExpr::new(cx.expr_str(topmost.call_site, filename)) + base::MacExpr::new(cx.expr_str(topmost, filename)) } pub fn expand_stringify(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) @@ -162,32 +160,6 @@ pub fn expand_include_bin(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) } } -// recur along an ExpnInfo chain to find the original expression -fn topmost_expn_info(expn_info: Gc<codemap::ExpnInfo>) -> Gc<codemap::ExpnInfo> { - match *expn_info { - ExpnInfo { call_site: ref call_site, .. } => { - match call_site.expn_info { - Some(next_expn_info) => { - match *next_expn_info { - ExpnInfo { - callee: NameAndSpan { name: ref name, .. }, - .. - } => { - // Don't recurse into file using "include!" - if "include" == name.as_slice() { - expn_info - } else { - topmost_expn_info(next_expn_info) - } - } - } - }, - None => expn_info - } - } - } -} - // resolve a file-system path to an absolute file-system path (if it // isn't already) fn res_rel_file(cx: &mut ExtCtxt, sp: codemap::Span, arg: &Path) -> Path { diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 3beba5bcda4..7ebb11c148b 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -657,16 +657,26 @@ pub fn noop_fold_fn_decl<T: Folder>(decl: P<FnDecl>, fld: &mut T) -> P<FnDecl> { }) } -pub fn noop_fold_ty_param_bound<T: Folder>(tpb: TyParamBound, fld: &mut T) - -> TyParamBound { +pub fn noop_fold_ty_param_bound<T>(tpb: TyParamBound, fld: &mut T) + -> TyParamBound + where T: Folder { match tpb { TraitTyParamBound(ty) => TraitTyParamBound(fld.fold_trait_ref(ty)), RegionTyParamBound(lifetime) => RegionTyParamBound(fld.fold_lifetime(lifetime)), - UnboxedFnTyParamBound(UnboxedFnTy {decl, kind}) => { - UnboxedFnTyParamBound(UnboxedFnTy { - decl: fld.fold_fn_decl(decl), - kind: kind, - }) + UnboxedFnTyParamBound(bound) => { + match *bound { + UnboxedFnBound { + ref path, + ref decl, + ref_id + } => { + UnboxedFnTyParamBound(P(UnboxedFnBound { + path: fld.fold_path(path.clone()), + decl: fld.fold_fn_decl(decl.clone()), + ref_id: fld.new_id(ref_id), + })) + } + } } } } @@ -1242,6 +1252,12 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span}: Expr, folder: &mut T) -> ExprIndex(el, er) => { ExprIndex(folder.fold_expr(el), folder.fold_expr(er)) } + ExprSlice(e, e1, e2, m) => { + ExprSlice(folder.fold_expr(e), + e1.map(|x| folder.fold_expr(x)), + e2.map(|x| folder.fold_expr(x)), + m) + } ExprPath(pth) => ExprPath(folder.fold_path(pth)), ExprBreak(opt_ident) => ExprBreak(opt_ident.map(|x| folder.fold_ident(x))), ExprAgain(opt_ident) => ExprAgain(opt_ident.map(|x| folder.fold_ident(x))), diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 457d77efb70..153b3cc90d6 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -23,7 +23,7 @@ html_favicon_url = "http://www.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/master/")] -#![feature(macro_rules, globs, managed_boxes, default_type_params, phase)] +#![feature(macro_rules, globs, default_type_params, phase)] #![feature(quote, struct_variant, unsafe_destructor, import_shadowing)] #![allow(deprecated)] diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index da43f08a4e5..68ddd17dd01 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1406,7 +1406,7 @@ fn ident_continue(c: Option<char>) -> bool { mod test { use super::*; - use codemap::{BytePos, CodeMap, Span}; + use codemap::{BytePos, CodeMap, Span, NO_EXPANSION}; use diagnostic; use parse::token; use parse::token::{str_to_ident}; @@ -1436,7 +1436,7 @@ mod test { let tok1 = string_reader.next_token(); let tok2 = TokenAndSpan{ tok:token::IDENT(id, false), - sp:Span {lo:BytePos(21),hi:BytePos(23),expn_info: None}}; + sp:Span {lo:BytePos(21),hi:BytePos(23),expn_id: NO_EXPANSION}}; assert_eq!(tok1,tok2); assert_eq!(string_reader.next_token().tok, token::WS); // the 'main' id is already read: @@ -1445,7 +1445,7 @@ mod test { let tok3 = string_reader.next_token(); let tok4 = TokenAndSpan{ tok:token::IDENT(str_to_ident("main"), false), - sp:Span {lo:BytePos(24),hi:BytePos(28),expn_info: None}}; + sp:Span {lo:BytePos(24),hi:BytePos(28),expn_id: NO_EXPANSION}}; assert_eq!(tok3,tok4); // the lparen is already read: assert_eq!(string_reader.last_pos.clone(), BytePos(29)) diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index d73cb211694..66ecdbfca02 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -721,7 +721,7 @@ pub fn integer_lit(s: &str, sd: &SpanHandler, sp: Span) -> ast::Lit_ { mod test { use super::*; use serialize::json; - use codemap::{Span, BytePos, Spanned}; + use codemap::{Span, BytePos, Spanned, NO_EXPANSION}; use owned_slice::OwnedSlice; use ast; use abi; @@ -736,7 +736,7 @@ mod test { // produce a codemap::span fn sp(a: u32, b: u32) -> Span { - Span{lo:BytePos(a),hi:BytePos(b),expn_info:None} + Span {lo: BytePos(a), hi: BytePos(b), expn_id: NO_EXPANSION} } #[test] fn path_exprs_1() { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ff4fd41fbd7..069d30cbd83 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -23,7 +23,7 @@ use ast::{DeclLocal, DefaultBlock, UnDeref, BiDiv, EMPTY_CTXT, EnumDef, Explicit use ast::{Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain}; use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox}; use ast::{ExprBreak, ExprCall, ExprCast}; -use ast::{ExprField, ExprTupField, ExprFnBlock, ExprIf, ExprIndex}; +use ast::{ExprField, ExprTupField, ExprFnBlock, ExprIf, ExprIndex, ExprSlice}; use ast::{ExprLit, ExprLoop, ExprMac}; use ast::{ExprMethodCall, ExprParen, ExprPath, ExprProc}; use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary, ExprUnboxedFn}; @@ -55,7 +55,8 @@ use ast::{TyTypeof, TyInfer, TypeMethod}; use ast::{TyNil, TyParam, TyParamBound, TyParen, TyPath, TyPtr, TyQPath}; use ast::{TyRptr, TyTup, TyU32, TyUnboxedFn, TyUniq, TyVec, UnUniq}; use ast::{TypeImplItem, TypeTraitItem, Typedef, UnboxedClosureKind}; -use ast::{UnboxedFnTy, UnboxedFnTyParamBound, UnnamedField, UnsafeBlock}; +use ast::{UnboxedFnBound, UnboxedFnTy, UnboxedFnTyParamBound}; +use ast::{UnnamedField, UnsafeBlock}; use ast::{UnsafeFn, ViewItem, ViewItem_, ViewItemExternCrate, ViewItemUse}; use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple}; use ast::{Visibility, WhereClause, WherePredicate}; @@ -1986,6 +1987,14 @@ impl<'a> Parser<'a> { ExprIndex(expr, idx) } + pub fn mk_slice(&mut self, expr: P<Expr>, + start: Option<P<Expr>>, + end: Option<P<Expr>>, + mutbl: Mutability) + -> ast::Expr_ { + ExprSlice(expr, start, end, mutbl) + } + pub fn mk_field(&mut self, expr: P<Expr>, ident: ast::SpannedIdent, tys: Vec<P<Ty>>) -> ast::Expr_ { ExprField(expr, ident, tys) @@ -2400,13 +2409,87 @@ impl<'a> Parser<'a> { } // expr[...] + // Could be either an index expression or a slicing expression. + // Any slicing non-terminal can have a mutable version with `mut` + // after the opening square bracket. token::LBRACKET => { self.bump(); - let ix = self.parse_expr(); - hi = self.span.hi; - self.commit_expr_expecting(&*ix, token::RBRACKET); - let index = self.mk_index(e, ix); - e = self.mk_expr(lo, hi, index) + let mutbl = if self.eat_keyword(keywords::Mut) { + MutMutable + } else { + MutImmutable + }; + match self.token { + // e[] + token::RBRACKET => { + self.bump(); + hi = self.span.hi; + let slice = self.mk_slice(e, None, None, mutbl); + e = self.mk_expr(lo, hi, slice) + } + // e[..e] + token::DOTDOT => { + self.bump(); + match self.token { + // e[..] + token::RBRACKET => { + self.bump(); + hi = self.span.hi; + let slice = self.mk_slice(e, None, None, mutbl); + e = self.mk_expr(lo, hi, slice); + + self.span_err(e.span, "incorrect slicing expression: `[..]`"); + self.span_note(e.span, + "use `expr[]` to construct a slice of the whole of expr"); + } + // e[..e] + _ => { + hi = self.span.hi; + let e2 = self.parse_expr(); + self.commit_expr_expecting(&*e2, token::RBRACKET); + let slice = self.mk_slice(e, None, Some(e2), mutbl); + e = self.mk_expr(lo, hi, slice) + } + } + } + // e[e] | e[e..] | e[e..e] + _ => { + let ix = self.parse_expr(); + match self.token { + // e[e..] | e[e..e] + token::DOTDOT => { + self.bump(); + let e2 = match self.token { + // e[e..] + token::RBRACKET => { + self.bump(); + None + } + // e[e..e] + _ => { + let e2 = self.parse_expr(); + self.commit_expr_expecting(&*e2, token::RBRACKET); + Some(e2) + } + }; + hi = self.span.hi; + let slice = self.mk_slice(e, Some(ix), e2, mutbl); + e = self.mk_expr(lo, hi, slice) + } + // e[e] + _ => { + if mutbl == ast::MutMutable { + self.span_err(e.span, + "`mut` keyword is invalid in index expressions"); + } + hi = self.span.hi; + self.commit_expr_expecting(&*ix, token::RBRACKET); + let index = self.mk_index(e, ix); + e = self.mk_expr(lo, hi, index) + } + } + } + } } _ => return e @@ -3153,7 +3236,8 @@ impl<'a> Parser<'a> { // These expressions are limited to literals (possibly // preceded by unary-minus) or identifiers. let val = self.parse_literal_maybe_minus(); - if self.token == token::DOTDOT && + // FIXME(#17295) remove the DOTDOT option. + if (self.token == token::DOTDOTDOT || self.token == token::DOTDOT) && self.look_ahead(1, |t| { *t != token::COMMA && *t != token::RBRACKET }) { @@ -3198,12 +3282,16 @@ impl<'a> Parser<'a> { } }); - if self.look_ahead(1, |t| *t == token::DOTDOT) && + // FIXME(#17295) remove the DOTDOT option. + if self.look_ahead(1, |t| *t == token::DOTDOTDOT || *t == token::DOTDOT) && self.look_ahead(2, |t| { *t != token::COMMA && *t != token::RBRACKET }) { let start = self.parse_expr_res(RestrictionNoBarOp); - self.eat(&token::DOTDOT); + // FIXME(#17295) remove the DOTDOT option (self.eat(&token::DOTDOTDOT)). + if self.token == token::DOTDOTDOT || self.token == token::DOTDOT { + self.bump(); + } let end = self.parse_expr_res(RestrictionNoBarOp); pat = PatRange(start, end); } else if is_plain_ident(&self.token) && !can_be_enum_or_struct { @@ -3590,7 +3678,7 @@ impl<'a> Parser<'a> { let span_with_semi = Span { lo: span.lo, hi: self.last_span.hi, - expn_info: span.expn_info, + expn_id: span.expn_id, }; stmts.push(P(Spanned { node: StmtSemi(e, stmt_id), @@ -3666,39 +3754,6 @@ impl<'a> Parser<'a> { }) } - fn parse_unboxed_function_type(&mut self) -> UnboxedFnTy { - let (optional_unboxed_closure_kind, inputs) = - if self.eat(&token::OROR) { - (None, Vec::new()) - } else { - self.expect_or(); - - let optional_unboxed_closure_kind = - self.parse_optional_unboxed_closure_kind(); - - let inputs = self.parse_seq_to_before_or(&token::COMMA, - |p| { - p.parse_arg_general(false) - }); - self.expect_or(); - (optional_unboxed_closure_kind, inputs) - }; - - let (return_style, output) = self.parse_ret_ty(); - UnboxedFnTy { - decl: P(FnDecl { - inputs: inputs, - output: output, - cf: return_style, - variadic: false, - }), - kind: match optional_unboxed_closure_kind { - Some(kind) => kind, - None => FnMutUnboxedClosureKind, - }, - } - } - // Parses a sequence of bounds if a `:` is found, // otherwise returns empty list. fn parse_colon_then_ty_param_bounds(&mut self) @@ -3730,13 +3785,31 @@ impl<'a> Parser<'a> { self.bump(); } token::MOD_SEP | token::IDENT(..) => { - let tref = self.parse_trait_ref(); - result.push(TraitTyParamBound(tref)); - } - token::BINOP(token::OR) | token::OROR => { - let unboxed_function_type = - self.parse_unboxed_function_type(); - result.push(UnboxedFnTyParamBound(unboxed_function_type)); + let path = + self.parse_path(LifetimeAndTypesWithoutColons).path; + if self.token == token::LPAREN { + self.bump(); + let inputs = self.parse_seq_to_end( + &token::RPAREN, + seq_sep_trailing_allowed(token::COMMA), + |p| p.parse_arg_general(false)); + let (return_style, output) = self.parse_ret_ty(); + result.push(UnboxedFnTyParamBound(P(UnboxedFnBound { + path: path, + decl: P(FnDecl { + inputs: inputs, + output: output, + cf: return_style, + variadic: false, + }), + ref_id: ast::DUMMY_NODE_ID, + }))); + } else { + result.push(TraitTyParamBound(ast::TraitRef { + path: path, + ref_id: ast::DUMMY_NODE_ID, + })) + } } _ => break, } @@ -4423,14 +4496,6 @@ impl<'a> Parser<'a> { Some(attrs)) } - /// Parse a::B<String,int> - fn parse_trait_ref(&mut self) -> TraitRef { - ast::TraitRef { - path: self.parse_path(LifetimeAndTypesWithoutColons).path, - ref_id: ast::DUMMY_NODE_ID, - } - } - /// Parse struct Foo { ... } fn parse_item_struct(&mut self, is_virtual: bool) -> ItemInfo { let class_name = self.parse_ident(); diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 5a0aeece272..f71190da430 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -431,9 +431,11 @@ macro_rules! declare_special_idents_and_keywords {( // If the special idents get renumbered, remember to modify these two as appropriate pub static SELF_KEYWORD_NAME: Name = Name(SELF_KEYWORD_NAME_NUM); static STATIC_KEYWORD_NAME: Name = Name(STATIC_KEYWORD_NAME_NUM); +static SUPER_KEYWORD_NAME: Name = Name(SUPER_KEYWORD_NAME_NUM); pub static SELF_KEYWORD_NAME_NUM: u32 = 1; static STATIC_KEYWORD_NAME_NUM: u32 = 2; +static SUPER_KEYWORD_NAME_NUM: u32 = 3; // NB: leaving holes in the ident table is bad! a different ident will get // interned with the id from the hole, but it will be between the min and max @@ -443,52 +445,53 @@ declare_special_idents_and_keywords! { pub mod special_idents { // These ones are statics (0, invalid, ""); - (super::SELF_KEYWORD_NAME_NUM, self_, "self"); - (super::STATIC_KEYWORD_NAME_NUM, statik, "static"); - (3, static_lifetime, "'static"); + (super::SELF_KEYWORD_NAME_NUM, self_, "self"); + (super::STATIC_KEYWORD_NAME_NUM, statik, "static"); + (super::SUPER_KEYWORD_NAME_NUM, super_, "super"); + (4, static_lifetime, "'static"); // for matcher NTs - (4, tt, "tt"); - (5, matchers, "matchers"); + (5, tt, "tt"); + (6, matchers, "matchers"); // outside of libsyntax - (6, clownshoe_abi, "__rust_abi"); - (7, opaque, "<opaque>"); - (8, unnamed_field, "<unnamed_field>"); - (9, type_self, "Self"); - (10, prelude_import, "prelude_import"); + (7, clownshoe_abi, "__rust_abi"); + (8, opaque, "<opaque>"); + (9, unnamed_field, "<unnamed_field>"); + (10, type_self, "Self"); + (11, prelude_import, "prelude_import"); } pub mod keywords { // These ones are variants of the Keyword enum 'strict: - (11, As, "as"); - (12, Break, "break"); - (13, Crate, "crate"); - (14, Else, "else"); - (15, Enum, "enum"); - (16, Extern, "extern"); - (17, False, "false"); - (18, Fn, "fn"); - (19, For, "for"); - (20, If, "if"); - (21, Impl, "impl"); - (22, In, "in"); - (23, Let, "let"); - (24, Loop, "loop"); - (25, Match, "match"); - (26, Mod, "mod"); - (27, Mut, "mut"); - (28, Once, "once"); - (29, Pub, "pub"); - (30, Ref, "ref"); - (31, Return, "return"); + (12, As, "as"); + (13, Break, "break"); + (14, Crate, "crate"); + (15, Else, "else"); + (16, Enum, "enum"); + (17, Extern, "extern"); + (18, False, "false"); + (19, Fn, "fn"); + (20, For, "for"); + (21, If, "if"); + (22, Impl, "impl"); + (23, In, "in"); + (24, Let, "let"); + (25, Loop, "loop"); + (26, Match, "match"); + (27, Mod, "mod"); + (28, Mut, "mut"); + (29, Once, "once"); + (30, Pub, "pub"); + (31, Ref, "ref"); + (32, Return, "return"); // Static and Self are also special idents (prefill de-dupes) - (super::STATIC_KEYWORD_NAME_NUM, Static, "static"); - (super::SELF_KEYWORD_NAME_NUM, Self, "self"); - (32, Struct, "struct"); - (33, Super, "super"); + (super::STATIC_KEYWORD_NAME_NUM, Static, "static"); + (super::SELF_KEYWORD_NAME_NUM, Self, "self"); + (33, Struct, "struct"); + (super::SUPER_KEYWORD_NAME_NUM, Super, "super"); (34, True, "true"); (35, Trait, "trait"); (36, Type, "type"); @@ -713,6 +716,7 @@ pub fn is_any_keyword(tok: &Token) -> bool { n == SELF_KEYWORD_NAME || n == STATIC_KEYWORD_NAME + || n == SUPER_KEYWORD_NAME || STRICT_KEYWORD_START <= n && n <= RESERVED_KEYWORD_FINAL }, @@ -727,9 +731,18 @@ pub fn is_strict_keyword(tok: &Token) -> bool { n == SELF_KEYWORD_NAME || n == STATIC_KEYWORD_NAME + || n == SUPER_KEYWORD_NAME || STRICT_KEYWORD_START <= n && n <= STRICT_KEYWORD_FINAL }, + token::IDENT(sid, true) => { + let n = sid.name; + + n != SELF_KEYWORD_NAME + && n != SUPER_KEYWORD_NAME + && STRICT_KEYWORD_START <= n + && n <= STRICT_KEYWORD_FINAL + } _ => false, } } diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index 70da4e11961..f1fdc71b9c6 100644 --- a/src/libsyntax/print/pp.rs +++ b/src/libsyntax/print/pp.rs @@ -60,7 +60,7 @@ //! avoid combining it with other lines and making matters even worse. use std::io; -use std::string::String; +use std::string; #[deriving(Clone, PartialEq)] pub enum Breaks { @@ -82,7 +82,7 @@ pub struct BeginToken { #[deriving(Clone)] pub enum Token { - String(String, int), + String(string::String, int), Break(BreakToken), Begin(BeginToken), End, @@ -107,7 +107,7 @@ impl Token { } } -pub fn tok_str(t: Token) -> String { +pub fn tok_str(t: Token) -> string::String { match t { String(s, len) => return format!("STR({},{})", s, len), Break(_) => return "BREAK".to_string(), @@ -122,12 +122,12 @@ pub fn buf_str(toks: Vec<Token>, left: uint, right: uint, lim: uint) - -> String { + -> string::String { let n = toks.len(); assert_eq!(n, szs.len()); let mut i = left; let mut l = lim; - let mut s = String::from_str("["); + let mut s = string::String::from_str("["); while i != right && l != 0u { l -= 1u; if i != left { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 0ae5303641b..473179a037a 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1651,6 +1651,28 @@ impl<'a> State<'a> { try!(self.print_expr(&**index)); try!(word(&mut self.s, "]")); } + ast::ExprSlice(ref e, ref start, ref end, ref mutbl) => { + try!(self.print_expr(&**e)); + try!(word(&mut self.s, "[")); + if mutbl == &ast::MutMutable { + try!(word(&mut self.s, "mut")); + if start.is_some() || end.is_some() { + try!(space(&mut self.s)); + } + } + match start { + &Some(ref e) => try!(self.print_expr(&**e)), + _ => {} + } + if start.is_some() || end.is_some() { + try!(word(&mut self.s, "..")); + } + match end { + &Some(ref e) => try!(self.print_expr(&**e)), + _ => {} + } + try!(word(&mut self.s, "]")); + } ast::ExprPath(ref path) => try!(self.print_path(path, true)), ast::ExprBreak(opt_ident) => { try!(word(&mut self.s, "break")); @@ -1944,7 +1966,7 @@ impl<'a> State<'a> { ast::PatRange(ref begin, ref end) => { try!(self.print_expr(&**begin)); try!(space(&mut self.s)); - try!(word(&mut self.s, "..")); + try!(word(&mut self.s, "...")); try!(self.print_expr(&**end)); } ast::PatVec(ref before, ref slice, ref after) => { @@ -2190,16 +2212,13 @@ impl<'a> State<'a> { self.print_lifetime(lt) } UnboxedFnTyParamBound(ref unboxed_function_type) => { - self.print_ty_fn(None, - None, - ast::NormalFn, - ast::Many, - &*unboxed_function_type.decl, - None, - &OwnedSlice::empty(), - None, - None, - Some(unboxed_function_type.kind)) + try!(self.print_path(&unboxed_function_type.path, + false)); + try!(self.popen()); + try!(self.print_fn_args(&*unboxed_function_type.decl, + None)); + try!(self.pclose()); + self.print_fn_output(&*unboxed_function_type.decl) } }) } @@ -2430,6 +2449,23 @@ impl<'a> State<'a> { self.end() } + pub fn print_fn_output(&mut self, decl: &ast::FnDecl) -> IoResult<()> { + match decl.output.node { + ast::TyNil => Ok(()), + _ => { + try!(self.space_if_not_bol()); + try!(self.ibox(indent_unit)); + try!(self.word_space("->")); + if decl.cf == ast::NoReturn { + try!(self.word_nbsp("!")); + } else { + try!(self.print_type(&*decl.output)); + } + self.end() + } + } + } + pub fn print_ty_fn(&mut self, opt_abi: Option<abi::Abi>, opt_sigil: Option<char>, @@ -2510,20 +2546,7 @@ impl<'a> State<'a> { try!(self.maybe_print_comment(decl.output.span.lo)); - match decl.output.node { - ast::TyNil => {} - _ => { - try!(self.space_if_not_bol()); - try!(self.ibox(indent_unit)); - try!(self.word_space("->")); - if decl.cf == ast::NoReturn { - try!(self.word_nbsp("!")); - } else { - try!(self.print_type(&*decl.output)); - } - try!(self.end()); - } - } + try!(self.print_fn_output(decl)); match generics { Some(generics) => try!(self.print_where_clause(generics)), diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index d425c60f4c9..32084856817 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -785,6 +785,11 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { visitor.visit_expr(&**main_expression); visitor.visit_expr(&**index_expression) } + ExprSlice(ref main_expression, ref start, ref end, _) => { + visitor.visit_expr(&**main_expression); + walk_expr_opt(visitor, start); + walk_expr_opt(visitor, end) + } ExprPath(ref path) => { visitor.visit_path(path, expression.id) } diff --git a/src/libterm/terminfo/parm.rs b/src/libterm/terminfo/parm.rs index e6fc64cbd3b..93f773f430d 100644 --- a/src/libterm/terminfo/parm.rs +++ b/src/libterm/terminfo/parm.rs @@ -41,7 +41,7 @@ enum FormatState { #[allow(missing_doc)] #[deriving(Clone)] pub enum Param { - String(String), + Words(String), Number(int) } @@ -140,8 +140,8 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) '{' => state = IntConstant(0), 'l' => if stack.len() > 0 { match stack.pop().unwrap() { - String(s) => stack.push(Number(s.len() as int)), - _ => return Err("a non-str was used with %l".to_string()) + Words(s) => stack.push(Number(s.len() as int)), + _ => return Err("a non-str was used with %l".to_string()) } } else { return Err("stack is empty".to_string()) }, '+' => if stack.len() > 1 { @@ -543,7 +543,7 @@ fn format(val: Param, op: FormatOp, flags: Flags) -> Result<Vec<u8> ,String> { } s } - String(s) => { + Words(s) => { match op { FormatString => { let mut s = Vec::from_slice(s.as_bytes()); @@ -575,7 +575,7 @@ fn format(val: Param, op: FormatOp, flags: Flags) -> Result<Vec<u8> ,String> { #[cfg(test)] mod test { - use super::{expand,String,Variables,Number}; + use super::{expand,Words,Variables,Number}; use std::result::Ok; #[test] @@ -611,7 +611,7 @@ mod test { assert!(res.is_err(), "Op {} succeeded incorrectly with 0 stack entries", *cap); let p = if *cap == "%s" || *cap == "%l" { - String("foo".to_string()) + Words("foo".to_string()) } else { Number(97) }; @@ -689,12 +689,12 @@ mod test { let mut varstruct = Variables::new(); let vars = &mut varstruct; assert_eq!(expand(b"%p1%s%p2%2s%p3%2s%p4%.2s", - [String("foo".to_string()), - String("foo".to_string()), - String("f".to_string()), - String("foo".to_string())], vars), + [Words("foo".to_string()), + Words("foo".to_string()), + Words("f".to_string()), + Words("foo".to_string())], vars), Ok("foofoo ffo".bytes().collect())); - assert_eq!(expand(b"%p1%:-4.2s", [String("foo".to_string())], vars), + assert_eq!(expand(b"%p1%:-4.2s", [Words("foo".to_string())], vars), Ok("fo ".bytes().collect())); assert_eq!(expand(b"%p1%d%p1%.3d%p1%5d%p1%:+d", [Number(1)], vars), diff --git a/src/test/auxiliary/issue_16723_multiple_items_syntax_ext.rs b/src/test/auxiliary/issue_16723_multiple_items_syntax_ext.rs new file mode 100644 index 00000000000..269afea52c2 --- /dev/null +++ b/src/test/auxiliary/issue_16723_multiple_items_syntax_ext.rs @@ -0,0 +1,33 @@ +// 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +// +// ignore-stage1 +#![feature(plugin_registrar, managed_boxes, quote)] +#![crate_type = "dylib"] + +extern crate syntax; +extern crate rustc; + +use syntax::ast; +use syntax::codemap; +use syntax::ext::base::{ExtCtxt, MacResult, MacItems}; +use rustc::plugin::Registry; + +#[plugin_registrar] +pub fn plugin_registrar(reg: &mut Registry) { + reg.register_macro("multiple_items", expand) +} + +fn expand(cx: &mut ExtCtxt, _: codemap::Span, _: &[ast::TokenTree]) -> Box<MacResult+'static> { + MacItems::new(vec![ + quote_item!(cx, struct Struct1;).unwrap(), + quote_item!(cx, struct Struct2;).unwrap() + ].into_iter()) +} diff --git a/src/test/auxiliary/macro_crate_test.rs b/src/test/auxiliary/macro_crate_test.rs index dd1f9c3404f..befd33fca4e 100644 --- a/src/test/auxiliary/macro_crate_test.rs +++ b/src/test/auxiliary/macro_crate_test.rs @@ -35,7 +35,7 @@ pub fn plugin_registrar(reg: &mut Registry) { reg.register_macro("identity", expand_identity); reg.register_syntax_extension( token::intern("into_foo"), - ItemModifier(box expand_into_foo)); + Modifier(box expand_into_foo)); } fn expand_make_a_1(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) diff --git a/src/test/auxiliary/xcrate_unit_struct.rs b/src/test/auxiliary/xcrate_unit_struct.rs index 7619513a2a6..6487c704765 100644 --- a/src/test/auxiliary/xcrate_unit_struct.rs +++ b/src/test/auxiliary/xcrate_unit_struct.rs @@ -15,7 +15,7 @@ pub struct Struct; pub enum Unit { - Unit, + UnitVariant, Argument(Struct) } diff --git a/src/test/compile-fail/borrowck-closures-unique.rs b/src/test/compile-fail/borrowck-closures-unique.rs index 80d942e58d1..61c77ce7bba 100644 --- a/src/test/compile-fail/borrowck-closures-unique.rs +++ b/src/test/compile-fail/borrowck-closures-unique.rs @@ -43,7 +43,7 @@ fn d(x: &mut int) { } fn e(x: &mut int) { - let c1: || = || x = fail!(); //~ ERROR closure cannot assign to immutable argument `x` + let c1: || = || x = fail!(); //~ ERROR closure cannot assign to immutable local variable } fn main() { diff --git a/src/test/compile-fail/borrowck-unboxed-closures.rs b/src/test/compile-fail/borrowck-unboxed-closures.rs index d822bb22e2a..5f9dd72f5bf 100644 --- a/src/test/compile-fail/borrowck-unboxed-closures.rs +++ b/src/test/compile-fail/borrowck-unboxed-closures.rs @@ -10,17 +10,17 @@ #![feature(overloaded_calls)] -fn a<F:|&: int, int| -> int>(mut f: F) { +fn a<F:Fn(int, int) -> int>(mut f: F) { let g = &mut f; f(1, 2); //~ ERROR cannot borrow `f` as immutable //~^ ERROR cannot borrow `f` as immutable } -fn b<F:|&mut: int, int| -> int>(f: F) { - f(1, 2); //~ ERROR cannot borrow immutable argument +fn b<F:FnMut(int, int) -> int>(f: F) { + f(1, 2); //~ ERROR cannot borrow immutable local variable } -fn c<F:|: int, int| -> int>(f: F) { +fn c<F:FnOnce(int, int) -> int>(f: F) { f(1, 2); f(1, 2); //~ ERROR use of moved value } diff --git a/src/test/compile-fail/enum-variant-type-2.rs b/src/test/compile-fail/enum-variant-type-2.rs new file mode 100644 index 00000000000..bf80626793d --- /dev/null +++ b/src/test/compile-fail/enum-variant-type-2.rs @@ -0,0 +1,19 @@ +// Copyright 2014 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that enum variants are not actually types. + +enum Foo { + Bar +} + +fn foo(x: Bar) {} //~ERROR found value name used as a type + +fn main() {} diff --git a/src/test/compile-fail/enum-variant-type.rs b/src/test/compile-fail/enum-variant-type.rs new file mode 100644 index 00000000000..93d44f96c8a --- /dev/null +++ b/src/test/compile-fail/enum-variant-type.rs @@ -0,0 +1,23 @@ +// Copyright 2014 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that enum variants are in the type namespace. + +enum Foo { + Foo //~ERROR duplicate definition of type or module `Foo` +} + +enum Bar { + Baz +} + +trait Baz {} //~ERROR duplicate definition of type or module `Baz` + +pub fn main() {} diff --git a/src/test/compile-fail/issue-3008-1.rs b/src/test/compile-fail/issue-3008-1.rs index 3613fb8ccbe..d2d7d800470 100644 --- a/src/test/compile-fail/issue-3008-1.rs +++ b/src/test/compile-fail/issue-3008-1.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum foo { foo(bar) } +enum foo { foo_(bar) } enum bar { bar_none, bar_some(bar) } //~^ ERROR illegal recursive enum type; wrap the inner value in a box to make it representable diff --git a/src/test/compile-fail/issue-3008-2.rs b/src/test/compile-fail/issue-3008-2.rs index db3124214bd..1e8f81a05e7 100644 --- a/src/test/compile-fail/issue-3008-2.rs +++ b/src/test/compile-fail/issue-3008-2.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum foo { foo(bar) } +enum foo { foo_(bar) } struct bar { x: bar } //~^ ERROR illegal recursive struct type; wrap the inner value in a box to make it representable //~^^ ERROR this type cannot be instantiated without an instance of itself diff --git a/src/test/run-pass/issue-3186.rs b/src/test/compile-fail/keywords-followed-by-double-colon.rs index 6b35cd7e0c9..f69b041597e 100644 --- a/src/test/run-pass/issue-3186.rs +++ b/src/test/compile-fail/keywords-followed-by-double-colon.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum y { x } +fn main() { + struct::foo(); //~ ERROR expected identifier + mut::baz(); //~ ERROR expected identifier +} -enum x {} - -pub fn main() {} diff --git a/src/test/compile-fail/qquote-1.rs b/src/test/compile-fail/qquote-1.rs index 365a2fbe287..06d473baea8 100644 --- a/src/test/compile-fail/qquote-1.rs +++ b/src/test/compile-fail/qquote-1.rs @@ -39,7 +39,7 @@ impl fake_ext_ctxt for fake_session { codemap::span { lo: codemap::BytePos(0), hi: codemap::BytePos(0), - expn_info: None + expn_id: NO_EXPANSION } } fn ident_of(st: &str) -> ast::ident { diff --git a/src/test/compile-fail/qquote-2.rs b/src/test/compile-fail/qquote-2.rs index f202f1bb73c..f63dd91eb2b 100644 --- a/src/test/compile-fail/qquote-2.rs +++ b/src/test/compile-fail/qquote-2.rs @@ -36,7 +36,7 @@ impl fake_ext_ctxt for fake_session { codemap::span { lo: codemap::BytePos(0), hi: codemap::BytePos(0), - expn_info: None + expn_id: codemap::NO_EXPANSION } } fn ident_of(st: &str) -> ast::ident { diff --git a/src/test/compile-fail/recursion.rs b/src/test/compile-fail/recursion.rs index 96676257184..c99ec5187b0 100644 --- a/src/test/compile-fail/recursion.rs +++ b/src/test/compile-fail/recursion.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum Nil {Nil} +enum Nil {NilValue} struct Cons<T> {head:int, tail:T} trait Dot {fn dot(&self, other:Self) -> int;} impl Dot for Nil { @@ -29,6 +29,6 @@ fn test<T:Dot> (n:int, i:int, first:T, second:T) ->int { } } pub fn main() { - let n = test(1, 0, Nil, Nil); + let n = test(1, 0, NilValue, NilValue); println!("{}", n); } diff --git a/src/test/compile-fail/slice-1.rs b/src/test/compile-fail/slice-1.rs new file mode 100644 index 00000000000..d0339745c9e --- /dev/null +++ b/src/test/compile-fail/slice-1.rs @@ -0,0 +1,19 @@ +// Copyright 2014 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test slicing expr[..] is an error and gives a helpful error message. + +struct Foo; + +fn main() { + let x = Foo; + x[..]; //~ ERROR incorrect slicing expression: `[..]` + //~^ NOTE use `expr[]` to construct a slice of the whole of expr +} diff --git a/src/test/compile-fail/slice-2.rs b/src/test/compile-fail/slice-2.rs new file mode 100644 index 00000000000..fbfc438321c --- /dev/null +++ b/src/test/compile-fail/slice-2.rs @@ -0,0 +1,25 @@ +// Copyright 2014 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that slicing syntax gives errors if we have not implemented the trait. + +struct Foo; + +fn main() { + let x = Foo; + x[]; //~ ERROR cannot take a slice of a value with type `Foo` + x[Foo..]; //~ ERROR cannot take a slice of a value with type `Foo` + x[..Foo]; //~ ERROR cannot take a slice of a value with type `Foo` + x[Foo..Foo]; //~ ERROR cannot take a slice of a value with type `Foo` + x[mut]; //~ ERROR cannot take a mutable slice of a value with type `Foo` + x[mut Foo..]; //~ ERROR cannot take a mutable slice of a value with type `Foo` + x[mut ..Foo]; //~ ERROR cannot take a mutable slice of a value with type `Foo` + x[mut Foo..Foo]; //~ ERROR cannot take a mutable slice of a value with type `Foo` +} diff --git a/src/test/compile-fail/slice-borrow.rs b/src/test/compile-fail/slice-borrow.rs new file mode 100644 index 00000000000..3d12511134f --- /dev/null +++ b/src/test/compile-fail/slice-borrow.rs @@ -0,0 +1,19 @@ +// Copyright 2014 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test slicing expressions doesn't defeat the borrow checker. + +fn main() { + let y; + { + let x: &[int] = &[1, 2, 3, 4, 5]; //~ ERROR borrowed value does not live long enough + y = x[1..]; + } +} diff --git a/src/test/compile-fail/slice-mut-2.rs b/src/test/compile-fail/slice-mut-2.rs new file mode 100644 index 00000000000..1176b637cec --- /dev/null +++ b/src/test/compile-fail/slice-mut-2.rs @@ -0,0 +1,17 @@ +// Copyright 2014 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test mutability and slicing syntax. + +fn main() { + let x: &[int] = &[1, 2, 3, 4, 5]; + // Can't mutably slice an immutable slice + let y = x[mut 2..4]; //~ ERROR cannot take a mutable slice of a value with type `&[int]` +} diff --git a/src/test/compile-fail/slice-mut.rs b/src/test/compile-fail/slice-mut.rs new file mode 100644 index 00000000000..8cd7c4ed0bb --- /dev/null +++ b/src/test/compile-fail/slice-mut.rs @@ -0,0 +1,22 @@ +// Copyright 2014 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test mutability and slicing syntax. + +fn main() { + let x: &[int] = &[1, 2, 3, 4, 5]; + // Immutable slices are not mutable. + let y: &mut[_] = x[2..4]; //~ ERROR cannot borrow immutable dereference of `&`-pointer as mutabl + + let x: &mut [int] = &mut [1, 2, 3, 4, 5]; + // Can't borrow mutably twice + let y = x[mut 1..2]; + let y = x[mut 4..5]; //~ERROR cannot borrow +} diff --git a/src/test/compile-fail/unboxed-closure-sugar-nonexistent-trait.rs b/src/test/compile-fail/unboxed-closure-sugar-nonexistent-trait.rs new file mode 100644 index 00000000000..f51160a1b23 --- /dev/null +++ b/src/test/compile-fail/unboxed-closure-sugar-nonexistent-trait.rs @@ -0,0 +1,18 @@ +// Copyright 2014 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn f<F:Nonexist(int) -> int>(x: F) {} //~ ERROR unresolved trait + +type Typedef = int; + +fn g<F:Typedef(int) -> int>(x: F) {} //~ ERROR `Typedef` is not a trait + +fn main() {} + diff --git a/src/test/compile-fail/unboxed-closure-sugar-wrong-trait.rs b/src/test/compile-fail/unboxed-closure-sugar-wrong-trait.rs new file mode 100644 index 00000000000..a751ae1c518 --- /dev/null +++ b/src/test/compile-fail/unboxed-closure-sugar-wrong-trait.rs @@ -0,0 +1,17 @@ +// Copyright 2014 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait Trait {} + +fn f<F:Trait(int) -> int>(x: F) {} +//~^ ERROR unboxed function trait must be one of `Fn`, `FnMut`, or `FnOnce` + +fn main() {} + diff --git a/src/test/compile-fail/unboxed-closures-wrong-trait.rs b/src/test/compile-fail/unboxed-closures-wrong-trait.rs index 27f1da75c3a..97ad64a77ba 100644 --- a/src/test/compile-fail/unboxed-closures-wrong-trait.rs +++ b/src/test/compile-fail/unboxed-closures-wrong-trait.rs @@ -10,7 +10,7 @@ #![feature(lang_items, overloaded_calls, unboxed_closures)] -fn c<F:|: int, int| -> int>(f: F) -> int { +fn c<F:FnOnce(int, int) -> int>(f: F) -> int { f(5, 6) } diff --git a/src/test/pretty/tag-blank-lines.rs b/src/test/pretty/tag-blank-lines.rs index 93373b0066d..29a3b965251 100644 --- a/src/test/pretty/tag-blank-lines.rs +++ b/src/test/pretty/tag-blank-lines.rs @@ -11,8 +11,8 @@ // pp-exact enum foo { - foo, // a foo. - bar, + bar, // a bar. + baz, } fn main() { } diff --git a/src/test/run-fail/issue-2444.rs b/src/test/run-fail/issue-2444.rs index dbe2a9e9229..9a5a8e7c38f 100644 --- a/src/test/run-fail/issue-2444.rs +++ b/src/test/run-fail/issue-2444.rs @@ -12,7 +12,7 @@ use std::sync::Arc; -enum e<T> { e(Arc<T>) } +enum e<T> { ee(Arc<T>) } fn foo() -> e<int> {fail!();} diff --git a/src/test/run-pass-fulldeps/issue_16723_multiple_items_syntax_ext.rs b/src/test/run-pass-fulldeps/issue_16723_multiple_items_syntax_ext.rs new file mode 100644 index 00000000000..c5cfabd74e1 --- /dev/null +++ b/src/test/run-pass-fulldeps/issue_16723_multiple_items_syntax_ext.rs @@ -0,0 +1,31 @@ +// 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-stage1 +// ignore-android +// aux-build:issue_16723_multiple_items_syntax_ext.rs +#![feature(phase)] + +#[phase(plugin)] extern crate issue_16723_multiple_items_syntax_ext; + +multiple_items!() + +impl Struct1 { + fn foo() {} +} +impl Struct2 { + fn foo() {} +} + +fn main() { + Struct1::foo(); + Struct2::foo(); + println!("hallo"); +} diff --git a/src/test/run-pass-fulldeps/qquote.rs b/src/test/run-pass-fulldeps/qquote.rs index a5cf8e46b7e..252d297d12d 100644 --- a/src/test/run-pass-fulldeps/qquote.rs +++ b/src/test/run-pass-fulldeps/qquote.rs @@ -41,7 +41,7 @@ impl fake_ext_ctxt for fake_session { codemap::span { lo: codemap::BytePos(0), hi: codemap::BytePos(0), - expn_info: None + expn_id: codemap::NO_EXPANSION } } fn ident_of(st: &str) -> ast::ident { diff --git a/src/test/run-pass/borrowck-univariant-enum.rs b/src/test/run-pass/borrowck-univariant-enum.rs index 0910f02dc29..8192566da19 100644 --- a/src/test/run-pass/borrowck-univariant-enum.rs +++ b/src/test/run-pass/borrowck-univariant-enum.rs @@ -13,7 +13,7 @@ use std::cell::Cell; use std::gc::GC; enum newtype { - newtype(int) + newvar(int) } pub fn main() { @@ -22,9 +22,9 @@ pub fn main() { // specially. let x = box(GC) Cell::new(5); - let y = box(GC) Cell::new(newtype(3)); + let y = box(GC) Cell::new(newvar(3)); let z = match y.get() { - newtype(b) => { + newvar(b) => { x.set(x.get() + 1); x.get() * b } diff --git a/src/test/run-pass/coerce-to-closure-and-proc.rs b/src/test/run-pass/coerce-to-closure-and-proc.rs index 15870b627b2..44a3517cc75 100644 --- a/src/test/run-pass/coerce-to-closure-and-proc.rs +++ b/src/test/run-pass/coerce-to-closure-and-proc.rs @@ -17,7 +17,7 @@ struct Foo<T>(T); #[deriving(PartialEq, Show)] enum Bar<T> { - Bar(T) + Baz(T) } pub fn main() { @@ -33,11 +33,11 @@ pub fn main() { let f: proc(int) -> Foo<int> = Foo; assert_eq!(f(5), Foo(5)); - let f: |int| -> Bar<int> = Bar; - assert_eq!(f(5), Bar(5)); + let f: |int| -> Bar<int> = Baz; + assert_eq!(f(5), Baz(5)); - let f: proc(int) -> Bar<int> = Bar; - assert_eq!(f(5), Bar(5)); + let f: proc(int) -> Bar<int> = Baz; + assert_eq!(f(5), Baz(5)); let f: |int| -> Option<int> = Some; assert_eq!(f(5), Some(5)); diff --git a/src/test/run-pass/fn-trait-sugar.rs b/src/test/run-pass/fn-trait-sugar.rs index ccb5634f7a2..b0947f46a86 100644 --- a/src/test/run-pass/fn-trait-sugar.rs +++ b/src/test/run-pass/fn-trait-sugar.rs @@ -21,7 +21,7 @@ impl FnMut<(int,),int> for S { } } -fn call_it<F:|int|->int>(mut f: F, x: int) -> int { +fn call_it<F:FnMut(int)->int>(mut f: F, x: int) -> int { f.call_mut((x,)) + 3 } diff --git a/src/test/run-pass/issue-2804.rs b/src/test/run-pass/issue-2804.rs index d4b77ea4976..b160fa34c91 100644 --- a/src/test/run-pass/issue-2804.rs +++ b/src/test/run-pass/issue-2804.rs @@ -22,7 +22,7 @@ enum object { int_value(i64), } -fn lookup(table: json::Object, key: String, default: String) -> String +fn lookup(table: json::JsonObject, key: String, default: String) -> String { match table.find(&key.to_string()) { option::Some(&json::String(ref s)) => { diff --git a/src/test/run-pass/issue-3874.rs b/src/test/run-pass/issue-3874.rs index 40725311f31..75f6a2faa80 100644 --- a/src/test/run-pass/issue-3874.rs +++ b/src/test/run-pass/issue-3874.rs @@ -8,10 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum PureCounter { PureCounter(uint) } +enum PureCounter { PureCounterVariant(uint) } fn each(thing: PureCounter, blk: |v: &uint|) { - let PureCounter(ref x) = thing; + let PureCounterVariant(ref x) = thing; blk(x); } diff --git a/src/test/run-pass/match-arm-statics.rs b/src/test/run-pass/match-arm-statics.rs index a8f6d9c3917..6eb0a4dad1b 100644 --- a/src/test/run-pass/match-arm-statics.rs +++ b/src/test/run-pass/match-arm-statics.rs @@ -88,10 +88,10 @@ fn issue_14576() { } fn issue_13731() { - enum A { A(()) } - static B: A = A(()); + enum A { AA(()) } + static B: A = AA(()); - match A(()) { + match AA(()) { B => () } } diff --git a/src/test/run-pass/match-range-static.rs b/src/test/run-pass/match-range-static.rs index 039b3f9a26c..08875699245 100644 --- a/src/test/run-pass/match-range-static.rs +++ b/src/test/run-pass/match-range-static.rs @@ -13,7 +13,7 @@ static e: int = 42; pub fn main() { match 7 { - s..e => (), + s...e => (), _ => (), } } diff --git a/src/test/compile-fail/sepcomp-lib-lto.rs b/src/test/run-pass/sepcomp-lib-lto.rs index 59706e20bed..51fd83a54cc 100644 --- a/src/test/compile-fail/sepcomp-lib-lto.rs +++ b/src/test/run-pass/sepcomp-lib-lto.rs @@ -8,12 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Make sure we give a sane error message when the user requests LTO with a -// library built with -C codegen-units > 1. +// Check that we can use `-Z lto` when linking against libraries that were +// separately compiled. // aux-build:sepcomp_lib.rs // compile-flags: -Z lto -// error-pattern:missing compressed bytecode // no-prefer-dynamic extern crate sepcomp_lib; diff --git a/src/test/run-pass/slice-2.rs b/src/test/run-pass/slice-2.rs new file mode 100644 index 00000000000..3c0933a055c --- /dev/null +++ b/src/test/run-pass/slice-2.rs @@ -0,0 +1,69 @@ +// Copyright 2014 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test slicing expressions on slices and Vecs. + +fn main() { + let x: &[int] = &[1, 2, 3, 4, 5]; + let cmp: &[int] = &[1, 2, 3, 4, 5]; + assert!(x[] == cmp) + let cmp: &[int] = &[3, 4, 5]; + assert!(x[2..] == cmp) + let cmp: &[int] = &[1, 2, 3]; + assert!(x[..3] == cmp) + let cmp: &[int] = &[2, 3, 4]; + assert!(x[1..4] == cmp) + + let x: Vec<int> = vec![1, 2, 3, 4, 5]; + let cmp: &[int] = &[1, 2, 3, 4, 5]; + assert!(x[] == cmp) + let cmp: &[int] = &[3, 4, 5]; + assert!(x[2..] == cmp) + let cmp: &[int] = &[1, 2, 3]; + assert!(x[..3] == cmp) + let cmp: &[int] = &[2, 3, 4]; + assert!(x[1..4] == cmp) + + let x: &mut [int] = &mut [1, 2, 3, 4, 5]; + { + let cmp: &mut [int] = &mut [1, 2, 3, 4, 5]; + assert!(x[mut] == cmp) + } + { + let cmp: &mut [int] = &mut [3, 4, 5]; + assert!(x[mut 2..] == cmp) + } + { + let cmp: &mut [int] = &mut [1, 2, 3]; + assert!(x[mut ..3] == cmp) + } + { + let cmp: &mut [int] = &mut [2, 3, 4]; + assert!(x[mut 1..4] == cmp) + } + + let mut x: Vec<int> = vec![1, 2, 3, 4, 5]; + { + let cmp: &mut [int] = &mut [1, 2, 3, 4, 5]; + assert!(x[mut] == cmp) + } + { + let cmp: &mut [int] = &mut [3, 4, 5]; + assert!(x[mut 2..] == cmp) + } + { + let cmp: &mut [int] = &mut [1, 2, 3]; + assert!(x[mut ..3] == cmp) + } + { + let cmp: &mut [int] = &mut [2, 3, 4]; + assert!(x[mut 1..4] == cmp) + } +} diff --git a/src/test/run-pass/slice-fail-1.rs b/src/test/run-pass/slice-fail-1.rs new file mode 100644 index 00000000000..f6972023a72 --- /dev/null +++ b/src/test/run-pass/slice-fail-1.rs @@ -0,0 +1,31 @@ +// Copyright 2014 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that is a slicing expr[..] fails, the correct cleanups happen. + +use std::task; + +struct Foo; + +static mut DTOR_COUNT: int = 0; + +impl Drop for Foo { + fn drop(&mut self) { unsafe { DTOR_COUNT += 1; } } +} + +fn foo() { + let x: &[_] = &[Foo, Foo]; + x[3..4]; +} + +fn main() { + let _ = task::try(proc() foo()); + unsafe { assert!(DTOR_COUNT == 2); } +} diff --git a/src/test/run-pass/slice-fail-2.rs b/src/test/run-pass/slice-fail-2.rs new file mode 100644 index 00000000000..cbe65fcd83d --- /dev/null +++ b/src/test/run-pass/slice-fail-2.rs @@ -0,0 +1,35 @@ +// Copyright 2014 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that is a slicing expr[..] fails, the correct cleanups happen. + +use std::task; + +struct Foo; + +static mut DTOR_COUNT: int = 0; + +impl Drop for Foo { + fn drop(&mut self) { unsafe { DTOR_COUNT += 1; } } +} + +fn bar() -> uint { + fail!(); +} + +fn foo() { + let x: &[_] = &[Foo, Foo]; + x[3..bar()]; +} + +fn main() { + let _ = task::try(proc() foo()); + unsafe { assert!(DTOR_COUNT == 2); } +} diff --git a/src/test/run-pass/slice.rs b/src/test/run-pass/slice.rs new file mode 100644 index 00000000000..39feb075add --- /dev/null +++ b/src/test/run-pass/slice.rs @@ -0,0 +1,70 @@ +// Copyright 2014 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test slicing sugar. + +extern crate core; +use core::ops::{Slice,SliceMut}; + +static mut COUNT: uint = 0; + +struct Foo; + +impl Slice<Foo, Foo> for Foo { + fn as_slice_<'a>(&'a self) -> &'a Foo { + unsafe { COUNT += 1; } + self + } + fn slice_from_<'a>(&'a self, _from: &Foo) -> &'a Foo { + unsafe { COUNT += 1; } + self + } + fn slice_to_<'a>(&'a self, _to: &Foo) -> &'a Foo { + unsafe { COUNT += 1; } + self + } + fn slice_<'a>(&'a self, _from: &Foo, _to: &Foo) -> &'a Foo { + unsafe { COUNT += 1; } + self + } +} + +impl SliceMut<Foo, Foo> for Foo { + fn as_mut_slice_<'a>(&'a mut self) -> &'a mut Foo { + unsafe { COUNT += 1; } + self + } + fn slice_from_mut_<'a>(&'a mut self, _from: &Foo) -> &'a mut Foo { + unsafe { COUNT += 1; } + self + } + fn slice_to_mut_<'a>(&'a mut self, _to: &Foo) -> &'a mut Foo { + unsafe { COUNT += 1; } + self + } + fn slice_mut_<'a>(&'a mut self, _from: &Foo, _to: &Foo) -> &'a mut Foo { + unsafe { COUNT += 1; } + self + } +} +fn main() { + let mut x = Foo; + x[]; + x[Foo..]; + x[..Foo]; + x[Foo..Foo]; + x[mut]; + x[mut Foo..]; + x[mut ..Foo]; + x[mut Foo..Foo]; + unsafe { + assert!(COUNT == 8); + } +} diff --git a/src/test/run-pass/tag-align-dyn-u64.rs b/src/test/run-pass/tag-align-dyn-u64.rs index 0fc20ef66b3..d6a154edd78 100644 --- a/src/test/run-pass/tag-align-dyn-u64.rs +++ b/src/test/run-pass/tag-align-dyn-u64.rs @@ -14,7 +14,7 @@ use std::mem; enum Tag<A> { - Tag(A) + Tag2(A) } struct Rec { @@ -23,7 +23,7 @@ struct Rec { } fn mk_rec() -> Rec { - return Rec { c8:0u8, t:Tag(0u64) }; + return Rec { c8:0u8, t:Tag2(0u64) }; } fn is_8_byte_aligned(u: &Tag<u64>) -> bool { diff --git a/src/test/run-pass/tag-align-shape.rs b/src/test/run-pass/tag-align-shape.rs index e161f6887e1..e032a5e4156 100644 --- a/src/test/run-pass/tag-align-shape.rs +++ b/src/test/run-pass/tag-align-shape.rs @@ -11,7 +11,7 @@ extern crate debug; enum a_tag { - a_tag(u64) + a_tag_var(u64) } struct t_rec { @@ -20,8 +20,8 @@ struct t_rec { } pub fn main() { - let x = t_rec {c8: 22u8, t: a_tag(44u64)}; + let x = t_rec {c8: 22u8, t: a_tag_var(44u64)}; let y = format!("{:?}", x); println!("y = {}", y); - assert_eq!(y, "t_rec{c8: 22u8, t: a_tag(44u64)}".to_string()); + assert_eq!(y, "t_rec{c8: 22u8, t: a_tag_var(44u64)}".to_string()); } diff --git a/src/test/run-pass/tag-align-u64.rs b/src/test/run-pass/tag-align-u64.rs index 8942e0b6b5d..398a0939d97 100644 --- a/src/test/run-pass/tag-align-u64.rs +++ b/src/test/run-pass/tag-align-u64.rs @@ -14,7 +14,7 @@ use std::mem; enum Tag { - Tag(u64) + TagInner(u64) } struct Rec { @@ -23,7 +23,7 @@ struct Rec { } fn mk_rec() -> Rec { - return Rec { c8:0u8, t:Tag(0u64) }; + return Rec { c8:0u8, t:TagInner(0u64) }; } fn is_8_byte_aligned(u: &Tag) -> bool { diff --git a/src/test/run-pass/unboxed-closures-all-traits.rs b/src/test/run-pass/unboxed-closures-all-traits.rs index c362a83e60c..d9120495155 100644 --- a/src/test/run-pass/unboxed-closures-all-traits.rs +++ b/src/test/run-pass/unboxed-closures-all-traits.rs @@ -10,15 +10,15 @@ #![feature(lang_items, overloaded_calls, unboxed_closures)] -fn a<F:|&: int, int| -> int>(f: F) -> int { +fn a<F:Fn(int, int) -> int>(f: F) -> int { f(1, 2) } -fn b<F:|&mut: int, int| -> int>(mut f: F) -> int { +fn b<F:FnMut(int, int) -> int>(mut f: F) -> int { f(3, 4) } -fn c<F:|: int, int| -> int>(f: F) -> int { +fn c<F:FnOnce(int, int) -> int>(f: F) -> int { f(5, 6) } diff --git a/src/test/run-pass/unboxed-closures-drop.rs b/src/test/run-pass/unboxed-closures-drop.rs index f20dddcae54..a455e4d2032 100644 --- a/src/test/run-pass/unboxed-closures-drop.rs +++ b/src/test/run-pass/unboxed-closures-drop.rs @@ -41,15 +41,15 @@ impl Drop for Droppable { } } -fn a<F:|&: int, int| -> int>(f: F) -> int { +fn a<F:Fn(int, int) -> int>(f: F) -> int { f(1, 2) } -fn b<F:|&mut: int, int| -> int>(mut f: F) -> int { +fn b<F:FnMut(int, int) -> int>(mut f: F) -> int { f(3, 4) } -fn c<F:|: int, int| -> int>(f: F) -> int { +fn c<F:FnOnce(int, int) -> int>(f: F) -> int { f(5, 6) } diff --git a/src/test/run-pass/unboxed-closures-single-word-env.rs b/src/test/run-pass/unboxed-closures-single-word-env.rs index 754b1f70644..aef6956118e 100644 --- a/src/test/run-pass/unboxed-closures-single-word-env.rs +++ b/src/test/run-pass/unboxed-closures-single-word-env.rs @@ -13,15 +13,15 @@ #![feature(overloaded_calls, unboxed_closures)] -fn a<F:|&: int, int| -> int>(f: F) -> int { +fn a<F:Fn(int, int) -> int>(f: F) -> int { f(1, 2) } -fn b<F:|&mut: int, int| -> int>(mut f: F) -> int { +fn b<F:FnMut(int, int) -> int>(mut f: F) -> int { f(3, 4) } -fn c<F:|: int, int| -> int>(f: F) -> int { +fn c<F:FnOnce(int, int) -> int>(f: F) -> int { f(5, 6) } diff --git a/src/test/run-pass/unboxed-closures-unique-type-id.rs b/src/test/run-pass/unboxed-closures-unique-type-id.rs index 55d89d4e4f6..f35daa65a43 100644 --- a/src/test/run-pass/unboxed-closures-unique-type-id.rs +++ b/src/test/run-pass/unboxed-closures-unique-type-id.rs @@ -21,8 +21,7 @@ use std::ptr; -pub fn replace_map<'a, T, F>(src: &mut T, prod: F) -where F: |: T| -> T { +pub fn replace_map<'a, T, F>(src: &mut T, prod: F) where F: FnOnce(T) -> T { unsafe { *src = prod(ptr::read(src as *mut T as *const T)); } } diff --git a/src/test/run-pass/where-clauses-unboxed-closures.rs b/src/test/run-pass/where-clauses-unboxed-closures.rs index ae005b4ae53..808e937bc72 100644 --- a/src/test/run-pass/where-clauses-unboxed-closures.rs +++ b/src/test/run-pass/where-clauses-unboxed-closures.rs @@ -13,7 +13,7 @@ struct Bencher; // ICE -fn warm_up<'a, F>(f: F) where F: |&: &'a mut Bencher| { +fn warm_up<'a, F>(f: F) where F: Fn(&'a mut Bencher) { } fn main() { diff --git a/src/test/run-pass/xcrate-unit-struct.rs b/src/test/run-pass/xcrate-unit-struct.rs index ae8d628289d..9ba4b707268 100644 --- a/src/test/run-pass/xcrate-unit-struct.rs +++ b/src/test/run-pass/xcrate-unit-struct.rs @@ -12,7 +12,7 @@ extern crate xcrate_unit_struct; static s1: xcrate_unit_struct::Struct = xcrate_unit_struct::Struct; -static s2: xcrate_unit_struct::Unit = xcrate_unit_struct::Unit; +static s2: xcrate_unit_struct::Unit = xcrate_unit_struct::UnitVariant; static s3: xcrate_unit_struct::Unit = xcrate_unit_struct::Argument(xcrate_unit_struct::Struct); static s4: xcrate_unit_struct::Unit = xcrate_unit_struct::Argument(s1); @@ -22,7 +22,7 @@ fn f2(_: xcrate_unit_struct::Unit) {} pub fn main() { f1(xcrate_unit_struct::Struct); - f2(xcrate_unit_struct::Unit); + f2(xcrate_unit_struct::UnitVariant); f2(xcrate_unit_struct::Argument(xcrate_unit_struct::Struct)); f1(s1); |
