diff --git a/.travis.yml b/.travis.yml index 0abd858d8228b..c5d8a94f39b05 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,9 +15,9 @@ before_install: script: - docker run -v `pwd`:/build rust sh -c " - ./configure --llvm-root=/usr/lib/llvm-3.7 && + ./configure --enable-rustbuild --llvm-root=/usr/lib/llvm-3.7 && make tidy && - make check-notidy -j4 + make check -j4 " # Real testing happens on http://buildbot.rust-lang.org/ diff --git a/configure b/configure index 44fb3d368d2c7..bcc1faea3b5d8 100755 --- a/configure +++ b/configure @@ -360,6 +360,13 @@ abs_path() { (unset CDPATH && cd "$_path" > /dev/null && pwd) } +HELP=0 +for arg; do + case "$arg" in + --help) HELP=1;; + esac +done + msg "looking for configure programs" need_cmd cmp need_cmd mkdir @@ -566,11 +573,8 @@ esac OPTIONS="" -HELP=0 -if [ "$1" = "--help" ] +if [ "$HELP" -eq 1 ] then - HELP=1 - shift echo echo "Usage: $CFG_SELF [options]" echo diff --git a/mk/main.mk b/mk/main.mk index 5a849af9856f1..6130b58138751 100644 --- a/mk/main.mk +++ b/mk/main.mk @@ -348,6 +348,7 @@ LLVM_AS_$(1)=$$(CFG_LLVM_INST_DIR_$(1))/bin/llvm-as$$(X_$(1)) LLC_$(1)=$$(CFG_LLVM_INST_DIR_$(1))/bin/llc$$(X_$(1)) LLVM_ALL_COMPONENTS_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --components) +LLVM_VERSION_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --version) endef diff --git a/mk/tests.mk b/mk/tests.mk index 201e4cae51d6d..c135aa9b8fb95 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -649,6 +649,7 @@ CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3) = \ --lldb-python $$(CFG_LLDB_PYTHON) \ --gdb-version="$(CFG_GDB_VERSION)" \ --lldb-version="$(CFG_LLDB_VERSION)" \ + --llvm-version="$$(LLVM_VERSION_$(3))" \ --android-cross-path=$(CFG_ARM_LINUX_ANDROIDEABI_NDK) \ --adb-path=$(CFG_ADB) \ --adb-test-dir=$(CFG_ADB_TEST_DIR) \ diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 3d8b1438125e6..2b9d717cbd48d 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -148,6 +148,9 @@ pub fn compiletest(build: &Build, if let Some(ref dir) = build.lldb_python_dir { cmd.arg("--lldb-python-dir").arg(dir); } + let llvm_config = build.llvm_config(target); + let llvm_version = output(Command::new(&llvm_config).arg("--version")); + cmd.arg("--llvm-version").arg(llvm_version); cmd.args(&build.flags.args); @@ -158,7 +161,6 @@ pub fn compiletest(build: &Build, // Only pass correct values for these flags for the `run-make` suite as it // requires that a C++ compiler was configured which isn't always the case. if suite == "run-make" { - let llvm_config = build.llvm_config(target); let llvm_components = output(Command::new(&llvm_config).arg("--components")); let llvm_cxxflags = output(Command::new(&llvm_config).arg("--cxxflags")); cmd.arg("--cc").arg(build.cc(target)) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 155848901cdb4..302ac68460c69 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -203,6 +203,10 @@ pub fn rustc<'a>(build: &'a Build, target: &str, compiler: &Compiler<'a>) { cargo.env("LLVM_RUSTLLVM", "1"); } cargo.env("LLVM_CONFIG", build.llvm_config(target)); + let target_config = build.config.target_config.get(target); + if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) { + cargo.env("CFG_LLVM_ROOT", s); + } if build.config.llvm_static_stdcpp { cargo.env("LLVM_STATIC_STDCPP", compiler_file(build.cxx(target), "libstdc++.a")); diff --git a/src/doc/reference.md b/src/doc/reference.md index ec2d3e2822e20..cc5d9c3685aba 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -2071,6 +2071,9 @@ macro scope. trait of the same name. `{Self}` will be replaced with the type that is supposed to implement the trait but doesn't. To use this, the `on_unimplemented` feature gate must be enabled. +- `must_use` - on structs and enums, will warn if a value of this type isn't used or + assigned to a variable. You may also include an optional message by using + `#[must_use = "message"]` which will be given alongside the warning. ### Conditional compilation diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 8271b85b01a3b..761f1cac8392b 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -222,15 +222,20 @@ extern "rust-intrinsic" { /// trait objects, because they can't be read out onto the stack and /// dropped normally. /// - /// * It is friendlier to the optimizer to do this over `ptr::read` when - /// dropping manually allocated memory (e.g. when writing Box/Rc/Vec), - /// as the compiler doesn't need to prove that it's sound to elide the - /// copy. + /// * It is friendlier to the optimizer to do this over [`ptr::read`] when + /// dropping manually allocated memory (e.g. when writing + /// [`Box`]/[`Rc`]/[`Vec`]), as the compiler doesn't need to prove that + /// it's sound to elide the copy. /// /// # Undefined Behavior /// - /// This has all the same safety problems as `ptr::read` with respect to + /// This has all the same safety problems as [`ptr::read`] with respect to /// invalid pointers, types, and double drops. + /// + /// [`ptr::read`]: fn.read.html + /// [`Box`]: ../boxed/struct.Box.html + /// [`Rc`]: ../rc/struct.Rc.html + /// [`Vec`]: ../vec/struct.Vec.html #[stable(feature = "drop_in_place", since = "1.8.0")] pub fn drop_in_place(to_drop: *mut T); diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index c916ad930ff10..f29a49dd5fe1a 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -189,10 +189,19 @@ macro_rules! debug_assert_eq { ($($arg:tt)*) => (if cfg!(debug_assertions) { assert_eq!($($arg)*); }) } -/// Helper macro for unwrapping `Result` values while returning early with an -/// error if the value of the expression is `Err`. Can only be used in -/// functions that return `Result` because of the early return of `Err` that -/// it provides. +/// Helper macro for reducing boilerplate code for matching `Result` together +/// with converting downstream errors. +/// +/// `try!` matches the given `Result`. In case of the `Ok` variant, the +/// expression has the value of the wrapped value. +/// +/// In case of the `Err` variant, it retrieves the inner error. `try!` then +/// performs conversion using `From`. This provides automatic conversion +/// between specialized errors and more general ones. The resulting +/// error is then immediately returned. +/// +/// Because of the early return, `try!` can only be used in functions that +/// return `Result`. /// /// # Examples /// @@ -201,18 +210,28 @@ macro_rules! debug_assert_eq { /// use std::fs::File; /// use std::io::prelude::*; /// -/// fn write_to_file_using_try() -> Result<(), io::Error> { +/// enum MyError { +/// FileWriteError +/// } +/// +/// impl From for MyError { +/// fn from(e: io::Error) -> MyError { +/// MyError::FileWriteError +/// } +/// } +/// +/// fn write_to_file_using_try() -> Result<(), MyError> { /// let mut file = try!(File::create("my_best_friends.txt")); /// try!(file.write_all(b"This is a list of my best friends.")); /// println!("I wrote to the file"); /// Ok(()) /// } /// // This is equivalent to: -/// fn write_to_file_using_match() -> Result<(), io::Error> { +/// fn write_to_file_using_match() -> Result<(), MyError> { /// let mut file = try!(File::create("my_best_friends.txt")); /// match file.write_all(b"This is a list of my best friends.") { /// Ok(v) => v, -/// Err(e) => return Err(e), +/// Err(e) => return Err(From::from(e)), /// } /// println!("I wrote to the file"); /// Ok(()) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 2bb0c3c04e02c..369c00f521418 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -140,6 +140,26 @@ //! //! // `consume_and_return_x` can no longer be invoked at this point //! ``` +//! +//! This example shows the behavior of the various `Range*` structs. +//! +//! ```rust +//! #![feature(inclusive_range_syntax)] +//! fn main() { +//! let arr = [0, 1, 2, 3, 4]; +//! +//! assert_eq!(arr[ .. ], [0,1,2,3,4]); // RangeFull +//! assert_eq!(arr[ ..3], [0,1,2 ]); // RangeTo +//! assert_eq!(arr[1.. ], [ 1,2,3,4]); // RangeFrom +//! assert_eq!(arr[1..3], [ 1,2 ]); // Range +//! +//! assert_eq!(arr[ ...3], [0,1,2,3 ]); // RangeToIncusive +//! assert_eq!(arr[1...3], [ 1,2,3 ]); // RangeInclusive +//! } +//! ``` +//! +//! Note: whitespace alignment is not idiomatic Rust. An exception is made in +//! this case to facilitate comparison. #![stable(feature = "rust1", since = "1.0.0")] @@ -282,6 +302,12 @@ macro_rules! forward_ref_binop { /// Point { x: 3, y: 3 }); /// } /// ``` +/// +/// Note that `RHS = Self` by default, but this is not mandatory. For example, +/// [std::time::SystemTime] implements `Add`, which permits +/// operations of the form `SystemTime = SystemTime + Duration`. +/// +/// [std::time::SystemTime]: ../../std/time/struct.SystemTime.html #[lang = "add"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Add { @@ -349,6 +375,12 @@ add_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } /// Point { x: 1, y: 0 }); /// } /// ``` +/// +/// Note that `RHS = Self` by default, but this is not mandatory. For example, +/// [std::time::SystemTime] implements `Sub`, which permits +/// operations of the form `SystemTime = SystemTime - Duration`. +/// +/// [std::time::SystemTime]: ../../std/time/struct.SystemTime.html #[lang = "sub"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Sub { @@ -1986,11 +2018,12 @@ pub trait IndexMut: Index { /// /// ``` /// let arr = [0, 1, 2, 3]; -/// assert_eq!(arr[ .. ], [0,1,2,3]); // RangeFull -/// assert_eq!(arr[ ..3], [0,1,2 ]); -/// assert_eq!(arr[1.. ], [ 1,2,3]); -/// assert_eq!(arr[1..3], [ 1,2 ]); +/// assert_eq!(arr[ .. ], [0, 1, 2, 3]); /// ``` +/// +/// See the [module examples] for the behavior of other range structs. +/// +/// [module examples]: ../#Examples #[derive(Copy, Clone, PartialEq, Eq, Hash)] #[stable(feature = "rust1", since = "1.0.0")] pub struct RangeFull; @@ -2015,12 +2048,13 @@ impl fmt::Debug for RangeFull { /// assert_eq!(3+4+5, (3..6).sum()); /// /// let arr = [0, 1, 2, 3]; -/// assert_eq!(arr[ .. ], [0,1,2,3]); -/// assert_eq!(arr[ ..3], [0,1,2 ]); -/// assert_eq!(arr[1.. ], [ 1,2,3]); -/// assert_eq!(arr[1..3], [ 1,2 ]); // Range +/// assert_eq!(arr[1..3], [1, 2]); /// } /// ``` +/// +/// See the [module examples] for the behavior of other range structs. +/// +/// [module examples]: ../#Examples #[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "rust1", since = "1.0.0")] pub struct Range { @@ -2078,12 +2112,13 @@ impl> Range { /// assert_eq!(2+3+4, (2..).take(3).sum()); /// /// let arr = [0, 1, 2, 3]; -/// assert_eq!(arr[ .. ], [0,1,2,3]); -/// assert_eq!(arr[ ..3], [0,1,2 ]); -/// assert_eq!(arr[1.. ], [ 1,2,3]); // RangeFrom -/// assert_eq!(arr[1..3], [ 1,2 ]); +/// assert_eq!(arr[1.. ], [1, 2, 3]); /// } /// ``` +/// +/// See the [module examples] for the behavior of other range structs. +/// +/// [module examples]: ../#Examples #[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "rust1", since = "1.0.0")] pub struct RangeFrom { @@ -2145,11 +2180,12 @@ impl> RangeFrom { /// /// ``` /// let arr = [0, 1, 2, 3]; -/// assert_eq!(arr[ .. ], [0,1,2,3]); -/// assert_eq!(arr[ ..3], [0,1,2 ]); // RangeTo -/// assert_eq!(arr[1.. ], [ 1,2,3]); -/// assert_eq!(arr[1..3], [ 1,2 ]); +/// assert_eq!(arr[ ..3], [0, 1, 2]); /// ``` +/// +/// See the [module examples] for the behavior of other range structs. +/// +/// [module examples]: ../#Examples #[derive(Copy, Clone, PartialEq, Eq, Hash)] #[stable(feature = "rust1", since = "1.0.0")] pub struct RangeTo { @@ -2196,10 +2232,13 @@ impl> RangeTo { /// assert_eq!(3+4+5, (3...5).sum()); /// /// let arr = [0, 1, 2, 3]; -/// assert_eq!(arr[ ...2], [0,1,2 ]); -/// assert_eq!(arr[1...2], [ 1,2 ]); // RangeInclusive +/// assert_eq!(arr[1...2], [1, 2]); /// } /// ``` +/// +/// See the [module examples] for the behavior of other range structs. +/// +/// [module examples]: ../#Examples #[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] pub enum RangeInclusive { @@ -2297,11 +2336,13 @@ impl> RangeInclusive { /// array elements up to and including the index indicated by `end`. /// /// ``` -/// #![feature(inclusive_range_syntax)] /// let arr = [0, 1, 2, 3]; -/// assert_eq!(arr[ ...2], [0,1,2 ]); // RangeToInclusive -/// assert_eq!(arr[1...2], [ 1,2 ]); +/// assert_eq!(arr[ ...2], [0, 1, 2]); /// ``` +/// +/// See the [module examples] for the behavior of other range structs. +/// +/// [module examples]: ../#Examples #[derive(Copy, Clone, PartialEq, Eq, Hash)] #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] pub struct RangeToInclusive { diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 8c8925251e5cf..1a6be5d202c9d 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -111,11 +111,15 @@ pub unsafe fn replace(dest: *mut T, mut src: T) -> T { /// # Safety /// /// Beyond accepting a raw pointer, this is unsafe because it semantically -/// moves the value out of `src` without preventing further usage of `src`. -/// If `T` is not `Copy`, then care must be taken to ensure that the value at -/// `src` is not used before the data is overwritten again (e.g. with `write`, -/// `zero_memory`, or `copy_memory`). Note that `*src = foo` counts as a use -/// because it will attempt to drop the value previously at `*src`. +/// moves the value out of `src` without preventing further usage of `src`. If +/// `T` is not [`Copy`], then care must be taken to ensure that the value at +/// `src` is not used before the data is overwritten again (e.g. with +/// [`write`]). Note that `*src = foo` +/// counts as a use because it will attempt to drop the value previously at +/// `*src`. +/// +/// [`Copy`]: ../marker/trait.Copy.html +/// [`write`]: fn.write.html /// /// # Examples /// @@ -190,11 +194,15 @@ pub unsafe fn write(dst: *mut T, src: T) { /// # Safety /// /// Beyond accepting a raw pointer, this is unsafe because it semantically -/// moves the value out of `src` without preventing further usage of `src`. -/// If `T` is not `Copy`, then care must be taken to ensure that the value at -/// `src` is not used before the data is overwritten again (e.g. with `write`, -/// `zero_memory`, or `copy_memory`). Note that `*src = foo` counts as a use -/// because it will attempt to drop the value previously at `*src`. +/// moves the value out of `src` without preventing further usage of `src`. If +/// `T` is not [`Copy`], then care must be taken to ensure that the value at +/// `src` is not used before the data is overwritten again (e.g. with +/// [`write`]). Note that `*src = foo` +/// counts as a use because it will attempt to drop the value previously at +/// `*src`. +/// +/// [`Copy`]: ../marker/trait.Copy.html +/// [`write`]: fn.write.html /// /// # Examples /// diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 07faeee10f1c4..67152ed04ec1d 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -1028,6 +1028,12 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } err_out_of_scope(super_scope, sub_scope, cause) => { + let (value_kind, value_msg) = match err.cmt.cat { + mc::Categorization::Rvalue(_) => + ("temporary value", "temporary value created here"), + _ => + ("borrowed value", "does not live long enough") + }; match cause { euv::ClosureCapture(s) => { // The primary span starts out as the closure creation point. @@ -1038,13 +1044,13 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { Some(primary) => { db.span = MultiSpan::from_span(s); db.span_label(primary, &format!("capture occurs here")); - db.span_label(s, &format!("does not live long enough")); + db.span_label(s, &value_msg); } None => () } } _ => { - db.span_label(error_span, &format!("does not live long enough")); + db.span_label(error_span, &value_msg); } } @@ -1053,14 +1059,15 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { match (sub_span, super_span) { (Some(s1), Some(s2)) if s1 == s2 => { - db.span_label(s1, &"borrowed value dropped before borrower"); + db.span_label(s1, &format!("{} dropped before borrower", value_kind)); db.note("values in a scope are dropped in the opposite order \ they are created"); } _ => { match sub_span { Some(s) => { - db.span_label(s, &"borrowed value must be valid until here"); + db.span_label(s, &format!("{} needs to live until here", + value_kind)); } None => { self.tcx.note_and_explain_region( @@ -1072,7 +1079,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } match super_span { Some(s) => { - db.span_label(s, &"borrowed value only valid until here"); + db.span_label(s, &format!("{} only lives until here", value_kind)); } None => { self.tcx.note_and_explain_region( @@ -1085,9 +1092,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } } - if let Some(span) = statement_scope_span(self.tcx, super_scope) { - db.span_help(span, - "consider using a `let` binding to increase its lifetime"); + if let Some(_) = statement_scope_span(self.tcx, super_scope) { + db.note("consider using a `let` binding to increase its lifetime"); } } diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index ed133d21b8a0f..dcdbe2a85259b 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -883,7 +883,11 @@ impl Destination { Style::FileNameStyle | Style::LineAndColumn => {} Style::LineNumber => { try!(self.start_attr(term::Attr::Bold)); - try!(self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_BLUE))); + if cfg!(windows) { + try!(self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_CYAN))); + } else { + try!(self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_BLUE))); + } } Style::ErrorCode => { try!(self.start_attr(term::Attr::Bold)); @@ -896,6 +900,9 @@ impl Destination { } Style::OldSchoolNoteText | Style::HeaderMsg => { try!(self.start_attr(term::Attr::Bold)); + if cfg!(windows) { + try!(self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_WHITE))); + } } Style::UnderlinePrimary | Style::LabelPrimary => { try!(self.start_attr(term::Attr::Bold)); @@ -904,7 +911,11 @@ impl Destination { Style::UnderlineSecondary | Style::LabelSecondary => { try!(self.start_attr(term::Attr::Bold)); - try!(self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_BLUE))); + if cfg!(windows) { + try!(self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_CYAN))); + } else { + try!(self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_BLUE))); + } } Style::NoStyle => {} Style::Level(l) => { diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index c99bc47044853..d82d7dbe70f92 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -732,7 +732,13 @@ impl Level { pub fn color(self) -> term::color::Color { match self { Bug | Fatal | PhaseFatal | Error => term::color::BRIGHT_RED, - Warning => term::color::YELLOW, + Warning => { + if cfg!(windows) { + term::color::BRIGHT_YELLOW + } else { + term::color::YELLOW + } + }, Note => term::color::BRIGHT_GREEN, Help => term::color::BRIGHT_CYAN, Cancelled => unreachable!(), diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 7f655ad3d149e..6c9cc5f5e132a 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1878,11 +1878,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { hir::DefaultReturn(..) => self.tcx().mk_nil(), }; + let input_tys = self_ty.into_iter().chain(arg_tys).collect(); + + debug!("ty_of_method_or_bare_fn: input_tys={:?}", input_tys); + debug!("ty_of_method_or_bare_fn: output_ty={:?}", output_ty); + (self.tcx().mk_bare_fn(ty::BareFnTy { unsafety: unsafety, abi: abi, sig: ty::Binder(ty::FnSig { - inputs: self_ty.into_iter().chain(arg_tys).collect(), + inputs: input_tys, output: output_ty, variadic: decl.variadic }), diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 225468cb9f40c..f8a2e82edc2a6 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -248,9 +248,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } else if let Some(rest) = size.checked_sub(min_len) { (inner_ty, tcx.mk_array(inner_ty, rest)) } else { - span_err!(tcx.sess, pat.span, E0528, - "pattern requires at least {} elements but array has {}", - min_len, size); + struct_span_err!(tcx.sess, pat.span, E0528, + "pattern requires at least {} elements but array has {}", + min_len, size) + .span_label(pat.span, + &format!("pattern cannot match array of {} elements", size)) + .emit(); (inner_ty, tcx.types.err) } } @@ -270,7 +273,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { _ => {} } } - err.emit(); + + err.span_label( pat.span, + &format!("pattern cannot match with input type `{}`", expected_ty) + ).emit(); } (tcx.types.err, tcx.types.err) } diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 516dd9c64221c..8980cb9076027 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -74,6 +74,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let fn_sig = self.tcx.liberate_late_bound_regions( self.tcx.region_maps.call_site_extent(expr.id, body.id), &fn_ty.sig); + let fn_sig = + (**self).normalize_associated_types_in(body.span, body.id, &fn_sig); check_fn(self, hir::Unsafety::Normal, expr.id, &fn_sig, decl, expr.id, &body); diff --git a/src/test/compile-fail/E0528.rs b/src/test/compile-fail/E0528.rs index 27187bb5aba08..e912650f11292 100644 --- a/src/test/compile-fail/E0528.rs +++ b/src/test/compile-fail/E0528.rs @@ -13,7 +13,9 @@ fn main() { let r = &[1, 2]; match r { - &[a, b, c, rest..] => { //~ ERROR E0528 + &[a, b, c, rest..] => { + //~^ ERROR E0528 + //~| NOTE pattern cannot match array of 2 elements } } } diff --git a/src/test/compile-fail/E0529.rs b/src/test/compile-fail/E0529.rs index 488fe7c7763ae..18d3e68816aad 100644 --- a/src/test/compile-fail/E0529.rs +++ b/src/test/compile-fail/E0529.rs @@ -13,7 +13,9 @@ fn main() { let r: f32 = 1.0; match r { - [a, b] => { //~ ERROR E0529 + [a, b] => { + //~^ ERROR E0529 + //~| NOTE pattern cannot match with input type `f32` } } } diff --git a/src/test/compile-fail/borrowck/borrowck-let-suggestion-suffixes.rs b/src/test/compile-fail/borrowck/borrowck-let-suggestion-suffixes.rs index 6c9f67b2b33d4..95c74348e788b 100644 --- a/src/test/compile-fail/borrowck/borrowck-let-suggestion-suffixes.rs +++ b/src/test/compile-fail/borrowck/borrowck-let-suggestion-suffixes.rs @@ -25,9 +25,9 @@ fn f() { v3.push(&'x'); // statement 6 //~^ ERROR borrowed value does not live long enough - //~| NOTE does not live long enough - //~| NOTE borrowed value only valid until here - //~| HELP consider using a `let` binding to increase its lifetime + //~| NOTE temporary value created here + //~| NOTE temporary value only lives until here + //~| NOTE consider using a `let` binding to increase its lifetime { @@ -35,26 +35,26 @@ fn f() { v4.push(&'y'); //~^ ERROR borrowed value does not live long enough - //~| NOTE does not live long enough - //~| NOTE borrowed value only valid until here - //~| HELP consider using a `let` binding to increase its lifetime + //~| NOTE temporary value created here + //~| NOTE temporary value only lives until here + //~| NOTE consider using a `let` binding to increase its lifetime } // (statement 7) - //~^ NOTE borrowed value must be valid until here + //~^ NOTE temporary value needs to live until here let mut v5 = Vec::new(); // statement 8 v5.push(&'z'); //~^ ERROR borrowed value does not live long enough - //~| NOTE does not live long enough - //~| NOTE borrowed value only valid until here - //~| HELP consider using a `let` binding to increase its lifetime + //~| NOTE temporary value created here + //~| NOTE temporary value only lives until here + //~| NOTE consider using a `let` binding to increase its lifetime v1.push(&old[0]); } //~^ NOTE borrowed value dropped before borrower -//~| NOTE borrowed value must be valid until here -//~| NOTE borrowed value must be valid until here +//~| NOTE temporary value needs to live until here +//~| NOTE temporary value needs to live until here fn main() { f(); diff --git a/src/test/compile-fail/regions-escape-loop-via-vec.rs b/src/test/compile-fail/regions-escape-loop-via-vec.rs index 8c026df7d9754..f5ea7a2108e79 100644 --- a/src/test/compile-fail/regions-escape-loop-via-vec.rs +++ b/src/test/compile-fail/regions-escape-loop-via-vec.rs @@ -24,8 +24,8 @@ fn broken() { x += 1; //~ ERROR cannot assign //~^ NOTE assignment to borrowed `x` occurs here } - //~^ NOTE borrowed value only valid until here + //~^ NOTE borrowed value only lives until here } -//~^ NOTE borrowed value must be valid until here +//~^ NOTE borrowed value needs to live until here fn main() { } diff --git a/src/test/run-pass/issue-36023.rs b/src/test/run-pass/issue-36023.rs index f6c03b384f23d..53a8a403b6410 100644 --- a/src/test/run-pass/issue-36023.rs +++ b/src/test/run-pass/issue-36023.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// min-llvm-version 3.9 + use std::ops::Deref; fn main() { diff --git a/src/test/run-pass/issue-36139-normalize-closure-sig.rs b/src/test/run-pass/issue-36139-normalize-closure-sig.rs new file mode 100644 index 0000000000000..adde0ed306674 --- /dev/null +++ b/src/test/run-pass/issue-36139-normalize-closure-sig.rs @@ -0,0 +1,28 @@ +// Copyright 2016 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. + +// Previously the closure's argument would be inferred to +// >::Item, causing an error in MIR type +// checking + +trait ITrait<'a> {type Item;} + +struct S {} + +impl<'a> ITrait<'a> for S { type Item = &'a mut usize; } + +fn m(_: F) + where I: for<'a> ITrait<'a>, + F: for<'a> FnMut(>::Item) { } + + +fn main() { + m::(|x| { *x += 1; }); +} diff --git a/src/test/compile-fail/borrowck/borrowck-let-suggestion.rs b/src/test/ui/lifetimes/borrowck-let-suggestion.rs similarity index 66% rename from src/test/compile-fail/borrowck/borrowck-let-suggestion.rs rename to src/test/ui/lifetimes/borrowck-let-suggestion.rs index ef8f44c1df789..eeafaab44c620 100644 --- a/src/test/compile-fail/borrowck/borrowck-let-suggestion.rs +++ b/src/test/ui/lifetimes/borrowck-let-suggestion.rs @@ -10,12 +10,7 @@ fn f() { let x = [1].iter(); - //~^ ERROR borrowed value does not live long enough - //~| NOTE does not live long enough - //~| NOTE borrowed value only valid until here - //~| HELP consider using a `let` binding to increase its lifetime } -//~^ borrowed value must be valid until here fn main() { f(); diff --git a/src/test/ui/lifetimes/borrowck-let-suggestion.stderr b/src/test/ui/lifetimes/borrowck-let-suggestion.stderr new file mode 100644 index 0000000000000..91600340019c3 --- /dev/null +++ b/src/test/ui/lifetimes/borrowck-let-suggestion.stderr @@ -0,0 +1,14 @@ +error: borrowed value does not live long enough + --> $DIR/borrowck-let-suggestion.rs:12:13 + | +12 | let x = [1].iter(); + | ^^^ - temporary value only lives until here + | | + | temporary value created here +13 | } + | - temporary value needs to live until here + | + = note: consider using a `let` binding to increase its lifetime + +error: aborting due to previous error + diff --git a/src/test/ui/span/issue-11925.stderr b/src/test/ui/span/issue-11925.stderr index d379cfc3d68a7..3fedb2884bc58 100644 --- a/src/test/ui/span/issue-11925.stderr +++ b/src/test/ui/span/issue-11925.stderr @@ -5,10 +5,10 @@ error: `x` does not live long enough | ^ | | | does not live long enough - | borrowed value only valid until here + | borrowed value only lives until here ... 23 | } - | - borrowed value must be valid until here + | - borrowed value needs to live until here error: aborting due to previous error diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 6090cb4f52725..5d522736089ea 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -152,6 +152,9 @@ pub struct Config { // Version of LLDB pub lldb_version: Option, + // Version of LLVM + pub llvm_version: Option, + // Path to the android tools pub android_cross_path: PathBuf, diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index af33d76be1b0d..899a366a4bb74 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -44,7 +44,9 @@ impl EarlyProps { (config.mode == common::Pretty && parse_name_directive(ln, "ignore-pretty")) || (config.target != config.host && parse_name_directive(ln, "ignore-cross-compile")) || - ignore_gdb(config, ln) || ignore_lldb(config, ln); + ignore_gdb(config, ln) || + ignore_lldb(config, ln) || + ignore_llvm(config, ln); props.should_fail = props.should_fail || parse_name_directive(ln, "should-fail"); }); @@ -115,6 +117,24 @@ impl EarlyProps { false } } + + fn ignore_llvm(config: &Config, line: &str) -> bool { + if let Some(ref actual_version) = config.llvm_version { + if line.contains("min-llvm-version") { + let min_version = line.trim() + .split(' ') + .last() + .expect("Malformed llvm version directive"); + // Ignore if actual version is smaller the minimum required + // version + &actual_version[..] < min_version + } else { + false + } + } else { + false + } + } } } diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 90641b5c476d7..4afeb3613319b 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -99,6 +99,7 @@ pub fn parse_config(args: Vec ) -> Config { optopt("", "host", "the host to build for", "HOST"), optopt("", "gdb-version", "the version of GDB used", "VERSION STRING"), optopt("", "lldb-version", "the version of LLDB used", "VERSION STRING"), + optopt("", "llvm-version", "the version of LLVM used", "VERSION STRING"), optopt("", "android-cross-path", "Android NDK standalone path", "PATH"), optopt("", "adb-path", "path to the android debugger", "PATH"), optopt("", "adb-test-dir", "path to tests for the android debugger", "PATH"), @@ -170,6 +171,7 @@ pub fn parse_config(args: Vec ) -> Config { host: opt_str2(matches.opt_str("host")), gdb_version: extract_gdb_version(matches.opt_str("gdb-version")), lldb_version: extract_lldb_version(matches.opt_str("lldb-version")), + llvm_version: matches.opt_str("llvm-version"), android_cross_path: opt_path(matches, "android-cross-path"), adb_path: opt_str2(matches.opt_str("adb-path")), adb_test_dir: format!("{}/{}",