diff --git a/configure b/configure index cabe2d52d7ba3066e776bc4181166deb103878d5..7b7eac8e73527e3c2127b356305c0975f7ce2e2b 100755 --- a/configure +++ b/configure @@ -28,8 +28,8 @@ need_ok() { need_cmd() { if command -v $1 >/dev/null 2>&1 - then msg "found $1" - else err "need $1" + then msg "found program $1" + else err "need program $1" fi } @@ -340,6 +340,7 @@ need_cmd date need_cmd tr need_cmd sed need_cmd file +need_cmd make msg "inspecting environment" diff --git a/mk/main.mk b/mk/main.mk index 8c910f4759610436a5efab78c64405828e9a7e4c..0e52f168f59ed2072cb87c2eddfee295cb821685 100644 --- a/mk/main.mk +++ b/mk/main.mk @@ -30,8 +30,8 @@ CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM) CFG_DISABLE_UNSTABLE_FEATURES=1 endif ifeq ($(CFG_RELEASE_CHANNEL),beta) -CFG_RELEASE=$(CFG_RELEASE_NUM)-beta(CFG_PRERELEASE_VERSION) -CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)-beta(CFG_PRERELEASE_VERSION) +CFG_RELEASE=$(CFG_RELEASE_NUM)-beta$(CFG_PRERELEASE_VERSION) +CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)-beta$(CFG_PRERELEASE_VERSION) CFG_DISABLE_UNSTABLE_FEATURES=1 endif ifeq ($(CFG_RELEASE_CHANNEL),nightly) diff --git a/src/compiletest/common.rs b/src/compiletest/common.rs index 1f4f444634dc254ad98fec426fdbdf8028a83a19..b2e852a36f7c36485c7d7ed9fa5469369f684c0b 100644 --- a/src/compiletest/common.rs +++ b/src/compiletest/common.rs @@ -12,6 +12,20 @@ use std::fmt; use std::str::FromStr; +#[cfg(stage0)] // NOTE: remove impl after snapshot +#[derive(Clone, PartialEq, Show)] +pub enum Mode { + CompileFail, + RunFail, + RunPass, + RunPassValgrind, + Pretty, + DebugInfoGdb, + DebugInfoLldb, + Codegen +} + +#[cfg(not(stage0))] // NOTE: remove cfg after snapshot #[derive(Clone, PartialEq, Debug)] pub enum Mode { CompileFail, @@ -24,6 +38,7 @@ pub enum Mode { Codegen } + impl Copy for Mode {} impl FromStr for Mode { diff --git a/src/doc/reference.md b/src/doc/reference.md index d703607c1723c2f47cf4d9cc4fa235a1d92d18f8..3cbd71a1eb3400850fa8c13538fc1904e3f2356a 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -2291,136 +2291,7 @@ The name `str_eq` has a special meaning to the Rust compiler, and the presence of this definition means that it will use this definition when generating calls to the string equality function. -A complete list of the built-in language items follows: - -#### Built-in Traits - -* `copy` - : Types that do not move ownership when used by-value. -* `drop` - : Have destructors. -* `send` - : Able to be sent across thread boundaries. -* `sized` - : Has a size known at compile time. -* `sync` - : Able to be safely shared between threads when aliased. - -#### Operators - -These language items are traits: - -* `add` - : Elements can be added (for example, integers and floats). -* `sub` - : Elements can be subtracted. -* `mul` - : Elements can be multiplied. -* `div` - : Elements have a division operation. -* `rem` - : Elements have a remainder operation. -* `neg` - : Elements can be negated arithmetically. -* `not` - : Elements can be negated logically. -* `bitxor` - : Elements have an exclusive-or operation. -* `bitand` - : Elements have a bitwise `and` operation. -* `bitor` - : Elements have a bitwise `or` operation. -* `shl` - : Elements have a left shift operation. -* `shr` - : Elements have a right shift operation. -* `index` - : Elements can be indexed. -* `index_mut` - : ___Needs filling in___ -* `eq` - : Elements can be compared for equality. -* `ord` - : Elements have a partial ordering. -* `deref` - : `*` can be applied, yielding a reference to another type. -* `deref_mut` - : `*` can be applied, yielding a mutable reference to another type. - -These are functions: - -* `fn` - : ___Needs filling in___ -* `fn_mut` - : ___Needs filling in___ -* `fn_once` - : ___Needs filling in___ -* `str_eq` - : Compare two strings (`&str`) for equality. -* `strdup_uniq` - : Return a new unique string - containing a copy of the contents of a unique string. - -#### Types - -* `type_id` - : The type returned by the `type_id` intrinsic. -* `unsafe` - : A type whose contents can be mutated through an immutable reference. - -#### Marker types - -These types help drive the compiler's analysis - -* `begin_unwind` - : ___Needs filling in___ -* `no_copy_bound` - : This type does not implement "copy", even if eligible. -* `eh_personality` - : ___Needs filling in___ -* `exchange_free` - : Free memory that was allocated on the exchange heap. -* `exchange_malloc` - : Allocate memory on the exchange heap. -* `closure_exchange_malloc` - : ___Needs filling in___ -* `panic` - : Abort the program with an error. -* `fail_bounds_check` - : Abort the program with a bounds check error. -* `free` - : Free memory that was allocated on the managed heap. -* `gc` - : ___Needs filling in___ -* `exchange_heap` - : ___Needs filling in___ -* `iterator` - : ___Needs filling in___ -* `contravariant_lifetime` - : The lifetime parameter should be considered contravariant. -* `covariant_lifetime` - : The lifetime parameter should be considered covariant. -* `invariant_lifetime` - : The lifetime parameter should be considered invariant. -* `malloc` - : Allocate memory on the managed heap. -* `owned_box` - : ___Needs filling in___ -* `stack_exhausted` - : ___Needs filling in___ -* `start` - : ___Needs filling in___ -* `contravariant_type` - : The type parameter should be considered contravariant. -* `covariant_type` - : The type parameter should be considered covariant. -* `invariant_type` - : The type parameter should be considered invariant. -* `ty_desc` - : ___Needs filling in___ - -> **Note:** This list is likely to become out of date. We should auto-generate -> it from `librustc/middle/lang_items.rs`. +A complete list of the built-in language items will be added in the future. ### Inline attributes @@ -2652,9 +2523,7 @@ The currently implemented features of the reference compiler are: declare a `static` as being unique per-thread leveraging LLVM's implementation which works in concert with the kernel loader and dynamic linker. This is not necessarily available - on all platforms, and usage of it is discouraged (rust - focuses more on thread-local data instead of thread-local - data). + on all platforms, and usage of it is discouraged. * `trace_macros` - Allows use of the `trace_macros` macro, which is a nasty hack that will certainly be removed. diff --git a/src/doc/trpl/installing-rust.md b/src/doc/trpl/installing-rust.md index 5893b51a4208cb2122cbc48f3c585333dd1bbab2..80288c4c3d9ca9604373e67f74b0c43eb51ec3c8 100644 --- a/src/doc/trpl/installing-rust.md +++ b/src/doc/trpl/installing-rust.md @@ -83,7 +83,6 @@ If not, there are a number of places where you can get help. The easiest is you can access through [Mibbit](http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust). Click that link, and you'll be chatting with other Rustaceans (a silly nickname we -call ourselves), and we can help you out. Other great resources include [our -forum](http://discuss.rust-lang.org/), [the /r/rust -subreddit](http://www.reddit.com/r/rust), and [Stack +call ourselves), and we can help you out. Other great resources include [the +/r/rust subreddit](http://www.reddit.com/r/rust), and [Stack Overflow](http://stackoverflow.com/questions/tagged/rust). diff --git a/src/doc/trpl/method-syntax.md b/src/doc/trpl/method-syntax.md index 3d8de00991c95af9cc3a9940b347b98cf599a2cb..e6570c2ee74c8d649faaf8afec41cf76358d30ba 100644 --- a/src/doc/trpl/method-syntax.md +++ b/src/doc/trpl/method-syntax.md @@ -18,6 +18,8 @@ x.foo().bar().baz(); Luckily, as you may have guessed with the leading question, you can! Rust provides the ability to use this *method call syntax* via the `impl` keyword. +## Method calls + Here's how it works: ```{rust} @@ -56,11 +58,56 @@ other parameter. Because we know it's a `Circle`, we can access the `radius` just like we would with any other struct. An import of π and some multiplications later, and we have our area. +## Chaining method calls + +So, now we know how to call a method, such as `foo.bar()`. But what about our +original example, `foo.bar().baz()`? This is called 'method chaining', and we +can do it by returning `self`. + +``` +struct Circle { + x: f64, + y: f64, + radius: f64, +} + +impl Circle { + fn area(&self) -> f64 { + std::f64::consts::PI * (self.radius * self.radius) + } + + fn grow(&self) -> Circle { + Circle { x: self.x, y: self.y, radius: (self.radius * 10.0) } + } +} + +fn main() { + let c = Circle { x: 0.0, y: 0.0, radius: 2.0 }; + println!("{}", c.area()); + + let d = c.grow().area(); + println!("{}", d); +} +``` + +Check the return type: + +``` +# struct Circle; +# impl Circle { +fn grow(&self) -> Circle { +# Circle } } +``` + +We just say we're returning a `Circle`. With this, we can grow a new circle +that's twice as big as the old one. + +## Static methods + You can also define methods that do not take a `self` parameter. Here's a pattern that's very common in Rust code: -```{rust} -# #![allow(non_shorthand_field_patterns)] +``` struct Circle { x: f64, y: f64, @@ -86,3 +133,66 @@ This *static method* builds a new `Circle` for us. Note that static methods are called with the `Struct::method()` syntax, rather than the `ref.method()` syntax. +## Builder Pattern + +Let's say that we want our users to be able to create Circles, but we will +allow them to only set the properties they care about. Otherwise, the `x` +and `y` attributes will be `0.0`, and the `radius` will be `1.0`. Rust doesn't +have method overloading, named arguments, or variable arguments. We employ +the builder pattern instead. It looks like this: + +``` +struct Circle { + x: f64, + y: f64, + radius: f64, +} + +impl Circle { + fn area(&self) -> f64 { + std::f64::consts::PI * (self.radius * self.radius) + } +} + +struct CircleBuilder { + coordinate: f64, + radius: f64, +} + +impl CircleBuilder { + fn new() -> CircleBuilder { + CircleBuilder { coordinate: 0.0, radius: 0.0, } + } + + fn coordinate(&mut self, coordinate: f64) -> &mut CircleBuilder { + self.coordinate = coordinate; + self + } + + fn radius(&mut self, radius: f64) -> &mut CircleBuilder { + self.radius = radius; + self + } + + fn finalize(&self) -> Circle { + Circle { x: self.coordinate, y: self.coordinate, radius: self.radius } + } +} + +fn main() { + let c = CircleBuilder::new() + .coordinate(10.0) + .radius(5.0) + .finalize(); + + + println!("area: {}", c.area()); +} +``` + +What we've done here is make another struct, `CircleBuilder`. We've defined our +builder methods on it. We've also defined our `area()` method on `Circle`. We +also made one more method on `CircleBuilder`: `finalize()`. This method creates +our final `Circle` from the builder. Now, we've used the type system to enforce +our concerns: we can use the methods on `CircleBuilder` to constrain making +`Circle`s in any way we choose. diff --git a/src/etc/errorck.py b/src/etc/errorck.py index 17659309d3b0d6822dcedb2b0f773e06d0b1187f..952e299265d85aba4ca5d6f76ca4b8c37ca2aa0a 100644 --- a/src/etc/errorck.py +++ b/src/etc/errorck.py @@ -14,11 +14,10 @@ import sys, os, re src_dir = sys.argv[1] - -errcode_map = { } +errcode_map = {} +error_re = re.compile("(E\d\d\d\d)") for (dirpath, dirnames, filenames) in os.walk(src_dir): - if "src/test" in dirpath or "src/llvm" in dirpath: # Short circuit for fast continue @@ -28,15 +27,12 @@ for (dirpath, dirnames, filenames) in os.walk(src_dir): continue path = os.path.join(dirpath, filename) - line_num = 1 - with open(path, 'r') as f: - for line in f: - - p = re.compile("(E\d\d\d\d)") - m = p.search(line) - if not m is None: - errcode = m.group(1) + with open(path, 'r') as f: + for line_num, line in enumerate(f, start=1): + match = error_re.search(line) + if match: + errcode = match.group(1) new_record = [(errcode, path, line_num, line)] existing = errcode_map.get(errcode) if existing is not None: @@ -45,26 +41,19 @@ for (dirpath, dirnames, filenames) in os.walk(src_dir): else: errcode_map[errcode] = new_record - line_num += 1 - errors = False all_errors = [] -for errcode in errcode_map: - entries = errcode_map[errcode] - all_errors += [entries[0][0]] + +for errcode, entries in errcode_map.items(): + all_errors.append(entries[0][0]) if len(entries) > 1: - print "error: duplicate error code " + errcode + print("error: duplicate error code " + errcode) for entry in entries: - print entry[1] + ": " + str(entry[2]) - print entry[3] + print("{1}: {2}\n{3}".format(*entry)) errors = True -print str(len(errcode_map)) + " error codes" - -all_errors.sort() -all_errors.reverse() - -print "highest error code: " + all_errors[0] +print("{0} error codes".format(len(errcode_map))) +print("highest error code: " + max(all_errors)) if errors: sys.exit(1) diff --git a/src/etc/licenseck.py b/src/etc/licenseck.py index 9ac0acc38a73e8b61c47694177aee91c87c95f6e..f38583ee1fb3774c8bf01c56304358b58992fe70 100644 --- a/src/etc/licenseck.py +++ b/src/etc/licenseck.py @@ -8,29 +8,18 @@ # option. This file may not be copied, modified, or distributed # except according to those terms. -license1 = """// Copyright """ -license2 = """ The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. -""" +import re -license3 = """# Copyright """ -license4 = """ The Rust Project Developers. See the COPYRIGHT -# file at the top-level directory of this distribution and at -# http://rust-lang.org/COPYRIGHT. -# -# Licensed under the Apache License, Version 2.0 or the MIT license -# , at your -# option. This file may not be copied, modified, or distributed -# except according to those terms. -""" +license_re = re.compile( +u"""(#|//) Copyright .* The Rust Project Developers. See the COPYRIGHT +\\1 file at the top-level directory of this distribution and at +\\1 http://rust-lang.org/COPYRIGHT. +\\1 +\\1 Licensed under the Apache License, Version 2.0 or the MIT license +\\1 , at your +\\1 option. This file may not be copied, modified, or distributed +\\1 except according to those terms.""") exceptions = [ "rt/rust_android_dummy.cpp", # BSD, chromium @@ -57,18 +46,14 @@ exceptions = [ def check_license(name, contents): # Whitelist check - for exception in exceptions: - if name.endswith(exception): - return True + if any(name.endswith(e) for e in exceptions): + return True # Xfail check firstlineish = contents[:100] - if firstlineish.find("ignore-license") != -1: + if "ignore-license" in firstlineish: return True # License check boilerplate = contents[:500] - if (boilerplate.find(license1) == -1 or boilerplate.find(license2) == -1) and \ - (boilerplate.find(license3) == -1 or boilerplate.find(license4) == -1): - return False - return True + return bool(license_re.search(boilerplate)) diff --git a/src/etc/tidy.py b/src/etc/tidy.py index 536ab7f30b9fa0604a420980633af1aa2dabcc92..c65b762e5173168c880f18dc5209b99e62c65226 100644 --- a/src/etc/tidy.py +++ b/src/etc/tidy.py @@ -113,7 +113,7 @@ try: if current_name != "": do_license_check(current_name, current_contents) -except UnicodeDecodeError, e: +except UnicodeDecodeError as e: report_err("UTF-8 decoding error " + str(e)) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 17eff98d429f622e505329b3444c00ca11630d53..87f7839cd472274d60e3a7b54c352855c71cadd0 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -243,6 +243,8 @@ pub trait Show { /// Format trait for the `:?` format. Useful for debugging, most all types /// should implement this. #[unstable = "I/O and core have yet to be reconciled"] +#[rustc_on_unimplemented = "`{Self}` cannot be formatted using `:?`; if it is defined in your \ + crate, add `#[derive(Debug)]` or manually implement it"] pub trait Debug { /// Formats the value using the given formatter. fn fmt(&self, &mut Formatter) -> Result; @@ -266,6 +268,8 @@ pub trait String { /// When a value can be semantically expressed as a String, this trait may be /// used. It corresponds to the default format, `{}`. #[unstable = "I/O and core have yet to be reconciled"] +#[rustc_on_unimplemented = "`{Self}` cannot be formatted with the default formatter; try using \ + `:?` instead if you are using a format string"] pub trait Display { /// Formats the value using the given formatter. fn fmt(&self, &mut Formatter) -> Result; diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 591822d6e1b7ac8534cc70a23112538b70993918..4910c03de5c68599cf21c0e2f6a4135b8de87d8e 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -82,6 +82,8 @@ /// else. #[lang="iterator"] #[stable] +#[rustc_on_unimplemented = "`{Self}` is not an iterator; maybe try calling `.iter()` or a similar \ + method"] pub trait Iterator { #[stable] type Item; diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index a987a0a5068a887341e585b5da5c31f35c1bf7d8..688f0484401529233794fdea918635d4a8ecab98 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -27,9 +27,10 @@ use clone::Clone; -/// Types able to be transferred across task boundaries. +/// Types able to be transferred across thread boundaries. #[unstable = "will be overhauled with new lifetime rules; see RFC 458"] #[lang="send"] +#[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"] pub unsafe trait Send: 'static { // empty. } @@ -37,6 +38,7 @@ pub unsafe trait Send: 'static { /// Types with a constant size known at compile-time. #[stable] #[lang="sized"] +#[rustc_on_unimplemented = "`{Self}` does not have a constant size known at compile-time"] pub trait Sized { // Empty. } @@ -146,11 +148,11 @@ pub trait Copy { // Empty. } -/// Types that can be safely shared between tasks when aliased. +/// Types that can be safely shared between threads when aliased. /// /// The precise definition is: a type `T` is `Sync` if `&T` is /// thread-safe. In other words, there is no possibility of data races -/// when passing `&T` references between tasks. +/// when passing `&T` references between threads. /// /// As one would expect, primitive types like `u8` and `f64` are all /// `Sync`, and so are simple aggregate types containing them (like @@ -193,6 +195,7 @@ pub trait Copy { /// `transmute`-ing from `&T` to `&mut T` is illegal). #[unstable = "will be overhauled with new lifetime rules; see RFC 458"] #[lang="sync"] +#[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"] pub unsafe trait Sync { // Empty } diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index e5d8e4e5143a778a665b8a603fce4af62b6cb24e..8933d3a966957c7496a7e466f8b61469f1d9a62f 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -295,6 +295,7 @@ fn has_test_signature(i: &ast::Item) -> HasTestSignature { &ast::ItemFn(ref decl, _, _, ref generics, _) => { let no_output = match decl.output { ast::DefaultReturn(..) => true, + ast::Return(ref t) if t.node == ast::TyTup(vec![]) => true, _ => false }; if decl.inputs.is_empty() @@ -331,6 +332,7 @@ fn has_test_signature(i: &ast::Item) -> bool { let input_cnt = decl.inputs.len(); let no_output = match decl.output { ast::DefaultReturn(..) => true, + ast::Return(ref t) if t.node == ast::TyTup(vec![]) => true, _ => false }; let tparm_cnt = generics.ty_params.len(); diff --git a/src/test/compile-fail/issue-19660.rs b/src/test/compile-fail/issue-19660.rs new file mode 100644 index 0000000000000000000000000000000000000000..f83037d47bbb1dc398068a64e95551f3fae8805c --- /dev/null +++ b/src/test/compile-fail/issue-19660.rs @@ -0,0 +1,22 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// error-pattern: requires `copy` lang_item + +#![feature(lang_items, start)] +#![no_std] + +#[lang = "sized"] +trait Sized {} + +#[start] +fn main(_: int, _: *const *const u8) -> int { + 0 +} diff --git a/src/test/run-pass/issue-15149.rs b/src/test/run-pass/issue-15149.rs index 57dc6fd75f08c603c1b1471cb0362720130cdf4c..bf395b14eb4eceafedb6bd2f75ffeb27ff386729 100644 --- a/src/test/run-pass/issue-15149.rs +++ b/src/test/run-pass/issue-15149.rs @@ -8,33 +8,54 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::io::{TempDir, Command, fs}; +use std::slice::SliceExt; +use std::io::{Command, fs, USER_RWX}; use std::os; +use std::path::BytesContainer; +use std::rand::random; fn main() { // If we're the child, make sure we were invoked correctly let args = os::args(); if args.len() > 1 && args[1].as_slice() == "child" { - return assert_eq!(args[0].as_slice(), "mytest"); + // FIXME: This should check the whole `args[0]` instead of just + // checking that it ends_with the executable name. This + // is needed because of Windows, which has a different behavior. + // See #15149 for more info. + return assert!(args[0].ends_with(&format!("mytest{}", os::consts::EXE_SUFFIX)[])); } test(); } fn test() { - // If we're the parent, copy our own binary to a tempr directory, and then - // make it executable. - let dir = TempDir::new("mytest").unwrap(); - let me = os::self_exe_name().unwrap(); - let dest = dir.path().join(format!("mytest{}", os::consts::EXE_SUFFIX)); - fs::copy(&me, &dest).unwrap(); - - // Append the temp directory to our own PATH. + // If we're the parent, copy our own binary to a new directory. + let my_path = os::self_exe_name().unwrap(); + let my_dir = my_path.dir_path(); + + let random_u32: u32 = random(); + let child_dir = Path::new(my_dir.join(format!("issue-15149-child-{}", + random_u32))); + fs::mkdir(&child_dir, USER_RWX).unwrap(); + + let child_path = child_dir.join(format!("mytest{}", + os::consts::EXE_SUFFIX)); + fs::copy(&my_path, &child_path).unwrap(); + + // Append the new directory to our own PATH. let mut path = os::split_paths(os::getenv("PATH").unwrap_or(String::new())); - path.push(dir.path().clone()); + path.push(child_dir.clone()); let path = os::join_paths(path.as_slice()).unwrap(); - Command::new("mytest").env("PATH", path.as_slice()) - .arg("child") - .spawn().unwrap(); + let child_output = Command::new("mytest").env("PATH", path.as_slice()) + .arg("child") + .output().unwrap(); + + assert!(child_output.status.success(), + format!("child assertion failed\n child stdout:\n {}\n child stderr:\n {}", + child_output.output.container_as_str().unwrap(), + child_output.error.container_as_str().unwrap())); + + fs::rmdir_recursive(&child_dir).unwrap(); + } diff --git a/src/test/run-pass/test-fn-signature-verification-for-explicit-return-type.rs b/src/test/run-pass/test-fn-signature-verification-for-explicit-return-type.rs new file mode 100644 index 0000000000000000000000000000000000000000..7c99c968e352317a3a313c79c20dd0074909ea76 --- /dev/null +++ b/src/test/run-pass/test-fn-signature-verification-for-explicit-return-type.rs @@ -0,0 +1,20 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: --test +// no-pretty-expanded +extern crate test; + +#[bench] +fn bench_explicit_return_type(_: &mut ::test::Bencher) -> () {} + +#[test] +fn test_explicit_return_type() -> () {} +