diff --git a/RELEASES.md b/RELEASES.md index 7ae7dc9935b6d..1d888731e94a2 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -4,34 +4,34 @@ Version 1.30.0 (2018-10-25) Language -------- - [Procedural macros are now available.][52081] These kinds of macros allow for - more powerful code generation, there is a [new chapter available][proc-macros] - in Rust Programming Language book that goes further in depth. + more powerful code generation. There is a [new chapter available][proc-macros] + in the Rust Programming Language book that goes further in depth. - [You can now use keywords as identifiers using the raw identifiers - syntax (`r#`).][53236] e.g. `let r#for = true;` + syntax (`r#`),][53236] e.g. `let r#for = true;` - [Using anonymous parameters in traits is now deprecated with a warning and will be a hard error in the 2018 edition.][53272] - [You can now use `crate` in paths.][54404] This allows you to refer to the - crate root in the path. e.g. `use crate::foo;` refers to `foo` in `src/lib.rs`. -- [Using a external crate now no longer requires being prefixed with `::`.][54404] - e.g. previously using a external crate in a module without a use statement - required `let json = ::serde_json::from_str(foo);` can now be written + crate root in the path, e.g. `use crate::foo;` refers to `foo` in `src/lib.rs`. +- [Using a external crate no longer requires being prefixed with `::`.][54404] + Previously, using a external crate in a module without a use statement + required `let json = ::serde_json::from_str(foo);` but can now be written as `let json = serde_json::from_str(foo);`. - [You can now apply the `#[used]` attribute to static items to prevent the - compiler from optimising them away even if they appear to be unused.][51363] + compiler from optimising them away, even if they appear to be unused,][51363] e.g. `#[used] static FOO: u32 = 1;` - [You can now import and reexport macros from other crates with the `use` syntax.][50911] Macros exported with `#[macro_export]` are now placed into the root module of the crate. If your macro relies on calling other local - macros it is recommended to export with the - `#[macro_export(local_inner_macros)]` attribute so that users won't have to - import those macros. -- [`mod.rs` files are now optional.][54146] Previously if you had a `foo` module + macros, it is recommended to export with the + `#[macro_export(local_inner_macros)]` attribute so users won't have to import + those macros. +- [`mod.rs` files are now optional.][54146] Previously, if you had a `foo` module with a `bar` submodule, you would have `src/foo/mod.rs` and `src/foo/bar.rs`. Now you can have `src/foo.rs` and `src/foo/bar.rs` to achieve the same effect. - [You can now catch visibility keywords (e.g. `pub`, `pub(crate)`) in macros using the `vis` specifier.][53370] -- [Non-macro attributes now allow all forms of literals not just - strings.][53044] e.g. Previously you would write `#[attr("true")]` you can now +- [Non-macro attributes now allow all forms of literals, not just + strings.][53044] Previously, you would write `#[attr("true")]`, and you can now write `#[attr(true)]`. - [You can now specify a function to handle a panic in the Rust runtime with the `#[panic_handler]` attribute.][51366] @@ -54,9 +54,9 @@ Stabilized APIs - [`Ipv6Addr::UNSPECIFIED`] - [`Iterator::find_map`] - The following methods are a replacement methods for `trim_left`, `trim_right`, - `trim_left_matches`, and `trim_right_matches`. Which will be deprecated - in 1.33.0. + The following methods are replacement methods for `trim_left`, `trim_right`, + `trim_left_matches`, and `trim_right_matches`, which will be deprecated + in 1.33.0: - [`str::trim_end_matches`] - [`str::trim_end`] - [`str::trim_start_matches`] @@ -76,12 +76,12 @@ Misc ---- - [`rustdoc` allows you to specify what edition to treat your code as with the `--edition` option.][54057] -- [`rustdoc` now has the `--color` (Specify whether to output color) and - `--error-format` (Specify error format e.g. `json`) options.][53003] +- [`rustdoc` now has the `--color` (specify whether to output color) and + `--error-format` (specify error format, e.g. `json`) options.][53003] - [We now distribute a `rust-gdbgui` script that invokes `gdbgui` with Rust debug symbols.][53774] - [Attributes from Rust tools such as `rustfmt` or `clippy` are now - available.][53459] e.g. `#[rustfmt::skip]` will skip formatting the next item. + available,][53459] e.g. `#[rustfmt::skip]` will skip formatting the next item. [50911]: https://github.com/rust-lang/rust/pull/50911/ [51363]: https://github.com/rust-lang/rust/pull/51363/ @@ -153,7 +153,7 @@ Compiler Libraries --------- -- [`Once::call_once` now no longer requires `Once` to be `'static`.][52239] +- [`Once::call_once` no longer requires `Once` to be `'static`.][52239] - [`BuildHasherDefault` now implements `PartialEq` and `Eq`.][52402] - [`Box`, `Box`, and `Box` now implement `Clone`.][51912] - [Implemented `PartialEq<&str>` for `OsString` and `PartialEq` @@ -169,10 +169,10 @@ Stabilized APIs Cargo ----- -- [Cargo can silently fix some bad lockfiles ][cargo/5831] You can use - `--locked` to disable this behaviour. +- [Cargo can silently fix some bad lockfiles.][cargo/5831] You can use + `--locked` to disable this behavior. - [`cargo-install` will now allow you to cross compile an install - using `--target`][cargo/5614] + using `--target`.][cargo/5614] - [Added the `cargo-fix` subcommand to automatically move project code from 2015 edition to 2018.][cargo/5723] - [`cargo doc` can now optionally document private types using the @@ -184,15 +184,15 @@ Misc the specified level to that level.][52354] For example `--cap-lints warn` will demote `deny` and `forbid` lints to `warn`. - [`rustc` and `rustdoc` will now have the exit code of `1` if compilation - fails, and `101` if there is a panic.][52197] + fails and `101` if there is a panic.][52197] - [A preview of clippy has been made available through rustup.][51122] - You can install the preview with `rustup component add clippy-preview` + You can install the preview with `rustup component add clippy-preview`. Compatibility Notes ------------------- - [`str::{slice_unchecked, slice_unchecked_mut}` are now deprecated.][51807] Use `str::get_unchecked(begin..end)` instead. -- [`std::env::home_dir` is now deprecated for its unintuitive behaviour.][51656] +- [`std::env::home_dir` is now deprecated for its unintuitive behavior.][51656] Consider using the `home_dir` function from https://crates.io/crates/dirs instead. - [`rustc` will no longer silently ignore invalid data in target spec.][52330] @@ -432,7 +432,7 @@ Language be used as an identifier. - [The dyn syntax is now available.][49968] This syntax is equivalent to the bare `Trait` syntax, and should make it clearer when being used in tandem with - `impl Trait`. Since it is equivalent to the following syntax: + `impl Trait` because it is equivalent to the following syntax: `&Trait == &dyn Trait`, `&mut Trait == &mut dyn Trait`, and `Box == Box`. - [Attributes on generic parameters such as types and lifetimes are @@ -495,10 +495,10 @@ Cargo a different directory than `target` for placing compilation artifacts. - [Cargo will be adding automatic target inference for binaries, benchmarks, examples, and tests in the Rust 2018 edition.][cargo/5335] If your project specifies - specific targets e.g. using `[[bin]]` and have other binaries in locations + specific targets, e.g. using `[[bin]]`, and have other binaries in locations where cargo would infer a binary, Cargo will produce a warning. You can - disable this feature ahead of time by setting any of the following `autobins`, - `autobenches`, `autoexamples`, `autotests` to false. + disable this feature ahead of time by setting any of the following to false: + `autobins`, `autobenches`, `autoexamples`, `autotests`. - [Cargo will now cache compiler information.][cargo/5359] This can be disabled by setting `CARGO_CACHE_RUSTC_INFO=0` in your environment. @@ -514,8 +514,8 @@ Compatibility Notes work.][49896] e.g. `::core::prelude::v1::StrExt::is_empty("")` will not compile, `"".is_empty()` will still compile. - [`Debug` output on `atomic::{AtomicBool, AtomicIsize, AtomicPtr, AtomicUsize}` - will only print the inner type.][48553] e.g. - `print!("{:?}", AtomicBool::new(true))` will print `true` + will only print the inner type.][48553] E.g. + `print!("{:?}", AtomicBool::new(true))` will print `true`, not `AtomicBool(true)`. - [The maximum number for `repr(align(N))` is now 2²⁹.][50378] Previously you could enter higher numbers but they were not supported by LLVM. Up to 512MB @@ -578,7 +578,7 @@ Version 1.26.2 (2018-06-05) Compatibility Notes ------------------- -- [The borrow checker was fixed to avoid unsoundness when using match ergonomics][51117] +- [The borrow checker was fixed to avoid unsoundness when using match ergonomics.][51117] [51117]: https://github.com/rust-lang/rust/issues/51117 @@ -589,18 +589,18 @@ Version 1.26.1 (2018-05-29) Tools ----- -- [RLS now works on Windows][50646] -- [Rustfmt stopped badly formatting text in some cases][rustfmt/2695] +- [RLS now works on Windows.][50646] +- [Rustfmt stopped badly formatting text in some cases.][rustfmt/2695] Compatibility Notes -------- - [`fn main() -> impl Trait` no longer works for non-Termination - trait][50656] + trait.][50656] This reverts an accidental stabilization. -- [`NaN > NaN` no longer returns true in const-fn contexts][50812] -- [Prohibit using turbofish for `impl Trait` in method arguments][50950] +- [`NaN > NaN` no longer returns true in const-fn contexts.][50812] +- [Prohibit using turbofish for `impl Trait` in method arguments.][50950] [50646]: https://github.com/rust-lang/rust/issues/50646 [50656]: https://github.com/rust-lang/rust/pull/50656 @@ -616,18 +616,18 @@ Language - [Closures now implement `Copy` and/or `Clone` if all captured variables implement either or both traits.][49299] - [The inclusive range syntax e.g. `for x in 0..=10` is now stable.][47813] -- [The `'_` lifetime is now stable. The underscore lifetime can be used anywhere where a +- [The `'_` lifetime is now stable. The underscore lifetime can be used anywhere a lifetime can be elided.][49458] - [`impl Trait` is now stable allowing you to have abstract types in returns - or in function parameters.][49255] e.g. `fn foo() -> impl Iterator` or + or in function parameters.][49255] E.g. `fn foo() -> impl Iterator` or `fn open(path: impl AsRef)`. - [Pattern matching will now automatically apply dereferences.][49394] - [128-bit integers in the form of `u128` and `i128` are now stable.][49101] - [`main` can now return `Result<(), E: Debug>`][49162] in addition to `()`. - [A lot of operations are now available in a const context.][46882] E.g. You can now index into constant arrays, reference and dereference into constants, - and use Tuple struct constructors. -- [Fixed entry slice patterns are now stable.][48516] e.g. + and use tuple struct constructors. +- [Fixed entry slice patterns are now stable.][48516] E.g. ```rust let points = [1, 2, 3, 4]; match points { @@ -1052,7 +1052,7 @@ Language Compiler -------- - [Enabled `TrapUnreachable` in LLVM which should mitigate the impact of - undefined behaviour.][45920] + undefined behavior.][45920] - [rustc now suggests renaming import if names clash.][45660] - [Display errors/warnings correctly when there are zero-width or wide characters.][45711] diff --git a/src/Cargo.lock b/src/Cargo.lock index 3361e81ecfe6d..e3a262fc97fd4 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -349,6 +349,7 @@ dependencies = [ "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2135,11 +2136,13 @@ dependencies = [ "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", + "rustc_allocator 0.0.0", "rustc_data_structures 0.0.0", "rustc_incremental 0.0.0", "rustc_metadata_utils 0.0.0", "rustc_mir 0.0.0", "rustc_target 0.0.0", + "serialize 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", ] diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index c27f4f056d747..ffc5adbebb34f 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -594,7 +594,7 @@ def exe_suffix(): return '' def bootstrap_binary(self): - """Return the path of the boostrap binary + """Return the path of the bootstrap binary >>> rb = RustBuild() >>> rb.build_dir = "build" diff --git a/src/etc/lldb_rust_formatters.py b/src/etc/lldb_rust_formatters.py index 4427313f9e5b3..2bbd4372721cb 100644 --- a/src/etc/lldb_rust_formatters.py +++ b/src/etc/lldb_rust_formatters.py @@ -277,7 +277,7 @@ def print_std_string_val(val, internal_dict): #=-------------------------------------------------------------------------------------------------- def print_array_of_values(array_name, data_ptr_val, length, internal_dict): - """Prints a contigous memory range, interpreting it as values of the + """Prints a contiguous memory range, interpreting it as values of the pointee-type of data_ptr_val.""" data_ptr_type = data_ptr_val.type diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 8c950cd06d9e3..24c8fd3a969ca 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -77,7 +77,7 @@ use self::Entry::*; /// movie_reviews.insert("Office Space", "Deals with real issues in the workplace."); /// movie_reviews.insert("Pulp Fiction", "Masterpiece."); /// movie_reviews.insert("The Godfather", "Very enjoyable."); -/// movie_reviews.insert("The Blues Brothers", "Eye lyked it alot."); +/// movie_reviews.insert("The Blues Brothers", "Eye lyked it a lot."); /// /// // check for a specific one. /// if !movie_reviews.contains_key("Les Misérables") { diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs index 35e4eea756d41..4efcaae59b012 100644 --- a/src/libcore/alloc.rs +++ b/src/libcore/alloc.rs @@ -518,7 +518,7 @@ pub unsafe trait GlobalAlloc { /// The block is described by the given `ptr` pointer and `layout`. /// /// If this returns a non-null pointer, then ownership of the memory block - /// referenced by `ptr` has been transferred to this alloctor. + /// referenced by `ptr` has been transferred to this allocator. /// The memory may or may not have been deallocated, /// and should be considered unusable (unless of course it was /// transferred back to the caller again via the return value of diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 56a24168e28d9..cceae9249e456 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -1025,7 +1025,7 @@ extern "rust-intrinsic" { /// // to avoid problems in case something further down panics. /// src.set_len(0); /// - /// // The two regions cannot overlap becuase mutable references do + /// // The two regions cannot overlap because mutable references do /// // not alias, and two different vectors cannot own the same /// // memory. /// ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len); diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index 07ba285ea5cb3..fd3e50998fe8c 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -304,7 +304,7 @@ impl> RangeTo { } } -/// An range bounded inclusively below and above (`start..=end`). +/// A range bounded inclusively below and above (`start..=end`). /// /// The `RangeInclusive` `start..=end` contains all values with `x >= start` /// and `x <= end`. It is empty unless `start <= end`. diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs index 0224560af4c76..a03c080fb3f34 100644 --- a/src/libcore/pin.rs +++ b/src/libcore/pin.rs @@ -102,7 +102,7 @@ pub use marker::Unpin; /// value in place, preventing the value referenced by that pointer from being moved /// unless it implements [`Unpin`]. /// -/// See the [`pin` module] documentation for furthur explanation on pinning. +/// See the [`pin` module] documentation for further explanation on pinning. /// /// [`Unpin`]: ../../std/marker/trait.Unpin.html /// [`pin` module]: ../../std/pin/index.html diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 1c761ba21b3ec..b699cb028842b 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -38,7 +38,7 @@ //! underlying object is live and no reference (just raw pointers) is used to //! access the same memory. //! -//! These axioms, along with careful use of [`offset`] for pointer arithmentic, +//! These axioms, along with careful use of [`offset`] for pointer arithmetic, //! are enough to correctly implement many useful things in unsafe code. Stronger guarantees //! will be provided eventually, as the [aliasing] rules are being determined. For more //! information, see the [book] as well as the section in the reference devoted diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index 6b9c0aac52e79..2c52697d56d27 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -415,8 +415,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { args: I) -> CFGIndex { let func_or_rcvr_exit = self.expr(func_or_rcvr, pred); let ret = self.straightline(call_expr, func_or_rcvr_exit, args); - // FIXME(canndrew): This is_never should probably be an is_uninhabited. - if self.tables.expr_ty(call_expr).is_never() { + if self.tables.expr_ty(call_expr).conservative_is_uninhabited(self.tcx) { self.add_unreachable_node() } else { ret diff --git a/src/librustc/hir/def_id.rs b/src/librustc/hir/def_id.rs index a09fd5df557f5..e378e1b8be0e9 100644 --- a/src/librustc/hir/def_id.rs +++ b/src/librustc/hir/def_id.rs @@ -40,7 +40,7 @@ impl ::std::fmt::Debug for CrateNum { match self { CrateNum::Index(id) => write!(fmt, "crate{}", id.private), CrateNum::Invalid => write!(fmt, "invalid crate"), - CrateNum::BuiltinMacros => write!(fmt, "bultin macros crate"), + CrateNum::BuiltinMacros => write!(fmt, "builtin macros crate"), CrateNum::ReservedForIncrCompCache => write!(fmt, "crate for decoding incr comp cache"), } } @@ -101,7 +101,7 @@ impl fmt::Display for CrateNum { match self { CrateNum::Index(id) => fmt::Display::fmt(&id.private, f), CrateNum::Invalid => write!(f, "invalid crate"), - CrateNum::BuiltinMacros => write!(f, "bultin macros crate"), + CrateNum::BuiltinMacros => write!(f, "builtin macros crate"), CrateNum::ReservedForIncrCompCache => write!(f, "crate for decoding incr comp cache"), } } diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index a1363168f0117..afb5f23db5b83 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1147,7 +1147,7 @@ impl<'a> LoweringContext<'a> { TyKind::Slice(ref ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)), TyKind::Ptr(ref mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)), TyKind::Rptr(ref region, ref mt) => { - let span = t.span.shrink_to_lo(); + let span = self.sess.source_map().next_point(t.span.shrink_to_lo()); let lifetime = match *region { Some(ref lt) => self.lower_lifetime(lt), None => self.elided_ref_lifetime(span), diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 08d46793d97bf..ad2fa48610b0e 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -180,7 +180,7 @@ impl<'a> State<'a> { State { s: pp::mk_printer(out, default_columns), cm: Some(cm), - comments: comments.clone(), + comments, literals: literals.unwrap_or_default().into_iter().peekable(), cur_cmnt: 0, boxes: Vec::new(), diff --git a/src/librustc/ich/caching_codemap_view.rs b/src/librustc/ich/caching_codemap_view.rs index 97114779042af..fbf4297222f9b 100644 --- a/src/librustc/ich/caching_codemap_view.rs +++ b/src/librustc/ich/caching_codemap_view.rs @@ -44,7 +44,7 @@ impl<'cm> CachingSourceMapView<'cm> { CachingSourceMapView { source_map, - line_cache: [entry.clone(), entry.clone(), entry.clone()], + line_cache: [entry.clone(), entry.clone(), entry], time_stamp: 0, } } diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs index de8f57ee79666..0ee03bc4c6e00 100644 --- a/src/librustc/infer/combine.rs +++ b/src/librustc/infer/combine.rs @@ -251,6 +251,7 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> { dir: RelationDir) -> RelateResult<'tcx, Generalization<'tcx>> { + debug!("generalize(ty={:?}, for_vid={:?}, dir={:?}", ty, for_vid, dir); // Determine the ambient variance within which `ty` appears. // The surrounding equation is: // @@ -273,8 +274,15 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> { root_ty: ty, }; - let ty = generalize.relate(&ty, &ty)?; + let ty = match generalize.relate(&ty, &ty) { + Ok(ty) => ty, + Err(e) => { + debug!("generalize: failure {:?}", e); + return Err(e); + } + }; let needs_wf = generalize.needs_wf; + debug!("generalize: success {{ {:?}, {:?} }}", ty, needs_wf); Ok(Generalization { ty, needs_wf }) } } diff --git a/src/librustc/infer/equate.rs b/src/librustc/infer/equate.rs index 854960492c9bd..c7b5ddb83410f 100644 --- a/src/librustc/infer/equate.rs +++ b/src/librustc/infer/equate.rs @@ -74,6 +74,9 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> let infcx = self.fields.infcx; let a = infcx.type_variables.borrow_mut().replace_if_possible(a); let b = infcx.type_variables.borrow_mut().replace_if_possible(b); + + debug!("{}.tys: replacements ({:?}, {:?})", self.tag(), a, b); + match (&a.sty, &b.sty) { (&ty::Infer(TyVar(a_id)), &ty::Infer(TyVar(b_id))) => { infcx.type_variables.borrow_mut().equate(a_id, b_id); diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 1b258a23462c7..9e566658dc7bd 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1197,8 +1197,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } hir::ExprKind::Call(ref f, ref args) => { - // FIXME(canndrew): This is_never should really be an is_uninhabited - let succ = if self.tables.expr_ty(expr).is_never() { + let succ = if self.tables.expr_ty(expr).conservative_is_uninhabited(self.ir.tcx) { self.s.exit_ln } else { succ @@ -1208,8 +1207,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } hir::ExprKind::MethodCall(.., ref args) => { - // FIXME(canndrew): This is_never should really be an is_uninhabited - let succ = if self.tables.expr_ty(expr).is_never() { + let succ = if self.tables.expr_ty(expr).conservative_is_uninhabited(self.ir.tcx) { self.s.exit_ln } else { succ diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 13e6f7a4c745a..9d3f37bc36a9d 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -93,6 +93,7 @@ use util::nodemap::ItemLocalSet; #[derive(Clone, Debug, PartialEq)] pub enum Categorization<'tcx> { Rvalue(ty::Region<'tcx>), // temporary val, argument is its scope + ThreadLocal(ty::Region<'tcx>), // value that cannot move, but still restricted in scope StaticItem, Upvar(Upvar), // upvar referenced by closure env Local(ast::NodeId), // local variable @@ -268,6 +269,7 @@ impl<'tcx> cmt_<'tcx> { Categorization::Deref(ref base_cmt, _) => { base_cmt.immutability_blame() } + Categorization::ThreadLocal(..) | Categorization::StaticItem => { // Do we want to do something here? None @@ -715,17 +717,23 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { } Def::Static(def_id, mutbl) => { - // `#[thread_local]` statics may not outlive the current function. - for attr in &self.tcx.get_attrs(def_id)[..] { - if attr.check_name("thread_local") { - return Ok(self.cat_rvalue_node(hir_id, span, expr_ty)); - } - } + // `#[thread_local]` statics may not outlive the current function, but + // they also cannot be moved out of. + let is_thread_local = self.tcx.get_attrs(def_id)[..] + .iter() + .any(|attr| attr.check_name("thread_local")); + + let cat = if is_thread_local { + let re = self.temporary_scope(hir_id.local_id); + Categorization::ThreadLocal(re) + } else { + Categorization::StaticItem + }; Ok(cmt_ { hir_id, - span:span, - cat:Categorization::StaticItem, + span, + cat, mutbl: if mutbl { McDeclared } else { McImmutable}, ty:expr_ty, note: NoteNone @@ -1408,6 +1416,7 @@ impl<'tcx> cmt_<'tcx> { match self.cat { Categorization::Rvalue(..) | Categorization::StaticItem | + Categorization::ThreadLocal(..) | Categorization::Local(..) | Categorization::Deref(_, UnsafePtr(..)) | Categorization::Deref(_, BorrowedPtr(..)) | @@ -1439,6 +1448,7 @@ impl<'tcx> cmt_<'tcx> { } Categorization::Rvalue(..) | + Categorization::ThreadLocal(..) | Categorization::Local(..) | Categorization::Upvar(..) | Categorization::Deref(_, UnsafePtr(..)) => { // yes, it's aliasable, but... @@ -1485,6 +1495,9 @@ impl<'tcx> cmt_<'tcx> { Categorization::StaticItem => { "static item".into() } + Categorization::ThreadLocal(..) => { + "thread-local static item".into() + } Categorization::Rvalue(..) => { "non-place".into() } diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 98e80d333c1c8..361abb1689619 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -2235,21 +2235,46 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { }; let mut err = report_missing_lifetime_specifiers(self.tcx.sess, span, lifetime_refs.len()); + let mut add_label = true; if let Some(params) = error { if lifetime_refs.len() == 1 { - self.report_elision_failure(&mut err, params); + add_label = add_label && self.report_elision_failure(&mut err, params, span); } } + if add_label { + add_missing_lifetime_specifiers_label(&mut err, span, lifetime_refs.len()); + } err.emit(); } + fn suggest_lifetime(&self, db: &mut DiagnosticBuilder<'_>, span: Span, msg: &str) -> bool { + match self.tcx.sess.source_map().span_to_snippet(span) { + Ok(ref snippet) => { + let (sugg, applicability) = if snippet == "&" { + ("&'static ".to_owned(), Applicability::MachineApplicable) + } else if snippet == "'_" { + ("'static".to_owned(), Applicability::MachineApplicable) + } else { + (format!("{} + 'static", snippet), Applicability::MaybeIncorrect) + }; + db.span_suggestion_with_applicability(span, msg, sugg, applicability); + false + } + Err(_) => { + db.help(msg); + true + } + } + } + fn report_elision_failure( &mut self, db: &mut DiagnosticBuilder<'_>, params: &[ElisionFailureInfo], - ) { + span: Span, + ) -> bool { let mut m = String::new(); let len = params.len(); @@ -2304,7 +2329,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { "this function's return type contains a borrowed value, but \ there is no value for it to be borrowed from" ); - help!(db, "consider giving it a 'static lifetime"); + self.suggest_lifetime(db, span, "consider giving it a 'static lifetime") } else if elided_len == 0 { help!( db, @@ -2312,11 +2337,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { an elided lifetime, but the lifetime cannot be derived from \ the arguments" ); - help!( - db, - "consider giving it an explicit bounded or 'static \ - lifetime" - ); + let msg = "consider giving it an explicit bounded or 'static lifetime"; + self.suggest_lifetime(db, span, msg) } else if elided_len == 1 { help!( db, @@ -2324,6 +2346,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { the signature does not say which {} it is borrowed from", m ); + true } else { help!( db, @@ -2331,6 +2354,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { the signature does not say whether it is borrowed from {}", m ); + true } } @@ -2744,26 +2768,28 @@ fn insert_late_bound_lifetimes( } } -pub fn report_missing_lifetime_specifiers( +fn report_missing_lifetime_specifiers( sess: &Session, span: Span, count: usize, ) -> DiagnosticBuilder<'_> { - let mut err = struct_span_err!( + struct_span_err!( sess, span, E0106, "missing lifetime specifier{}", if count > 1 { "s" } else { "" } - ); + ) +} - let msg: Cow<'static, str> = if count > 1 { - format!("expected {} lifetime parameters", count).into() +fn add_missing_lifetime_specifiers_label( + err: &mut DiagnosticBuilder<'_>, + span: Span, + count: usize, +) { + if count > 1 { + err.span_label(span, format!("expected {} lifetime parameters", count)); } else { - "expected lifetime parameter".into() + err.span_label(span, "expected lifetime parameter"); }; - - err.span_label(span, msg); - - err } diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index 4c2b2b2d41d1b..5054f52277870 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -632,7 +632,7 @@ pub fn read_target_uint(endianness: layout::Endian, mut source: &[u8]) -> Result } //////////////////////////////////////////////////////////////////////////////// -// Methods to faciliate working with signed integers stored in a u128 +// Methods to facilitate working with signed integers stored in a u128 //////////////////////////////////////////////////////////////////////////////// pub fn sign_extend(value: u128, size: Size) -> u128 { diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 62b5327ae4692..f1c5030c6419a 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -469,7 +469,7 @@ pub enum BorrowKind { /// } /// /// This can't be a shared borrow because mutably borrowing (*x as Some).0 - /// should not prevent `if let None = x { ... }`, for example, becase the + /// should not prevent `if let None = x { ... }`, for example, because the /// mutating `(*x as Some).0` can't affect the discriminant of `x`. /// We can also report errors with this kind of borrow differently. Shallow, diff --git a/src/librustc/mir/traversal.rs b/src/librustc/mir/traversal.rs index db1bc3e7519c2..a1e2b7a06468d 100644 --- a/src/librustc/mir/traversal.rs +++ b/src/librustc/mir/traversal.rs @@ -34,6 +34,7 @@ pub struct Preorder<'a, 'tcx: 'a> { mir: &'a Mir<'tcx>, visited: BitSet, worklist: Vec, + root_is_start_block: bool, } impl<'a, 'tcx> Preorder<'a, 'tcx> { @@ -44,6 +45,7 @@ impl<'a, 'tcx> Preorder<'a, 'tcx> { mir, visited: BitSet::new_empty(mir.basic_blocks().len()), worklist, + root_is_start_block: root == START_BLOCK, } } } @@ -75,15 +77,19 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> { fn size_hint(&self) -> (usize, Option) { // All the blocks, minus the number of blocks we've visited. - let remaining = self.mir.basic_blocks().len() - self.visited.count(); + let upper = self.mir.basic_blocks().len() - self.visited.count(); - // We will visit all remaining blocks exactly once. - (remaining, Some(remaining)) + let lower = if self.root_is_start_block { + // We will visit all remaining blocks exactly once. + upper + } else { + self.worklist.len() + }; + + (lower, Some(upper)) } } -impl<'a, 'tcx> ExactSizeIterator for Preorder<'a, 'tcx> {} - /// Postorder traversal of a graph. /// /// Postorder traversal is when each node is visited after all of it's @@ -105,7 +111,8 @@ impl<'a, 'tcx> ExactSizeIterator for Preorder<'a, 'tcx> {} pub struct Postorder<'a, 'tcx: 'a> { mir: &'a Mir<'tcx>, visited: BitSet, - visit_stack: Vec<(BasicBlock, Successors<'a>)> + visit_stack: Vec<(BasicBlock, Successors<'a>)>, + root_is_start_block: bool, } impl<'a, 'tcx> Postorder<'a, 'tcx> { @@ -113,7 +120,8 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> { let mut po = Postorder { mir, visited: BitSet::new_empty(mir.basic_blocks().len()), - visit_stack: Vec::new() + visit_stack: Vec::new(), + root_is_start_block: root == START_BLOCK, }; @@ -214,15 +222,19 @@ impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> { fn size_hint(&self) -> (usize, Option) { // All the blocks, minus the number of blocks we've visited. - let remaining = self.mir.basic_blocks().len() - self.visited.count(); + let upper = self.mir.basic_blocks().len() - self.visited.count(); - // We will visit all remaining blocks exactly once. - (remaining, Some(remaining)) + let lower = if self.root_is_start_block { + // We will visit all remaining blocks exactly once. + upper + } else { + self.visit_stack.len() + }; + + (lower, Some(upper)) } } -impl<'a, 'tcx> ExactSizeIterator for Postorder<'a, 'tcx> {} - /// Reverse postorder traversal of a graph /// /// Reverse postorder is the reverse order of a postorder traversal. diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index dc0039926448c..ea30752a820ee 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -412,7 +412,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { flags.push(("crate_local".to_owned(), None)); } - // Allow targetting all integers using `{integral}`, even if the exact type was resolved + // Allow targeting all integers using `{integral}`, even if the exact type was resolved if self_ty.is_integral() { flags.push(("_Self".to_owned(), Some("{integral}".to_owned()))); } diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index b29ee8f7cdce4..b266fbe0d1145 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -340,7 +340,7 @@ impl<'a, 'b, 'gcx, 'tcx> AssociatedTypeNormalizer<'a, 'b, 'gcx, 'tcx> { let value = self.selcx.infcx().resolve_type_vars_if_possible(value); if !value.has_projections() { - value.clone() + value } else { value.fold_with(self) } diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 49f3717935493..2ea16823cc65d 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -1522,6 +1522,33 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { .map(|v| v.get(tcx)) } + /// Determines whether can we safely cache the result + /// of selecting an obligation. This is almost always 'true', + /// except when dealing with certain ParamCandidates. + /// + /// Ordinarily, a ParamCandidate will contain no inference variables, + /// since it was usually produced directly from a DefId. However, + /// certain cases (currently only librustdoc's blanket impl finder), + /// a ParamEnv may be explicitly constructed with inference types. + /// When this is the case, we do *not* want to cache the resulting selection + /// candidate. This is due to the fact that it might not always be possible + /// to equate the obligation's trait ref and the candidate's trait ref, + /// if more constraints end up getting added to an inference variable. + /// + /// Because of this, we always want to re-run the full selection + /// process for our obligation the next time we see it, since + /// we might end up picking a different SelectionCandidate (or none at all) + fn can_cache_candidate(&self, + result: &SelectionResult<'tcx, SelectionCandidate<'tcx>> + ) -> bool { + match result { + Ok(Some(SelectionCandidate::ParamCandidate(trait_ref))) => { + !trait_ref.skip_binder().input_types().any(|t| t.walk().any(|t_| t_.is_ty_infer())) + }, + _ => true + } + } + fn insert_candidate_cache( &mut self, param_env: ty::ParamEnv<'tcx>, @@ -1531,6 +1558,14 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { ) { let tcx = self.tcx(); let trait_ref = cache_fresh_trait_pred.skip_binder().trait_ref; + + if !self.can_cache_candidate(&candidate) { + debug!("insert_candidate_cache(trait_ref={:?}, candidate={:?} -\ + candidate is not cacheable", trait_ref, candidate); + return; + + } + if self.can_use_global_caches(param_env) { if let Err(Overflow) = candidate { // Don't cache overflow globally; we only produce this diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 05d4aeb6ddec4..f40200fff018a 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -190,7 +190,14 @@ fn layout_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty::tls::enter_context(&icx, |_| { let cx = LayoutCx { tcx, param_env }; - cx.layout_raw_uncached(ty) + let layout = cx.layout_raw_uncached(ty); + // Type-level uninhabitedness should always imply ABI uninhabitedness. + if let Ok(layout) = layout { + if ty.conservative_is_uninhabited(tcx) { + assert!(layout.abi.is_uninhabited()); + } + } + layout }) }) } @@ -205,12 +212,11 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { #[derive(Copy, Clone)] pub struct LayoutCx<'tcx, C> { pub tcx: C, - pub param_env: ty::ParamEnv<'tcx> + pub param_env: ty::ParamEnv<'tcx>, } impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { - fn layout_raw_uncached(self, ty: Ty<'tcx>) - -> Result<&'tcx LayoutDetails, LayoutError<'tcx>> { + fn layout_raw_uncached(self, ty: Ty<'tcx>) -> Result<&'tcx LayoutDetails, LayoutError<'tcx>> { let tcx = self.tcx; let param_env = self.param_env; let dl = self.data_layout(); @@ -555,13 +561,19 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { let size = element.size.checked_mul(count, dl) .ok_or(LayoutError::SizeOverflow(ty))?; + let abi = if count != 0 && ty.conservative_is_uninhabited(tcx) { + Abi::Uninhabited + } else { + Abi::Aggregate { sized: true } + }; + tcx.intern_layout(LayoutDetails { variants: Variants::Single { index: 0 }, fields: FieldPlacement::Array { stride: element.size, count }, - abi: Abi::Aggregate { sized: true }, + abi, align: element.align, size }) diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index cd9679c876355..3225037576578 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -967,7 +967,7 @@ impl<'tcx> PolyFnSig<'tcx> { self.map_bound_ref(|fn_sig| fn_sig.inputs_and_output) } pub fn output(&self) -> ty::Binder> { - self.map_bound_ref(|fn_sig| fn_sig.output().clone()) + self.map_bound_ref(|fn_sig| fn_sig.output()) } pub fn variadic(&self) -> bool { self.skip_binder().variadic @@ -1515,6 +1515,51 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { } } + /// Checks whether a type is definitely uninhabited. This is + /// conservative: for some types that are uninhabited we return `false`, + /// but we only return `true` for types that are definitely uninhabited. + /// `ty.conservative_is_uninhabited` implies that any value of type `ty` + /// will be `Abi::Uninhabited`. (Note that uninhabited types may have nonzero + /// size, to account for partial initialisation. See #49298 for details.) + pub fn conservative_is_uninhabited(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> bool { + // FIXME(varkor): we can make this less conversative by substituting concrete + // type arguments. + match self.sty { + ty::Never => true, + ty::Adt(def, _) if def.is_union() => { + // For now, `union`s are never considered uninhabited. + false + } + ty::Adt(def, _) => { + // Any ADT is uninhabited if either: + // (a) It has no variants (i.e. an empty `enum`); + // (b) Each of its variants (a single one in the case of a `struct`) has at least + // one uninhabited field. + def.variants.iter().all(|var| { + var.fields.iter().any(|field| { + tcx.type_of(field.did).conservative_is_uninhabited(tcx) + }) + }) + } + ty::Tuple(tys) => tys.iter().any(|ty| ty.conservative_is_uninhabited(tcx)), + ty::Array(ty, len) => { + match len.val.try_to_scalar() { + // If the array is definitely non-empty, it's uninhabited if + // the type of its elements is uninhabited. + Some(n) if !n.is_null() => ty.conservative_is_uninhabited(tcx), + _ => false + } + } + ty::Ref(..) => { + // References to uninitialised memory is valid for any type, including + // uninhabited types, in unsafe code, so we treat all references as + // inhabited. + false + } + _ => false, + } + } + pub fn is_primitive(&self) -> bool { match self.sty { Bool | Char | Int(_) | Uint(_) | Float(_) => true, diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index d9b64527700fc..1fc9ee07a1ae4 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -377,6 +377,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { // by-move upvars, which is local data for generators Categorization::Upvar(..) => true, + Categorization::ThreadLocal(region) | Categorization::Rvalue(region) => { // Rvalues promoted to 'static are no longer local if let RegionKind::ReStatic = *region { diff --git a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs index ffc4fbfb4c9cb..7bb5f411752fe 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs @@ -177,6 +177,7 @@ fn check_and_get_illegal_move_origin<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, match cmt.cat { Categorization::Deref(_, mc::BorrowedPtr(..)) | Categorization::Deref(_, mc::UnsafePtr(..)) | + Categorization::ThreadLocal(..) | Categorization::StaticItem => { Some(cmt.clone()) } diff --git a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs b/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs index c9dcc0d9fa266..6ef5d65d10dca 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs @@ -70,6 +70,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> { match cmt.cat { Categorization::Rvalue(..) | + Categorization::ThreadLocal(..) | Categorization::Local(..) | // L-Local Categorization::Upvar(..) | Categorization::Deref(_, mc::BorrowedPtr(..)) | // L-Deref-Borrowed @@ -105,6 +106,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> { //! rooting etc, and presuming `cmt` is not mutated. match cmt.cat { + Categorization::ThreadLocal(temp_scope) | Categorization::Rvalue(temp_scope) => { temp_scope } diff --git a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs index b29ab55f9ba78..e1a4473539c8c 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs @@ -145,6 +145,8 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &'a BorrowckCtxt<'a, 'tcx>, match move_from.cat { Categorization::Deref(_, mc::BorrowedPtr(..)) | Categorization::Deref(_, mc::UnsafePtr(..)) | + Categorization::Deref(_, mc::Unique) | + Categorization::ThreadLocal(..) | Categorization::StaticItem => { bccx.cannot_move_out_of( move_from.span, &move_from.descriptive_string(bccx.tcx), Origin::Ast) @@ -166,7 +168,10 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &'a BorrowckCtxt<'a, 'tcx>, } } } - _ => { + + Categorization::Rvalue(..) | + Categorization::Local(..) | + Categorization::Upvar(..) => { span_bug!(move_from.span, "this path should not cause illegal move"); } } diff --git a/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs b/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs index d9784cc2177fd..52c7ebb4beb02 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs @@ -70,6 +70,12 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> { RestrictionResult::Safe } + Categorization::ThreadLocal(..) => { + // Thread-locals are statics that have a scope, with + // no underlying structure to provide restrictions. + RestrictionResult::Safe + } + Categorization::Local(local_id) => { // R-Variable, locally declared let lp = new_lp(LpVar(local_id)); diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index da5c5f47c08ac..8ac46d344d767 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -520,6 +520,7 @@ pub fn opt_loan_path_is_field<'tcx>(cmt: &mc::cmt_<'tcx>) -> (Option { (None, false) } diff --git a/src/librustc_codegen_llvm/back/archive.rs b/src/librustc_codegen_llvm/back/archive.rs index af9efc6d7c417..ce4cb1ea3a042 100644 --- a/src/librustc_codegen_llvm/back/archive.rs +++ b/src/librustc_codegen_llvm/back/archive.rs @@ -52,28 +52,6 @@ enum Addition { }, } -pub fn find_library(name: &str, search_paths: &[PathBuf], sess: &Session) - -> PathBuf { - // On Windows, static libraries sometimes show up as libfoo.a and other - // times show up as foo.lib - let oslibname = format!("{}{}{}", - sess.target.target.options.staticlib_prefix, - name, - sess.target.target.options.staticlib_suffix); - let unixlibname = format!("lib{}.a", name); - - for path in search_paths { - debug!("looking for {} inside {:?}", name, path); - let test = path.join(&oslibname); - if test.exists() { return test } - if oslibname != unixlibname { - let test = path.join(&unixlibname); - if test.exists() { return test } - } - } - sess.fatal(&format!("could not find native static library `{}`, \ - perhaps an -L flag is missing?", name)); -} fn is_relevant_child(c: &Child) -> bool { match c.name() { @@ -128,7 +106,7 @@ impl<'a> ArchiveBuilder<'a> { /// Adds all of the contents of a native library to this archive. This will /// search in the relevant locations for a library named `name`. pub fn add_native_library(&mut self, name: &str) { - let location = find_library(name, &self.config.lib_search_paths, + let location = ::rustc_codegen_utils::find_library(name, &self.config.lib_search_paths, self.config.sess); self.add_archive(&location, |_| false).unwrap_or_else(|e| { self.config.sess.fatal(&format!("failed to add native library {}: {}", diff --git a/src/librustc_codegen_llvm/back/link.rs b/src/librustc_codegen_llvm/back/link.rs index 86c6a5e65b0e9..dd95c3d986299 100644 --- a/src/librustc_codegen_llvm/back/link.rs +++ b/src/librustc_codegen_llvm/back/link.rs @@ -12,8 +12,6 @@ use back::wasm; use cc::windows_registry; use super::archive::{ArchiveBuilder, ArchiveConfig}; use super::bytecode::RLIB_BYTECODE_EXTENSION; -use super::linker::Linker; -use super::command::Command; use super::rpath::RPathConfig; use super::rpath; use metadata::METADATA_FILENAME; @@ -31,6 +29,8 @@ use rustc::hir::def_id::CrateNum; use tempfile::{Builder as TempFileBuilder, TempDir}; use rustc_target::spec::{PanicStrategy, RelroLevel, LinkerFlavor}; use rustc_data_structures::fx::FxHashSet; +use rustc_codegen_utils::linker::Linker; +use rustc_codegen_utils::command::Command; use context::get_reloc_model; use llvm; @@ -701,7 +701,8 @@ fn link_natively(sess: &Session, } { - let mut linker = codegen_results.linker_info.to_linker(cmd, &sess, flavor); + let target_cpu = ::llvm_util::target_cpu(sess); + let mut linker = codegen_results.linker_info.to_linker(cmd, &sess, flavor, target_cpu); link_args(&mut *linker, flavor, sess, crate_type, tmpdir, out_filename, codegen_results); cmd = linker.finalize(); diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs index 61856236a1491..8f940e0d22a83 100644 --- a/src/librustc_codegen_llvm/back/lto.rs +++ b/src/librustc_codegen_llvm/back/lto.rs @@ -9,7 +9,6 @@ // except according to those terms. use back::bytecode::{DecodedBytecode, RLIB_BYTECODE_EXTENSION}; -use back::symbol_export; use back::write::{ModuleConfig, with_llvm_pmb, CodegenContext}; use back::write::{self, DiagnosticHandlers, pre_lto_bitcode_filename}; use errors::{FatalError, Handler}; @@ -24,6 +23,7 @@ use rustc::middle::exported_symbols::SymbolExportLevel; use rustc::session::config::{self, Lto}; use rustc::util::common::time_ext; use rustc_data_structures::fx::FxHashMap; +use rustc_codegen_utils::symbol_export; use time_graph::Timeline; use {ModuleCodegen, ModuleLlvm, ModuleKind}; diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index 81619c219757b..333a778e7765f 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -12,9 +12,6 @@ use attributes; use back::bytecode::{self, RLIB_BYTECODE_EXTENSION}; use back::lto::{self, ModuleBuffer, ThinBuffer, SerializedModule}; use back::link::{self, get_linker, remove}; -use back::command::Command; -use back::linker::LinkerInfo; -use back::symbol_export::ExportedSymbols; use base; use consts; use memmap; @@ -38,6 +35,9 @@ use rustc::util::common::{time_ext, time_depth, set_time_depth, print_time_passe use rustc_fs_util::{path2cstr, link_or_copy}; use rustc_data_structures::small_c_str::SmallCStr; use rustc_data_structures::svh::Svh; +use rustc_codegen_utils::command::Command; +use rustc_codegen_utils::linker::LinkerInfo; +use rustc_codegen_utils::symbol_export::ExportedSymbols; use errors::{self, Handler, Level, DiagnosticBuilder, FatalError, DiagnosticId}; use errors::emitter::{Emitter}; use syntax::attr; diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 169bd9a8466a0..2fe6a0377f81b 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -761,7 +761,7 @@ impl Builder<'a, 'll, 'tcx> { fty, asm, cons, volatile, alignstack, dia); Some(self.call(v, inputs, None)) } else { - // LLVM has detected an issue with our constaints, bail out + // LLVM has detected an issue with our constraints, bail out None } } diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 63a8ab077e5ae..f64cf0c7364dd 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -71,7 +71,6 @@ use back::bytecode::RLIB_BYTECODE_EXTENSION; pub use llvm_util::target_features; use std::any::Any; -use std::path::{PathBuf}; use std::sync::mpsc; use rustc_data_structures::sync::Lrc; @@ -87,20 +86,17 @@ use rustc::util::time_graph; use rustc::util::nodemap::{FxHashSet, FxHashMap}; use rustc::util::profiling::ProfileCategory; use rustc_mir::monomorphize; +use rustc_codegen_utils::{CompiledModule, ModuleKind}; use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc_data_structures::svh::Svh; mod diagnostics; mod back { - pub use rustc_codegen_utils::symbol_names; mod archive; pub mod bytecode; - mod command; - pub mod linker; pub mod link; pub mod lto; - pub mod symbol_export; pub mod write; mod rpath; pub mod wasm; @@ -194,14 +190,14 @@ impl CodegenBackend for LlvmCodegenBackend { } fn provide(&self, providers: &mut ty::query::Providers) { - back::symbol_names::provide(providers); - back::symbol_export::provide(providers); + rustc_codegen_utils::symbol_export::provide(providers); + rustc_codegen_utils::symbol_names::provide(providers); base::provide(providers); attributes::provide(providers); } fn provide_extern(&self, providers: &mut ty::query::Providers) { - back::symbol_export::provide_extern(providers); + rustc_codegen_utils::symbol_export::provide_extern(providers); base::provide_extern(providers); attributes::provide_extern(providers); } @@ -281,13 +277,6 @@ struct CachedModuleCodegen { source: WorkProduct, } -#[derive(Copy, Clone, Debug, PartialEq)] -enum ModuleKind { - Regular, - Metadata, - Allocator, -} - impl ModuleCodegen { fn into_compiled_module(self, emit_obj: bool, @@ -321,15 +310,6 @@ impl ModuleCodegen { } } -#[derive(Debug)] -struct CompiledModule { - name: String, - kind: ModuleKind, - object: Option, - bytecode: Option, - bytecode_compressed: Option, -} - struct ModuleLlvm { llcx: &'static mut llvm::Context, llmod_raw: *const llvm::Module, @@ -377,7 +357,7 @@ struct CodegenResults { crate_hash: Svh, metadata: rustc::middle::cstore::EncodedMetadata, windows_subsystem: Option, - linker_info: back::linker::LinkerInfo, + linker_info: rustc_codegen_utils::linker::LinkerInfo, crate_info: CrateInfo, } diff --git a/src/librustc_codegen_utils/Cargo.toml b/src/librustc_codegen_utils/Cargo.toml index a1f4a323f849e..3a09e8e4b5606 100644 --- a/src/librustc_codegen_utils/Cargo.toml +++ b/src/librustc_codegen_utils/Cargo.toml @@ -13,9 +13,11 @@ test = false flate2 = "1.0" log = "0.4" +serialize = { path = "../libserialize" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } rustc = { path = "../librustc" } +rustc_allocator = { path = "../librustc_allocator" } rustc_target = { path = "../librustc_target" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_mir = { path = "../librustc_mir" } diff --git a/src/librustc_codegen_llvm/back/command.rs b/src/librustc_codegen_utils/command.rs similarity index 100% rename from src/librustc_codegen_llvm/back/command.rs rename to src/librustc_codegen_utils/command.rs diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs index 03b3b20a4e772..89cf19d047216 100644 --- a/src/librustc_codegen_utils/lib.rs +++ b/src/librustc_codegen_utils/lib.rs @@ -30,8 +30,10 @@ extern crate flate2; #[macro_use] extern crate log; +extern crate serialize; #[macro_use] extern crate rustc; +extern crate rustc_allocator; extern crate rustc_target; extern crate rustc_mir; extern crate rustc_incremental; @@ -40,10 +42,16 @@ extern crate syntax_pos; #[macro_use] extern crate rustc_data_structures; extern crate rustc_metadata_utils; +use std::path::PathBuf; + +use rustc::session::Session; use rustc::ty::TyCtxt; +pub mod command; pub mod link; +pub mod linker; pub mod codegen_backend; +pub mod symbol_export; pub mod symbol_names; pub mod symbol_names_test; @@ -61,4 +69,43 @@ pub fn check_for_rustc_errors_attr(tcx: TyCtxt) { } } +#[derive(Copy, Clone, Debug, PartialEq)] +pub enum ModuleKind { + Regular, + Metadata, + Allocator, +} + +#[derive(Debug)] +pub struct CompiledModule { + pub name: String, + pub kind: ModuleKind, + pub object: Option, + pub bytecode: Option, + pub bytecode_compressed: Option, +} + +pub fn find_library(name: &str, search_paths: &[PathBuf], sess: &Session) + -> PathBuf { + // On Windows, static libraries sometimes show up as libfoo.a and other + // times show up as foo.lib + let oslibname = format!("{}{}{}", + sess.target.target.options.staticlib_prefix, + name, + sess.target.target.options.staticlib_suffix); + let unixlibname = format!("lib{}.a", name); + + for path in search_paths { + debug!("looking for {} inside {:?}", name, path); + let test = path.join(&oslibname); + if test.exists() { return test } + if oslibname != unixlibname { + let test = path.join(&unixlibname); + if test.exists() { return test } + } + } + sess.fatal(&format!("could not find native static library `{}`, \ + perhaps an -L flag is missing?", name)); +} + __build_diagnostic_array! { librustc_codegen_utils, DIAGNOSTICS } diff --git a/src/librustc_codegen_llvm/back/linker.rs b/src/librustc_codegen_utils/linker.rs similarity index 98% rename from src/librustc_codegen_llvm/back/linker.rs rename to src/librustc_codegen_utils/linker.rs index e18c8b9dec463..c1f41fd509a14 100644 --- a/src/librustc_codegen_llvm/back/linker.rs +++ b/src/librustc_codegen_utils/linker.rs @@ -15,9 +15,7 @@ use std::io::prelude::*; use std::io::{self, BufWriter}; use std::path::{Path, PathBuf}; -use back::archive; -use back::command::Command; -use back::symbol_export; +use command::Command; use rustc::hir::def_id::{LOCAL_CRATE, CrateNum}; use rustc::middle::dependency_format::Linkage; use rustc::session::Session; @@ -26,7 +24,6 @@ use rustc::session::config::{self, CrateType, OptLevel, DebugInfo, use rustc::ty::TyCtxt; use rustc_target::spec::{LinkerFlavor, LldFlavor}; use serialize::{json, Encoder}; -use llvm_util; /// For all the linkers we support, and information they might /// need out of the shared crate context before we get rid of it. @@ -43,10 +40,13 @@ impl LinkerInfo { } } - pub fn to_linker<'a>(&'a self, - cmd: Command, - sess: &'a Session, - flavor: LinkerFlavor) -> Box { + pub fn to_linker<'a>( + &'a self, + cmd: Command, + sess: &'a Session, + flavor: LinkerFlavor, + target_cpu: &'a str, + ) -> Box { match flavor { LinkerFlavor::Lld(LldFlavor::Link) | LinkerFlavor::Msvc => { @@ -70,6 +70,7 @@ impl LinkerInfo { info: self, hinted_static: false, is_ld: false, + target_cpu, }) as Box } @@ -82,6 +83,7 @@ impl LinkerInfo { info: self, hinted_static: false, is_ld: true, + target_cpu, }) as Box } @@ -144,6 +146,7 @@ pub struct GccLinker<'a> { hinted_static: bool, // Keeps track of the current hinting mode. // Link as ld is_ld: bool, + target_cpu: &'a str, } impl<'a> GccLinker<'a> { @@ -204,7 +207,8 @@ impl<'a> GccLinker<'a> { }; self.linker_arg(&format!("-plugin-opt={}", opt_level)); - self.linker_arg(&format!("-plugin-opt=mcpu={}", llvm_util::target_cpu(self.sess))); + let target_cpu = self.target_cpu; + self.linker_arg(&format!("-plugin-opt=mcpu={}", target_cpu)); match self.sess.lto() { config::Lto::Thin | @@ -263,7 +267,7 @@ impl<'a> Linker for GccLinker<'a> { // -force_load is the macOS equivalent of --whole-archive, but it // involves passing the full path to the library to link. self.linker_arg("-force_load"); - let lib = archive::find_library(lib, search_path, &self.sess); + let lib = ::find_library(lib, search_path, &self.sess); self.linker_arg(&lib); } } @@ -898,7 +902,8 @@ impl<'a> Linker for EmLinker<'a> { fn exported_symbols(tcx: TyCtxt, crate_type: CrateType) -> Vec { let mut symbols = Vec::new(); - let export_threshold = symbol_export::crates_export_threshold(&[crate_type]); + let export_threshold = + ::symbol_export::crates_export_threshold(&[crate_type]); for &(symbol, level) in tcx.exported_symbols(LOCAL_CRATE).iter() { if level.is_below_threshold(export_threshold) { symbols.push(symbol.symbol_name(tcx).to_string()); diff --git a/src/librustc_codegen_llvm/back/symbol_export.rs b/src/librustc_codegen_utils/symbol_export.rs similarity index 99% rename from src/librustc_codegen_llvm/back/symbol_export.rs rename to src/librustc_codegen_utils/symbol_export.rs index 6b1b0b94fd9d7..2d650f7f18d6f 100644 --- a/src/librustc_codegen_llvm/back/symbol_export.rs +++ b/src/librustc_codegen_utils/symbol_export.rs @@ -11,7 +11,7 @@ use rustc_data_structures::sync::Lrc; use std::sync::Arc; -use monomorphize::Instance; +use rustc::ty::Instance; use rustc::hir; use rustc::hir::Node; use rustc::hir::CodegenFnAttrFlags; diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 7988de28b5d7b..e6e1367b592df 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -68,7 +68,7 @@ macro_rules! provide { let $cdata = $tcx.crate_data_as_rc_any($def_id.krate); let $cdata = $cdata.downcast_ref::() - .expect("CrateStore crated ata is not a CrateMetadata"); + .expect("CrateStore created data is not a CrateMetadata"); $compute })* diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 26f977c6b59d1..a855c94707880 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -340,7 +340,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let source_map = self.tcx.sess.source_map(); let all_source_files = source_map.files(); - let (working_dir, working_dir_was_remapped) = self.tcx.sess.working_dir.clone(); + let (working_dir, _cwd_remapped) = self.tcx.sess.working_dir.clone(); let adapted = all_source_files.iter() .filter(|source_file| { @@ -349,32 +349,26 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { !source_file.is_imported() }) .map(|source_file| { - // When exporting SourceFiles, we expand all paths to absolute - // paths because any relative paths are potentially relative to - // a wrong directory. - // However, if a path has been modified via - // `--remap-path-prefix` we assume the user has already set - // things up the way they want and don't touch the path values - // anymore. match source_file.name { + // This path of this SourceFile has been modified by + // path-remapping, so we use it verbatim (and avoid + // cloning the whole map in the process). + _ if source_file.name_was_remapped => source_file.clone(), + + // Otherwise expand all paths to absolute paths because + // any relative paths are potentially relative to a + // wrong directory. FileName::Real(ref name) => { - if source_file.name_was_remapped || - (name.is_relative() && working_dir_was_remapped) { - // This path of this SourceFile has been modified by - // path-remapping, so we use it verbatim (and avoid cloning - // the whole map in the process). - source_file.clone() - } else { - let mut adapted = (**source_file).clone(); - adapted.name = Path::new(&working_dir).join(name).into(); - adapted.name_hash = { - let mut hasher: StableHasher = StableHasher::new(); - adapted.name.hash(&mut hasher); - hasher.finish() - }; - Lrc::new(adapted) - } + let mut adapted = (**source_file).clone(); + adapted.name = Path::new(&working_dir).join(name).into(); + adapted.name_hash = { + let mut hasher: StableHasher = StableHasher::new(); + adapted.name.hash(&mut hasher); + hasher.finish() + }; + Lrc::new(adapted) }, + // expanded code, not from a file _ => source_file.clone(), } diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 6db107344747e..45300699a7708 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -1562,8 +1562,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { } } None => { - // FIXME(canndrew): This is_never should probably be an is_uninhabited - if !sig.output().is_never() { + if !sig.output().conservative_is_uninhabited(self.tcx()) { span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig); } } diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index 4f5ed34a46133..bf0a1e583dff5 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -275,8 +275,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { exit_block.unit() } ExprKind::Call { ty, fun, args, from_hir_call } => { - // FIXME(canndrew): This is_never should probably be an is_uninhabited - let diverges = expr.ty.is_never(); let intrinsic = match ty.sty { ty::FnDef(def_id, _) => { let f = ty.fn_sig(this.hir.tcx()); @@ -332,7 +330,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { func: fun, args, cleanup: Some(cleanup), - destination: if diverges { + destination: if expr.ty.conservative_is_uninhabited(this.hir.tcx()) { None } else { Some((destination.clone(), success)) diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index bc917140bbd67..9702e94a9e0f0 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -129,7 +129,7 @@ pub fn op_to_const<'tcx>( assert!(alloc.bytes.len() as u64 - ptr.offset.bytes() >= op.layout.size.bytes()); let mut alloc = alloc.clone(); alloc.align = align; - // FIXME shouldnt it be the case that `mark_static_initialized` has already + // FIXME shouldn't it be the case that `mark_static_initialized` has already // interned this? I thought that is the entire point of that `FinishStatic` stuff? let alloc = ecx.tcx.intern_const_alloc(alloc); ConstValue::ByRef(ptr.alloc_id, alloc, ptr.offset) diff --git a/src/librustc_mir/diagnostics.rs b/src/librustc_mir/diagnostics.rs index bb3e4a8d8813f..56a9daf84f768 100644 --- a/src/librustc_mir/diagnostics.rs +++ b/src/librustc_mir/diagnostics.rs @@ -2279,7 +2279,7 @@ fn demo<'a>(s: &'a mut S<'a>) -> &'a mut String { let p = &mut *(*s).data; p } Note that this approach needs a reference to S with lifetime `'a`. Nothing shorter than `'a` will suffice: a shorter lifetime would imply -that after `demo` finishes excuting, something else (such as the +that after `demo` finishes executing, something else (such as the destructor!) could access `s.data` after the end of that shorter lifetime, which would again violate the `&mut`-borrow's exclusive access. diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index 04a297d0a8317..77483ad184ba6 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -1048,7 +1048,7 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, if let Some(constructors) = pat_constructors(cx, v[0], pcx) { debug!("is_useful - expanding constructors: {:#?}", constructors); split_grouped_constructors(cx.tcx, constructors, matrix, pcx.ty).into_iter().map(|c| - is_useful_specialized(cx, matrix, v, c.clone(), pcx.ty, witness) + is_useful_specialized(cx, matrix, v, c, pcx.ty, witness) ).find(|result| result.is_useful()).unwrap_or(NotUseful) } else { debug!("is_useful - expanding wildcard"); @@ -1096,7 +1096,7 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, if missing_ctors.is_empty() && !is_non_exhaustive { split_grouped_constructors(cx.tcx, all_ctors, matrix, pcx.ty).into_iter().map(|c| { - is_useful_specialized(cx, matrix, v, c.clone(), pcx.ty, witness) + is_useful_specialized(cx, matrix, v, c, pcx.ty, witness) }).find(|result| result.is_useful()).unwrap_or(NotUseful) } else { let matrix = rows.iter().filter_map(|r| { diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index f2ae5774da875..0335947a868b2 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -229,7 +229,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { let scrutinee_is_uninhabited = if self.tcx.features().exhaustive_patterns { self.tcx.is_ty_uninhabited_from(module, pat_ty) } else { - self.conservative_is_uninhabited(pat_ty) + pat_ty.conservative_is_uninhabited(self.tcx) }; if !scrutinee_is_uninhabited { // We know the type is inhabited, so this must be wrong @@ -257,15 +257,6 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { }) } - fn conservative_is_uninhabited(&self, scrutinee_ty: Ty<'tcx>) -> bool { - // "rustc-1.0-style" uncontentious uninhabitableness check - match scrutinee_ty.sty { - ty::Never => true, - ty::Adt(def, _) => def.variants.is_empty(), - _ => false - } - } - fn check_irrefutable(&self, pat: &'tcx Pat, origin: &str) { let module = self.tcx.hir.get_module_parent(pat.id); MatchCheckCtxt::create_and_enter(self.tcx, module, |ref mut cx| { diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 189388921650c..64ad4c2eec1e1 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -556,7 +556,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc )?; } } else { - // Uh, that shouln't happen... the function did not intend to return + // Uh, that shouldn't happen... the function did not intend to return return err!(Unreachable); } diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 9adca6c429798..68d3ba9b876ca 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -94,7 +94,7 @@ impl<'a, 'b, 'c, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> HasDataLayout } } -// FIXME: Really we shouldnt clone memory, ever. Snapshot machinery should instad +// FIXME: Really we shouldn't clone memory, ever. Snapshot machinery should instead // carefully copy only the reachable parts. impl<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'a, 'mir, 'tcx>> Clone for Memory<'a, 'mir, 'tcx, M> @@ -658,7 +658,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { } /// It is the caller's responsibility to handle undefined and pointer bytes. - /// However, this still checks that there are no relocations on the *egdes*. + /// However, this still checks that there are no relocations on the *edges*. #[inline] fn get_bytes_with_undef_and_ptr( &self, @@ -732,6 +732,11 @@ where if self.alloc_map.contains_key(&alloc) { // Not yet interned, so proceed recursively self.intern_static(alloc, mutability)?; + } else if self.dead_alloc_map.contains_key(&alloc) { + // danging pointer + return err!(ValidationFailure( + "encountered dangling pointer in final constant".into(), + )) } } Ok(()) @@ -1098,7 +1103,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { Ok(()) } - /// Error if there are relocations overlapping with the egdes of the + /// Error if there are relocations overlapping with the edges of the /// given memory range. #[inline] fn check_relocation_edges(&self, ptr: Pointer, size: Size) -> EvalResult<'tcx> { diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 71b2f4b53a60c..021e2d58f84b1 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -357,14 +357,14 @@ fn from_known_layout<'tcx>( } impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { - /// Try reading a value in memory; this is interesting particularily for ScalarPair. + /// Try reading a value in memory; this is interesting particularly for ScalarPair. /// Return None if the layout does not permit loading this as a value. pub(super) fn try_read_value_from_mplace( &self, mplace: MPlaceTy<'tcx, M::PointerTag>, ) -> EvalResult<'tcx, Option>> { if mplace.layout.is_unsized() { - // Dont touch unsized + // Don't touch unsized return Ok(None); } let (ptr, ptr_align) = mplace.to_scalar_ptr_align(); diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index 38cf79d8fa0b9..ac1ba0edc3b3b 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -230,7 +230,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> ), } } - // non-ZST also have to be dereferencable + // non-ZST also have to be dereferenceable if size != Size::ZERO { let ptr = try_validation!(place.ptr.to_ptr(), "integer pointer in non-ZST reference", path); @@ -272,7 +272,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> // FIXME: Check if the signature matches } // This should be all the primitive types - ty::Never => bug!("Uninhabited type should have been catched earlier"), + ty::Never => bug!("Uninhabited type should have been caught earlier"), _ => bug!("Unexpected primitive type {}", value.layout.ty) } Ok(()) diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index f6ace57f5e0fb..0e9596244cd58 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -166,12 +166,12 @@ impl<'a> AstValidator<'a> { } } - /// With eRFC 2497, we need to check whether an expression is ambigious and warn or error + /// With eRFC 2497, we need to check whether an expression is ambiguous and warn or error /// depending on the edition, this function handles that. fn while_if_let_ambiguity(&self, expr: &P) { if let Some((span, op_kind)) = self.while_if_let_expr_ambiguity(&expr) { let mut err = self.err_handler().struct_span_err( - span, &format!("ambigious use of `{}`", op_kind.to_string()) + span, &format!("ambiguous use of `{}`", op_kind.to_string()) ); err.note( @@ -193,9 +193,9 @@ impl<'a> AstValidator<'a> { } /// With eRFC 2497 adding if-let chains, there is a requirement that the parsing of - /// `&&` and `||` in a if-let statement be unambigious. This function returns a span and - /// a `BinOpKind` (either `&&` or `||` depending on what was ambigious) if it is determined - /// that the current expression parsed is ambigious and will break in future. + /// `&&` and `||` in a if-let statement be unambiguous. This function returns a span and + /// a `BinOpKind` (either `&&` or `||` depending on what was ambiguous) if it is determined + /// that the current expression parsed is ambiguous and will break in future. fn while_if_let_expr_ambiguity(&self, expr: &P) -> Option<(Span, BinOpKind)> { debug!("while_if_let_expr_ambiguity: expr.node: {:?}", expr.node); match &expr.node { @@ -203,12 +203,12 @@ impl<'a> AstValidator<'a> { Some((expr.span, op.node)) }, ExprKind::Range(ref lhs, ref rhs, _) => { - let lhs_ambigious = lhs.as_ref() + let lhs_ambiguous = lhs.as_ref() .and_then(|lhs| self.while_if_let_expr_ambiguity(lhs)); - let rhs_ambigious = rhs.as_ref() + let rhs_ambiguous = rhs.as_ref() .and_then(|rhs| self.while_if_let_expr_ambiguity(rhs)); - lhs_ambigious.or(rhs_ambigious) + lhs_ambiguous.or(rhs_ambiguous) } _ => None, } diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index 5e9169e86a98d..ca58239df8eac 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -663,6 +663,7 @@ impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for CheckCrateVisitor<'a, 'gcx> { let mut cur = cmt; loop { match cur.cat { + Categorization::ThreadLocal(..) | Categorization::Rvalue(..) => { if loan_cause == euv::MatchDiscriminant { // Ignore the dummy immutable borrow created by EUV. diff --git a/src/librustc_resolve/error_reporting.rs b/src/librustc_resolve/error_reporting.rs index 74d1ae96e794f..4ee50bfca7897 100644 --- a/src/librustc_resolve/error_reporting.rs +++ b/src/librustc_resolve/error_reporting.rs @@ -24,7 +24,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { &mut self, span: Span, path: Vec - ) -> Option> { + ) -> Option<(Vec, Option)> { debug!("make_path_suggestion: span={:?} path={:?}", span, path); // If we don't have a path to suggest changes to, then return. if path.is_empty() { @@ -60,13 +60,13 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { &mut self, span: Span, mut path: Vec - ) -> Option> { + ) -> Option<(Vec, Option)> { // Replace first ident with `self` and check if that is valid. path[0].name = keywords::SelfValue.name(); let result = self.resolve_path(None, &path, None, false, span, CrateLint::No); debug!("make_missing_self_suggestion: path={:?} result={:?}", path, result); if let PathResult::Module(..) = result { - Some(path) + Some((path, None)) } else { None } @@ -83,13 +83,20 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { &mut self, span: Span, mut path: Vec - ) -> Option> { + ) -> Option<(Vec, Option)> { // Replace first ident with `crate` and check if that is valid. path[0].name = keywords::Crate.name(); let result = self.resolve_path(None, &path, None, false, span, CrateLint::No); debug!("make_missing_crate_suggestion: path={:?} result={:?}", path, result); if let PathResult::Module(..) = result { - Some(path) + Some(( + path, + Some( + "`use` statements changed in Rust 2018; read more at \ + ".to_string() + ), + )) } else { None } @@ -106,13 +113,13 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { &mut self, span: Span, mut path: Vec - ) -> Option> { + ) -> Option<(Vec, Option)> { // Replace first ident with `crate` and check if that is valid. path[0].name = keywords::Super.name(); let result = self.resolve_path(None, &path, None, false, span, CrateLint::No); debug!("make_missing_super_suggestion: path={:?} result={:?}", path, result); if let PathResult::Module(..) = result { - Some(path) + Some((path, None)) } else { None } @@ -132,7 +139,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { &mut self, span: Span, mut path: Vec - ) -> Option> { + ) -> Option<(Vec, Option)> { // Need to clone else we can't call `resolve_path` without a borrow error. We also store // into a `BTreeMap` so we can get consistent ordering (and therefore the same diagnostic) // each time. @@ -157,7 +164,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { debug!("make_external_crate_suggestion: name={:?} path={:?} result={:?}", name, path, result); if let PathResult::Module(..) = result { - return Some(path) + return Some((path, None)) } } } diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 27ba1ced74985..8b93596e866e7 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -700,7 +700,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { } } }); - } else if let Some((span, err)) = error { + } else if let Some((span, err, note)) = error { errors = true; if let SingleImport { source, ref result, .. } = import.subclass { @@ -728,7 +728,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { let path = import_path_to_string(&import.module_path[..], &import.subclass, span); - error_vec.push((span, path, err)); + error_vec.push((span, path, err, note)); seen_spans.insert(span); prev_root_id = import.root_id; } @@ -821,27 +821,45 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { } } - fn throw_unresolved_import_error(&self, error_vec: Vec<(Span, String, String)>, - span: Option) { + fn throw_unresolved_import_error( + &self, + error_vec: Vec<(Span, String, String, Option)>, + span: Option, + ) { let max_span_label_msg_count = 10; // upper limit on number of span_label message. - let (span, msg) = if error_vec.is_empty() { - (span.unwrap(), "unresolved import".to_string()) + let (span, msg, note) = if error_vec.is_empty() { + (span.unwrap(), "unresolved import".to_string(), None) } else { - let span = MultiSpan::from_spans(error_vec.clone().into_iter() - .map(|elem: (Span, String, String)| { elem.0 }) - .collect()); + let span = MultiSpan::from_spans( + error_vec.clone().into_iter() + .map(|elem: (Span, String, String, Option)| elem.0) + .collect() + ); + + let note: Option = error_vec.clone().into_iter() + .filter_map(|elem: (Span, String, String, Option)| elem.3) + .last(); + let path_vec: Vec = error_vec.clone().into_iter() - .map(|elem: (Span, String, String)| { format!("`{}`", elem.1) }) + .map(|elem: (Span, String, String, Option)| format!("`{}`", elem.1)) .collect(); let path = path_vec.join(", "); - let msg = format!("unresolved import{} {}", - if path_vec.len() > 1 { "s" } else { "" }, path); - (span, msg) + let msg = format!( + "unresolved import{} {}", + if path_vec.len() > 1 { "s" } else { "" }, + path + ); + + (span, msg, note) }; + let mut err = struct_span_err!(self.resolver.session, span, E0432, "{}", &msg); for span_error in error_vec.into_iter().take(max_span_label_msg_count) { err.span_label(span_error.0, span_error.2); } + if let Some(note) = note { + err.note(¬e); + } err.emit(); } @@ -936,7 +954,10 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { } // If appropriate, returns an error to report. - fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<(Span, String)> { + fn finalize_import( + &mut self, + directive: &'b ImportDirective<'b> + ) -> Option<(Span, String, Option)> { self.current_module = directive.parent; let ImportDirective { ref module_path, span, .. } = *directive; @@ -959,15 +980,16 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { return None; } PathResult::Failed(span, msg, true) => { - return if let Some(suggested_path) = self.make_path_suggestion( + return if let Some((suggested_path, note)) = self.make_path_suggestion( span, module_path.clone() ) { Some(( span, - format!("Did you mean `{}`?", names_to_string(&suggested_path[..])) + format!("Did you mean `{}`?", names_to_string(&suggested_path[..])), + note, )) } else { - Some((span, msg)) + Some((span, msg, None)) }; }, _ => return None, @@ -992,8 +1014,11 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { if let ModuleOrUniformRoot::Module(module) = module { if module.def_id() == directive.parent.def_id() { // Importing a module into itself is not allowed. - return Some((directive.span, - "Cannot glob-import a module into itself.".to_string())); + return Some(( + directive.span, + "Cannot glob-import a module into itself.".to_string(), + None, + )); } } if !is_prelude && @@ -1084,7 +1109,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { } } }; - Some((span, msg)) + Some((span, msg, None)) } else { // `resolve_ident_in_module` reported a privacy error. self.import_dummy_binding(directive); diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs index 6b28fd091748f..1a5d2801af0c5 100644 --- a/src/librustc_target/abi/mod.rs +++ b/src/librustc_target/abi/mod.rs @@ -430,7 +430,7 @@ impl Align { } /// Lower the alignment, if necessary, such that the given offset - /// is aligned to it (the offset is a multiple of the aligment). + /// is aligned to it (the offset is a multiple of the alignment). pub fn restrict_for_offset(self, offset: Size) -> Align { self.min(Align::max_for_offset(offset)) } diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index d82d36a1937bf..7773e2d570844 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -111,34 +111,35 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let expr_ty = self.resolve_type_vars_with_obligations(checked_ty); let mut err = self.report_mismatched_types(&cause, expected, expr_ty, e); - // If the expected type is an enum with any variants whose sole - // field is of the found type, suggest such variants. See Issue - // #42764. + // If the expected type is an enum (Issue #55250) with any variants whose + // sole field is of the found type, suggest such variants. (Issue #42764) if let ty::Adt(expected_adt, substs) = expected.sty { - let mut compatible_variants = expected_adt.variants - .iter() - .filter(|variant| variant.fields.len() == 1) - .filter_map(|variant| { - let sole_field = &variant.fields[0]; - let sole_field_ty = sole_field.ty(self.tcx, substs); - if self.can_coerce(expr_ty, sole_field_ty) { - let variant_path = self.tcx.item_path_str(variant.did); - Some(variant_path.trim_left_matches("std::prelude::v1::").to_string()) - } else { - None + if expected_adt.is_enum() { + let mut compatible_variants = expected_adt.variants + .iter() + .filter(|variant| variant.fields.len() == 1) + .filter_map(|variant| { + let sole_field = &variant.fields[0]; + let sole_field_ty = sole_field.ty(self.tcx, substs); + if self.can_coerce(expr_ty, sole_field_ty) { + let variant_path = self.tcx.item_path_str(variant.did); + Some(variant_path.trim_left_matches("std::prelude::v1::").to_string()) + } else { + None + } + }).peekable(); + + if compatible_variants.peek().is_some() { + let expr_text = print::to_string(print::NO_ANN, |s| s.print_expr(expr)); + let suggestions = compatible_variants + .map(|v| format!("{}({})", v, expr_text)).collect::>(); + err.span_suggestions_with_applicability( + expr.span, + "try using a variant of the expected type", + suggestions, + Applicability::MaybeIncorrect, + ); } - }).peekable(); - - if compatible_variants.peek().is_some() { - let expr_text = print::to_string(print::NO_ANN, |s| s.print_expr(expr)); - let suggestions = compatible_variants.map(|v| - format!("{}({})", v, expr_text)).collect::>(); - err.span_suggestions_with_applicability( - expr.span, - "try using a variant of the expected type", - suggestions, - Applicability::MaybeIncorrect, - ); } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 1c562859bb48d..77151351d08a1 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5198,7 +5198,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } else { // If no type arguments were provided, we have to infer them. // This case also occurs as a result of some malformed input, e.g. - // a lifetime argument being given instead of a type paramter. + // a lifetime argument being given instead of a type parameter. // Using inference instead of `Error` gives better error messages. self.var_for_def(span, param) } diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 80b4ba6240d33..212ee2698e012 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -1243,6 +1243,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { | Categorization::StaticItem | Categorization::Upvar(..) | Categorization::Local(..) + | Categorization::ThreadLocal(..) | Categorization::Rvalue(..) => { // These are all "base cases" with independent lifetimes // that are not subject to inference diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index 99effce4ee08d..df994ad9e55c4 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -401,6 +401,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { Categorization::Deref(_, mc::UnsafePtr(..)) | Categorization::StaticItem | + Categorization::ThreadLocal(..) | Categorization::Rvalue(..) | Categorization::Local(_) | Categorization::Upvar(..) => { @@ -431,6 +432,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { Categorization::Deref(_, mc::UnsafePtr(..)) | Categorization::StaticItem | + Categorization::ThreadLocal(..) | Categorization::Rvalue(..) | Categorization::Local(_) | Categorization::Upvar(..) => {} diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index ec773e384af38..9990d2ee2b676 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -674,7 +674,7 @@ fn check_existential_types<'a, 'fcx, 'gcx, 'tcx>( } // if may_define_existential_type // now register the bounds on the parameters of the existential type - // so the parameters given by the function need to fulfil them + // so the parameters given by the function need to fulfill them // ```rust // existential type Foo: 'static; // fn foo() -> Foo { .. *} diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index c54d9e4b47578..05a83dd307c38 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -269,7 +269,7 @@ pub fn coerce_unsized_info<'a, 'gcx>(gcx: TyCtxt<'a, 'gcx, 'gcx>, // exactly one (non-phantom) field has changed its // type, which we will expect to be the pointer that // is becoming fat (we could probably generalize this - // to mutiple thin pointers of the same type becoming + // to multiple thin pointers of the same type becoming // fat, but we don't). In this case: // // - `extra` has type `T` before and type `T` after diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index b6bc8d603d5ac..57c7e2afd625e 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -50,6 +50,7 @@ impl<'a, 'tcx, 'rcx, 'cstore> BlanketImplFinder <'a, 'tcx, 'rcx, 'cstore> { name: Option, ) -> Vec where F: Fn(DefId) -> Def { + debug!("get_blanket_impls(def_id={:?}, ...)", def_id); let mut impls = Vec::new(); if self.cx .tcx @@ -78,6 +79,8 @@ impl<'a, 'tcx, 'rcx, 'cstore> BlanketImplFinder <'a, 'tcx, 'rcx, 'cstore> { } self.cx.tcx.for_each_relevant_impl(trait_def_id, ty, |impl_def_id| { self.cx.tcx.infer_ctxt().enter(|infcx| { + debug!("get_blanet_impls: Considering impl for trait '{:?}' {:?}", + trait_def_id, impl_def_id); let t_generics = infcx.tcx.generics_of(impl_def_id); let trait_ref = infcx.tcx.impl_trait_ref(impl_def_id) .expect("Cannot get impl trait"); @@ -104,8 +107,8 @@ impl<'a, 'tcx, 'rcx, 'cstore> BlanketImplFinder <'a, 'tcx, 'rcx, 'cstore> { drop(obligations); debug!( - "invoking predicate_may_hold: {:?}", - trait_ref, + "invoking predicate_may_hold: param_env={:?}, trait_ref={:?}, ty={:?}", + param_env, trait_ref, ty ); let may_apply = match infcx.evaluate_obligation( &traits::Obligation::new( @@ -117,6 +120,10 @@ impl<'a, 'tcx, 'rcx, 'cstore> BlanketImplFinder <'a, 'tcx, 'rcx, 'cstore> { Ok(eval_result) => eval_result.may_apply(), Err(traits::OverflowError) => true, // overflow doesn't mean yes *or* no }; + debug!("get_blanket_impls: found applicable impl: {}\ + for trait_ref={:?}, ty={:?}", + may_apply, trait_ref, ty); + if !may_apply { return } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index db605e57735aa..2e6cc4bd54c61 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -3632,7 +3632,7 @@ fn name_from_pat(p: &hir::Pat) -> String { fields.iter().map(|&Spanned { node: ref fp, .. }| format!("{}: {}", fp.ident, name_from_pat(&*fp.pat))) .collect::>().join(", "), - if etc { ", ..." } else { "" } + if etc { ", .." } else { "" } ) } PatKind::Tuple(ref elts, _) => format!("({})", elts.iter().map(|p| name_from_pat(&**p)) diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index 75c7a3d928094..ad212a547579b 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -43,12 +43,12 @@ use time::Duration; /// use std::io::prelude::*; /// use std::net::TcpStream; /// -/// { -/// let mut stream = TcpStream::connect("127.0.0.1:34254").unwrap(); +/// fn main() -> std::io::Result<()> { +/// let mut stream = TcpStream::connect("127.0.0.1:34254")?; /// -/// // ignore the Result -/// let _ = stream.write(&[1]); -/// let _ = stream.read(&mut [0; 128]); // ignore here too +/// stream.write(&[1])?; +/// stream.read(&mut [0; 128])?; +/// Ok(()) /// } // the stream is closed here /// ``` #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index 3b432d0513209..c2a16122a0dd1 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -323,8 +323,8 @@ mod prim_never { } /// let s = String::from("love: ❤️"); /// let v: Vec = s.chars().collect(); /// -/// assert_eq!(12, s.len() * std::mem::size_of::()); -/// assert_eq!(32, v.len() * std::mem::size_of::()); +/// assert_eq!(12, std::mem::size_of_val(&s[..])); +/// assert_eq!(32, std::mem::size_of_val(&v[..])); /// ``` #[stable(feature = "rust1", since = "1.0.0")] mod prim_char { } diff --git a/src/libstd/sync/mod.rs b/src/libstd/sync/mod.rs index d69ebc1762272..a7db372a0e20a 100644 --- a/src/libstd/sync/mod.rs +++ b/src/libstd/sync/mod.rs @@ -97,7 +97,7 @@ //! - A **multiprocessor** system executing multiple hardware threads //! at the same time: In multi-threaded scenarios, you can use two //! kinds of primitives to deal with synchronization: -//! - [memory fences] to ensure memory accesses are made visibile to +//! - [memory fences] to ensure memory accesses are made visible to //! other CPUs in the right order. //! - [atomic operations] to ensure simultaneous access to the same //! memory location doesn't lead to undefined behavior. diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs index 98845e457b25c..cf9698cb2a971 100644 --- a/src/libstd/sync/once.rs +++ b/src/libstd/sync/once.rs @@ -290,8 +290,8 @@ impl Once { } /// Returns true if some `call_once` call has completed - /// successfuly. Specifically, `is_completed` will return false in - /// the following situtations: + /// successfully. Specifically, `is_completed` will return false in + /// the following situations: /// * `call_once` was not called at all, /// * `call_once` was called, but has not yet completed, /// * the `Once` instance is poisoned diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index e611eb86dc1b3..d8fb20d425008 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -96,7 +96,7 @@ impl<'a> StripUnconfigured<'a> { /// when the configuration predicate is true, or otherwise expand into an /// empty list of attributes. /// - /// Gives a compiler warning when the `cfg_attr` contains no attribtes and + /// Gives a compiler warning when the `cfg_attr` contains no attributes and /// is in the original source file. Gives a compiler error if the syntax of /// the attribute is incorrect fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Vec { @@ -138,7 +138,7 @@ impl<'a> StripUnconfigured<'a> { }; // Check feature gate and lint on zero attributes in source. Even if the feature is gated, - // we still compute as if it wasn't, since the emitted error will stop compilation futher + // we still compute as if it wasn't, since the emitted error will stop compilation further // along the compilation. match (expanded_attrs.len(), gate_cfg_attr_multi) { (0, false) => { diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 95a2298ca757d..18d5970462f63 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -965,7 +965,7 @@ pub fn noop_fold_item_kind(i: ItemKind, folder: &mut T) -> ItemKind { polarity, defaultness, folder.fold_generics(generics), - ifce.map(|trait_ref| folder.fold_trait_ref(trait_ref.clone())), + ifce.map(|trait_ref| folder.fold_trait_ref(trait_ref)), folder.fold_ty(ty), impl_items.move_flat_map(|item| folder.fold_impl_item(item)), ), diff --git a/src/stdsimd b/src/stdsimd index 307650500de5b..431766a3fbcfb 160000 --- a/src/stdsimd +++ b/src/stdsimd @@ -1 +1 @@ -Subproject commit 307650500de5b44dc1047dc9d15e449e09d92b57 +Subproject commit 431766a3fbcfb6dafb2d5a3866c1609bf44ee554 diff --git a/src/test/codegen/remap_path_prefix/auxiliary/xcrate-generic.rs b/src/test/codegen/remap_path_prefix/auxiliary/xcrate-generic.rs new file mode 100644 index 0000000000000..6c477a407812a --- /dev/null +++ b/src/test/codegen/remap_path_prefix/auxiliary/xcrate-generic.rs @@ -0,0 +1,16 @@ +// Copyright 2017 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. + +// ignore-tidy-linelength +// compile-flags: -g --remap-path-prefix={{cwd}}=/the/aux-cwd --remap-path-prefix={{src-base}}/remap_path_prefix/auxiliary=/the/aux-src + +#![crate_type = "lib"] + +pub fn foo() {} diff --git a/src/test/codegen/remap_path_prefix/xcrate-generic.rs b/src/test/codegen/remap_path_prefix/xcrate-generic.rs new file mode 100644 index 0000000000000..f206df9813165 --- /dev/null +++ b/src/test/codegen/remap_path_prefix/xcrate-generic.rs @@ -0,0 +1,25 @@ +// Copyright 2017 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. + +// ignore-windows +// ignore-tidy-linelength +// compile-flags: -g -C metadata=foo -C no-prepopulate-passes +// aux-build:xcrate-generic.rs + +#![crate_type = "lib"] + +extern crate xcrate_generic; + +pub fn foo() { + xcrate_generic::foo::(); +} + +// Here we check that local debuginfo is mapped correctly. +// CHECK: !DIFile(filename: "/the/aux-src/xcrate-generic.rs", directory: "") diff --git a/src/test/debuginfo/nil-enum.rs b/src/test/debuginfo/nil-enum.rs index ab9c7e2dd2758..27e8e9d17e82c 100644 --- a/src/test/debuginfo/nil-enum.rs +++ b/src/test/debuginfo/nil-enum.rs @@ -1,50 +1,24 @@ -// Copyright 2013-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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// NOTE Instantiating an empty enum is UB. This test may break in the future. - -// LLDB can't handle zero-sized values +// LLDB can't handle zero-sized values. // ignore-lldb - // compile-flags:-g // gdb-command:run -// gdb-command:print first +// gdb-command:print *first // gdbg-check:$1 = {} // gdbr-check:$1 = -// gdb-command:print second -// gdbg-check:$2 = {} -// gdbr-check:$2 = - #![allow(unused_variables)] #![feature(omit_gdb_pretty_printer_section)] #![feature(maybe_uninit)] #![omit_gdb_pretty_printer_section] -use std::mem::MaybeUninit; - -enum ANilEnum {} -enum AnotherNilEnum {} +enum Void {} -// This test relies on gdbg printing the string "{}" for empty -// structs (which may change some time) -// The error from gdbr is expected since nil enums are not supposed to exist. fn main() { - unsafe { - let first: ANilEnum = MaybeUninit::uninitialized().into_inner(); - let second: AnotherNilEnum = MaybeUninit::uninitialized().into_inner(); + let first: *const Void = 1 as *const _; - zzz(); // #break - } + zzz(); // #break } -fn zzz() {()} +fn zzz() {} diff --git a/src/test/run-pass/issues/issue-18804/main.rs b/src/test/run-pass/issues/issue-18804/main.rs index a3a5337077cc6..2abcd4b7ba99c 100644 --- a/src/test/run-pass/issues/issue-18804/main.rs +++ b/src/test/run-pass/issues/issue-18804/main.rs @@ -9,7 +9,7 @@ // except according to those terms. // run-pass -// Test for issue #18804, #[linkage] does not propagate thorugh generic +// Test for issue #18804, #[linkage] does not propagate through generic // functions. Failure results in a linker error. // ignore-asmjs no weak symbol support diff --git a/src/test/rustdoc/issue-55001.rs b/src/test/rustdoc/issue-55001.rs new file mode 100644 index 0000000000000..f6c7f9a3d082c --- /dev/null +++ b/src/test/rustdoc/issue-55001.rs @@ -0,0 +1,31 @@ +// Regression test for issue #55001. Previously, we would incorrectly +// cache certain trait selection results when checking for blanket impls, +// resulting in an ICE when we tried to confirm the cached ParamCandidate +// against an obligation. + +pub struct DefaultAllocator; +pub struct Standard; +pub struct Inner; + +pub trait Rand {} + +pub trait Distribution {} +pub trait Allocator {} + +impl Rand for T where Standard: Distribution {} + +impl Distribution> for Standard +where +DefaultAllocator: Allocator, +Standard: Distribution {} + +impl Distribution for Standard {} + + +pub struct Point +where DefaultAllocator: Allocator +{ + field: N +} + +fn main() {} diff --git a/src/test/ui/associated-types/bound-lifetime-in-binding-only.elision.stderr b/src/test/ui/associated-types/bound-lifetime-in-binding-only.elision.stderr index 0a12aa76a785b..6b9d4ebb2987d 100644 --- a/src/test/ui/associated-types/bound-lifetime-in-binding-only.elision.stderr +++ b/src/test/ui/associated-types/bound-lifetime-in-binding-only.elision.stderr @@ -2,10 +2,9 @@ error[E0106]: missing lifetime specifier --> $DIR/bound-lifetime-in-binding-only.rs:62:23 | LL | fn elision &i32>() { - | ^ expected lifetime parameter + | ^ help: consider giving it a 'static lifetime: `&'static` | = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from - = help: consider giving it a 'static lifetime error: aborting due to previous error diff --git a/src/test/ui/associated-types/bound-lifetime-in-return-only.elision.stderr b/src/test/ui/associated-types/bound-lifetime-in-return-only.elision.stderr index 8fefdfd4d19ef..7906f0a30e4eb 100644 --- a/src/test/ui/associated-types/bound-lifetime-in-return-only.elision.stderr +++ b/src/test/ui/associated-types/bound-lifetime-in-return-only.elision.stderr @@ -2,10 +2,9 @@ error[E0106]: missing lifetime specifier --> $DIR/bound-lifetime-in-return-only.rs:44:23 | LL | fn elision(_: fn() -> &i32) { - | ^ expected lifetime parameter + | ^ help: consider giving it a 'static lifetime: `&'static` | = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from - = help: consider giving it a 'static lifetime error: aborting due to previous error diff --git a/src/test/ui/block-result/unexpected-return-on-unit.rs b/src/test/ui/block-result/unexpected-return-on-unit.rs index 3cf76365c77b1..b116888d63c10 100644 --- a/src/test/ui/block-result/unexpected-return-on-unit.rs +++ b/src/test/ui/block-result/unexpected-return-on-unit.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Test that we do some basic error correcton in the tokeniser (and don't spew +// Test that we do some basic error correction in the tokeniser (and don't spew // too many bogus errors). fn foo() -> usize { diff --git a/src/test/ui/borrowck/borrowck-thread-local-static-borrow-outlives-fn.ast.stderr b/src/test/ui/borrowck/borrowck-thread-local-static-borrow-outlives-fn.ast.stderr index 27e0dba5095b2..505bcfb1e6e14 100644 --- a/src/test/ui/borrowck/borrowck-thread-local-static-borrow-outlives-fn.ast.stderr +++ b/src/test/ui/borrowck/borrowck-thread-local-static-borrow-outlives-fn.ast.stderr @@ -2,9 +2,9 @@ error[E0597]: borrowed value does not live long enough --> $DIR/borrowck-thread-local-static-borrow-outlives-fn.rs:21:21 | LL | assert_static(&FOO); //[ast]~ ERROR [E0597] - | ^^^ - temporary value only lives until here + | ^^^ - borrowed value only lives until here | | - | temporary value does not live long enough + | borrowed value does not live long enough | = note: borrowed value must be valid for the static lifetime... diff --git a/src/test/ui/borrowck/issue-47215-ice-from-drop-elab.nll.stderr b/src/test/ui/borrowck/issue-47215-ice-from-drop-elab.nll.stderr new file mode 100644 index 0000000000000..255eb757a4989 --- /dev/null +++ b/src/test/ui/borrowck/issue-47215-ice-from-drop-elab.nll.stderr @@ -0,0 +1,12 @@ +error[E0507]: cannot move out of static item + --> $DIR/issue-47215-ice-from-drop-elab.rs:17:21 + | +LL | let mut x = X; //~ ERROR cannot move out of thread-local static item [E0507] + | ^ + | | + | cannot move out of static item + | help: consider borrowing here: `&X` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0507`. diff --git a/src/test/ui/borrowck/issue-47215-ice-from-drop-elab.rs b/src/test/ui/borrowck/issue-47215-ice-from-drop-elab.rs new file mode 100644 index 0000000000000..670c6bb869d59 --- /dev/null +++ b/src/test/ui/borrowck/issue-47215-ice-from-drop-elab.rs @@ -0,0 +1,20 @@ +// rust-lang/rust#47215: at one time, the compiler categorized +// thread-local statics as a temporary rvalue, as a way to enforce +// that they are only valid for a given lifetime. +// +// The problem with this is that you cannot move out of static items, +// but you *can* move temporary rvalues. I.e., the categorization +// above only solves half of the problem presented by thread-local +// statics. + +#![feature(thread_local)] + +#[thread_local] +static mut X: ::std::sync::atomic::AtomicUsize = ::std::sync::atomic::ATOMIC_USIZE_INIT; + +fn main() { + unsafe { + let mut x = X; //~ ERROR cannot move out of thread-local static item [E0507] + let _y = x.get_mut(); + } +} diff --git a/src/test/ui/borrowck/issue-47215-ice-from-drop-elab.stderr b/src/test/ui/borrowck/issue-47215-ice-from-drop-elab.stderr new file mode 100644 index 0000000000000..219a1fd2e7727 --- /dev/null +++ b/src/test/ui/borrowck/issue-47215-ice-from-drop-elab.stderr @@ -0,0 +1,12 @@ +error[E0507]: cannot move out of thread-local static item + --> $DIR/issue-47215-ice-from-drop-elab.rs:17:21 + | +LL | let mut x = X; //~ ERROR cannot move out of thread-local static item [E0507] + | ^ + | | + | cannot move out of thread-local static item + | help: consider using a reference instead: `&X` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0507`. diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-false.rs b/src/test/ui/conditional-compilation/cfg-attr-multi-false.rs index 84bd33fc0e7d3..ec4ee80b498a5 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-multi-false.rs +++ b/src/test/ui/conditional-compilation/cfg-attr-multi-false.rs @@ -1,5 +1,5 @@ // Test that cfg_attr doesn't emit any attributes when the -// configuation variable is false. This mirrors `cfg-attr-multi-true.rs` +// configuration variable is false. This mirrors `cfg-attr-multi-true.rs` // compile-pass diff --git a/src/test/ui/consts/const-eval/ub-uninhabit.rs b/src/test/ui/consts/const-eval/ub-uninhabit.rs index 99305beee5281..733de2726632d 100644 --- a/src/test/ui/consts/const-eval/ub-uninhabit.rs +++ b/src/test/ui/consts/const-eval/ub-uninhabit.rs @@ -1,13 +1,3 @@ -// Copyright 2018 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. - #![feature(const_transmute)] use std::mem; @@ -15,14 +5,18 @@ use std::mem; #[derive(Copy, Clone)] enum Bar {} -const BAD_BAD_BAD: Bar = unsafe { mem::transmute(()) }; +union TransmuteUnion { + a: A, + b: B, +} + +const BAD_BAD_BAD: Bar = unsafe { (TransmuteUnion::<(), Bar> { a: () }).b }; //~^ ERROR this constant likely exhibits undefined behavior const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) }; //~^ ERROR this constant likely exhibits undefined behavior -const BAD_BAD_ARRAY: [Bar; 1] = unsafe { mem::transmute(()) }; +const BAD_BAD_ARRAY: [Bar; 1] = unsafe { (TransmuteUnion::<(), [Bar; 1]> { a: () }).b }; //~^ ERROR this constant likely exhibits undefined behavior -fn main() { -} +fn main() {} diff --git a/src/test/ui/consts/const-eval/ub-uninhabit.stderr b/src/test/ui/consts/const-eval/ub-uninhabit.stderr index 136d5f2919946..62e6ff2c7bd5b 100644 --- a/src/test/ui/consts/const-eval/ub-uninhabit.stderr +++ b/src/test/ui/consts/const-eval/ub-uninhabit.stderr @@ -1,13 +1,13 @@ error[E0080]: this constant likely exhibits undefined behavior - --> $DIR/ub-uninhabit.rs:18:1 + --> $DIR/ub-uninhabit.rs:13:1 | -LL | const BAD_BAD_BAD: Bar = unsafe { mem::transmute(()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of an uninhabited type +LL | const BAD_BAD_BAD: Bar = unsafe { (TransmuteUnion::<(), Bar> { a: () }).b }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of an uninhabited type | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior error[E0080]: this constant likely exhibits undefined behavior - --> $DIR/ub-uninhabit.rs:21:1 + --> $DIR/ub-uninhabit.rs:16:1 | LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of an uninhabited type at . @@ -15,10 +15,10 @@ LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) }; = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior error[E0080]: this constant likely exhibits undefined behavior - --> $DIR/ub-uninhabit.rs:24:1 + --> $DIR/ub-uninhabit.rs:19:1 | -LL | const BAD_BAD_ARRAY: [Bar; 1] = unsafe { mem::transmute(()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of an uninhabited type at [0] +LL | const BAD_BAD_ARRAY: [Bar; 1] = unsafe { (TransmuteUnion::<(), [Bar; 1]> { a: () }).b }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of an uninhabited type | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior diff --git a/src/test/ui/consts/dangling-alloc-id-ice-2.nll.stderr b/src/test/ui/consts/dangling-alloc-id-ice-2.nll.stderr new file mode 100644 index 0000000000000..e6ae57796055f --- /dev/null +++ b/src/test/ui/consts/dangling-alloc-id-ice-2.nll.stderr @@ -0,0 +1,30 @@ +warning[E0716]: temporary value dropped while borrowed + --> $DIR/dangling-alloc-id-ice-2.rs:5:28 + | +LL | static MAP: Slice = Slice(&[ + | ___________________________-^ + | |___________________________| + | || +LL | || b"CloseEvent" as &'static [u8], +LL | || ]); + | || -- temporary value is freed at the end of this statement + | ||_| + | |__creates a temporary which is freed while still in use + | cast requires that borrow lasts for `'static` + | + = warning: This error has been downgraded to a warning for backwards compatibility with previous releases. + It represents potential unsoundness in your code. + This warning will become a hard error in the future. + +error[E0080]: could not evaluate static initializer + --> $DIR/dangling-alloc-id-ice-2.rs:5:1 + | +LL | / static MAP: Slice = Slice(&[ +LL | | b"CloseEvent" as &'static [u8], +LL | | ]); + | |___^ type validation failed: encountered dangling pointer in final constant + +error: aborting due to previous error + +Some errors occurred: E0080, E0716. +For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/dangling-alloc-id-ice-2.rs b/src/test/ui/consts/dangling-alloc-id-ice-2.rs new file mode 100644 index 0000000000000..b4691641fc98f --- /dev/null +++ b/src/test/ui/consts/dangling-alloc-id-ice-2.rs @@ -0,0 +1,10 @@ +// FIXME(#55223) this is just a reproduction test showing the wrong behavior + +struct Slice(&'static [&'static [u8]]); + +static MAP: Slice = Slice(&[ + b"CloseEvent" as &'static [u8], +]); + + +fn main() {} diff --git a/src/test/ui/consts/dangling-alloc-id-ice-2.stderr b/src/test/ui/consts/dangling-alloc-id-ice-2.stderr new file mode 100644 index 0000000000000..42df542f55cf5 --- /dev/null +++ b/src/test/ui/consts/dangling-alloc-id-ice-2.stderr @@ -0,0 +1,11 @@ +error[E0080]: could not evaluate static initializer + --> $DIR/dangling-alloc-id-ice-2.rs:5:1 + | +LL | / static MAP: Slice = Slice(&[ +LL | | b"CloseEvent" as &'static [u8], +LL | | ]); + | |___^ type validation failed: encountered dangling pointer in final constant + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/dangling-alloc-id-ice.rs b/src/test/ui/consts/dangling-alloc-id-ice.rs new file mode 100644 index 0000000000000..31fa23ae23221 --- /dev/null +++ b/src/test/ui/consts/dangling-alloc-id-ice.rs @@ -0,0 +1,15 @@ +// https://github.com/rust-lang/rust/issues/55223 + +#![feature(const_let)] + +union Foo<'a> { + y: &'a (), + long_live_the_unit: &'static (), +} + +const FOO: &() = { //~ ERROR this constant cannot be used + let y = (); + unsafe { Foo { y: &y }.long_live_the_unit } +}; + +fn main() {} diff --git a/src/test/ui/consts/dangling-alloc-id-ice.stderr b/src/test/ui/consts/dangling-alloc-id-ice.stderr new file mode 100644 index 0000000000000..df623f943addc --- /dev/null +++ b/src/test/ui/consts/dangling-alloc-id-ice.stderr @@ -0,0 +1,13 @@ +error: this constant cannot be used + --> $DIR/dangling-alloc-id-ice.rs:10:1 + | +LL | / const FOO: &() = { //~ ERROR this constant cannot be used +LL | | let y = (); +LL | | unsafe { Foo { y: &y }.long_live_the_unit } +LL | | }; + | |__^ type validation failed: encountered dangling pointer in final constant + | + = note: #[deny(const_err)] on by default + +error: aborting due to previous error + diff --git a/src/test/ui/did_you_mean/issue-42764.rs b/src/test/ui/did_you_mean/issue-42764.rs index ff4bb428d5f5f..1c79499ba5902 100644 --- a/src/test/ui/did_you_mean/issue-42764.rs +++ b/src/test/ui/did_you_mean/issue-42764.rs @@ -20,4 +20,20 @@ fn main() { let n: usize = 42; this_function_expects_a_double_option(n); //~^ ERROR mismatched types + //~| HELP try using a variant of the expected type +} + + +// But don't issue the "try using a variant" help if the one-"variant" ADT is +// actually a one-field struct. + +struct Payload; + +struct Wrapper { payload: Payload } + +struct Context { wrapper: Wrapper } + +fn overton() { + let _c = Context { wrapper: Payload{} }; + //~^ ERROR mismatched types } diff --git a/src/test/ui/did_you_mean/issue-42764.stderr b/src/test/ui/did_you_mean/issue-42764.stderr index f1da920872d7c..e256a436affba 100644 --- a/src/test/ui/did_you_mean/issue-42764.stderr +++ b/src/test/ui/did_you_mean/issue-42764.stderr @@ -13,6 +13,15 @@ LL | this_function_expects_a_double_option(DoubleOption::FirstSome(n)); LL | this_function_expects_a_double_option(DoubleOption::AlternativeSome(n)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error[E0308]: mismatched types + --> $DIR/issue-42764.rs:37:33 + | +LL | let _c = Context { wrapper: Payload{} }; + | ^^^^^^^^^ expected struct `Wrapper`, found struct `Payload` + | + = note: expected type `Wrapper` + found type `Payload` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/foreign-fn-return-lifetime.fixed b/src/test/ui/foreign-fn-return-lifetime.fixed new file mode 100644 index 0000000000000..9fc35eae7052f --- /dev/null +++ b/src/test/ui/foreign-fn-return-lifetime.fixed @@ -0,0 +1,18 @@ +// Copyright 2017 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. + +// run-rustfix + +extern "C" { + pub fn g(_: &u8) -> &u8; // OK + pub fn f() -> &'static u8; //~ ERROR missing lifetime specifier +} + +fn main() {} diff --git a/src/test/ui/foreign-fn-return-lifetime.rs b/src/test/ui/foreign-fn-return-lifetime.rs index da77066150cc7..941e7e05a3635 100644 --- a/src/test/ui/foreign-fn-return-lifetime.rs +++ b/src/test/ui/foreign-fn-return-lifetime.rs @@ -8,9 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// run-rustfix + extern "C" { - fn g(_: &u8) -> &u8; // OK - fn f() -> &u8; //~ ERROR missing lifetime specifier + pub fn g(_: &u8) -> &u8; // OK + pub fn f() -> &u8; //~ ERROR missing lifetime specifier } fn main() {} diff --git a/src/test/ui/foreign-fn-return-lifetime.stderr b/src/test/ui/foreign-fn-return-lifetime.stderr index ea15897b3d694..583487656f24d 100644 --- a/src/test/ui/foreign-fn-return-lifetime.stderr +++ b/src/test/ui/foreign-fn-return-lifetime.stderr @@ -1,11 +1,10 @@ error[E0106]: missing lifetime specifier - --> $DIR/foreign-fn-return-lifetime.rs:13:15 + --> $DIR/foreign-fn-return-lifetime.rs:15:19 | -LL | fn f() -> &u8; //~ ERROR missing lifetime specifier - | ^ expected lifetime parameter +LL | pub fn f() -> &u8; //~ ERROR missing lifetime specifier + | ^ help: consider giving it a 'static lifetime: `&'static` | = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from - = help: consider giving it a 'static lifetime error: aborting due to previous error diff --git a/src/test/ui/issues/issue-13497.stderr b/src/test/ui/issues/issue-13497.stderr index ab6d041bd48d7..e592452b89944 100644 --- a/src/test/ui/issues/issue-13497.stderr +++ b/src/test/ui/issues/issue-13497.stderr @@ -2,10 +2,9 @@ error[E0106]: missing lifetime specifier --> $DIR/issue-13497.rs:12:5 | LL | &str //~ ERROR missing lifetime specifier - | ^ expected lifetime parameter + | ^ help: consider giving it a 'static lifetime: `&'static` | = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from - = help: consider giving it a 'static lifetime error: aborting due to previous error diff --git a/src/test/ui/issues/issue-17954.rs b/src/test/ui/issues/issue-17954.rs index ce554a7254812..5f003436951ce 100644 --- a/src/test/ui/issues/issue-17954.rs +++ b/src/test/ui/issues/issue-17954.rs @@ -23,4 +23,4 @@ fn main() { println!("{}", a); }); } -//~^ NOTE temporary value only lives until here +//~^ NOTE borrowed value only lives until here diff --git a/src/test/ui/issues/issue-17954.stderr b/src/test/ui/issues/issue-17954.stderr index 76858a9b097b2..020e544ad10ff 100644 --- a/src/test/ui/issues/issue-17954.stderr +++ b/src/test/ui/issues/issue-17954.stderr @@ -2,10 +2,10 @@ error[E0597]: borrowed value does not live long enough --> $DIR/issue-17954.rs:17:14 | LL | let a = &FOO; - | ^^^ temporary value does not live long enough + | ^^^ borrowed value does not live long enough ... LL | } - | - temporary value only lives until here + | - borrowed value only lives until here | = note: borrowed value must be valid for the static lifetime... diff --git a/src/test/ui/issues/issue-26638.stderr b/src/test/ui/issues/issue-26638.stderr index cf6fcd9f01cc8..0ac6316f0dcf8 100644 --- a/src/test/ui/issues/issue-26638.stderr +++ b/src/test/ui/issues/issue-26638.stderr @@ -10,19 +10,17 @@ error[E0106]: missing lifetime specifier --> $DIR/issue-26638.rs:14:40 | LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() } - | ^ expected lifetime parameter + | ^ help: consider giving it an explicit bounded or 'static lifetime: `&'static` | = help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments - = help: consider giving it an explicit bounded or 'static lifetime error[E0106]: missing lifetime specifier --> $DIR/issue-26638.rs:17:22 | LL | fn parse_type_3() -> &str { unimplemented!() } - | ^ expected lifetime parameter + | ^ help: consider giving it a 'static lifetime: `&'static` | = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from - = help: consider giving it a 'static lifetime error: aborting due to 3 previous errors diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr index 30cff86ed1d40..4c7a1b5ea9ff0 100644 --- a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr +++ b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr @@ -2,10 +2,9 @@ error[E0106]: missing lifetime specifier --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:12:11 | LL | fn f() -> &isize { //~ ERROR missing lifetime specifier - | ^ expected lifetime parameter + | ^ help: consider giving it a 'static lifetime: `&'static` | = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from - = help: consider giving it a 'static lifetime error[E0106]: missing lifetime specifier --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:17:33 @@ -27,28 +26,25 @@ error[E0106]: missing lifetime specifier --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:31:20 | LL | fn i(_x: isize) -> &isize { //~ ERROR missing lifetime specifier - | ^ expected lifetime parameter + | ^ help: consider giving it an explicit bounded or 'static lifetime: `&'static` | = help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments - = help: consider giving it an explicit bounded or 'static lifetime error[E0106]: missing lifetime specifier --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:44:24 | LL | fn j(_x: StaticStr) -> &isize { //~ ERROR missing lifetime specifier - | ^ expected lifetime parameter + | ^ help: consider giving it an explicit bounded or 'static lifetime: `&'static` | = help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments - = help: consider giving it an explicit bounded or 'static lifetime error[E0106]: missing lifetime specifier --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:50:49 | LL | fn k<'a, T: WithLifetime<'a>>(_x: T::Output) -> &isize { - | ^ expected lifetime parameter + | ^ help: consider giving it an explicit bounded or 'static lifetime: `&'static` | = help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments - = help: consider giving it an explicit bounded or 'static lifetime error: aborting due to 6 previous errors diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs new file mode 100644 index 0000000000000..eb959bfbcb533 --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs @@ -0,0 +1,12 @@ +trait Future { + type Item; + type Error; +} + +use std::error::Error; + +fn foo() -> impl Future> { + Ok(()) +} + +fn main() {} diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr new file mode 100644 index 0000000000000..b2a3d9a94361f --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr @@ -0,0 +1,11 @@ +error[E0106]: missing lifetime specifier + --> $DIR/lifetime-elision-return-type-trait.rs:8:44 + | +LL | fn foo() -> impl Future> { + | ^^^^^ help: consider giving it a 'static lifetime: `Error + 'static` + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0106`. diff --git a/src/test/ui/nll/issue-21232-partial-init-and-use.rs b/src/test/ui/nll/issue-21232-partial-init-and-use.rs index e3ae4c0dcbe57..186ecc5482720 100644 --- a/src/test/ui/nll/issue-21232-partial-init-and-use.rs +++ b/src/test/ui/nll/issue-21232-partial-init-and-use.rs @@ -66,7 +66,7 @@ impl R { fn new(f: F) -> Self { R { w: 0, f } } } // It got pretty monotonous writing the same code over and over, and I // feared I would forget details. So I abstracted some desiderata into // macros. But I left the initialization code inline, because that's -// where the errors for #54986 will be emited. +// where the errors for #54986 will be emitted. macro_rules! use_fully { (struct $s:expr) => { { diff --git a/src/test/ui/nll/issue-52059-report-when-borrow-and-drop-conflict.rs b/src/test/ui/nll/issue-52059-report-when-borrow-and-drop-conflict.rs index fff73c6d0fa9c..eaa809d2b3706 100644 --- a/src/test/ui/nll/issue-52059-report-when-borrow-and-drop-conflict.rs +++ b/src/test/ui/nll/issue-52059-report-when-borrow-and-drop-conflict.rs @@ -1,5 +1,5 @@ // rust-lang/rust#52059: Regardless of whether you are moving out of a -// Drop type or just introducing an inadvertant alias via a borrow of +// Drop type or just introducing an inadvertent alias via a borrow of // one of its fields, it is useful to be reminded of the significance // of the fact that the type implements Drop. diff --git a/src/test/ui/resolve/token-error-correct-2.rs b/src/test/ui/resolve/token-error-correct-2.rs index e49374f9ce649..55803e4034bf4 100644 --- a/src/test/ui/resolve/token-error-correct-2.rs +++ b/src/test/ui/resolve/token-error-correct-2.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Test that we do some basic error correcton in the tokeniser (and don't ICE). +// Test that we do some basic error correction in the tokeniser (and don't ICE). fn main() { if foo { diff --git a/src/test/ui/resolve/token-error-correct-3.rs b/src/test/ui/resolve/token-error-correct-3.rs index 8881b965f9480..fd4bbde28660e 100644 --- a/src/test/ui/resolve/token-error-correct-3.rs +++ b/src/test/ui/resolve/token-error-correct-3.rs @@ -10,7 +10,7 @@ // ignore-cloudabi no std::fs support -// Test that we do some basic error correcton in the tokeniser (and don't spew +// Test that we do some basic error correction in the tokeniser (and don't spew // too many bogus errors). pub mod raw { diff --git a/src/test/ui/resolve/token-error-correct.rs b/src/test/ui/resolve/token-error-correct.rs index 39c664e270c45..099ead93beb06 100644 --- a/src/test/ui/resolve/token-error-correct.rs +++ b/src/test/ui/resolve/token-error-correct.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Test that we do some basic error correcton in the tokeniser. +// Test that we do some basic error correction in the tokeniser. fn main() { foo(bar(; diff --git a/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2015.rs b/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2015.rs index 339d49104b021..31a34a9e6fbbb 100644 --- a/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2015.rs +++ b/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2015.rs @@ -19,22 +19,22 @@ fn main() { use std::ops::Range; if let Range { start: _, end: _ } = true..true && false { } - //~^ ERROR ambigious use of `&&` + //~^ ERROR ambiguous use of `&&` if let Range { start: _, end: _ } = true..true || false { } - //~^ ERROR ambigious use of `||` + //~^ ERROR ambiguous use of `||` while let Range { start: _, end: _ } = true..true && false { } - //~^ ERROR ambigious use of `&&` + //~^ ERROR ambiguous use of `&&` while let Range { start: _, end: _ } = true..true || false { } - //~^ ERROR ambigious use of `||` + //~^ ERROR ambiguous use of `||` if let true = false && false { } - //~^ ERROR ambigious use of `&&` + //~^ ERROR ambiguous use of `&&` while let true = (1 == 2) && false { } - //~^ ERROR ambigious use of `&&` + //~^ ERROR ambiguous use of `&&` // The following cases are not an error as parenthesis are used to // clarify intent: diff --git a/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2015.stderr b/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2015.stderr index 8597294913f27..411cb99fbca19 100644 --- a/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2015.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2015.stderr @@ -1,4 +1,4 @@ -error: ambigious use of `&&` +error: ambiguous use of `&&` --> $DIR/syntax-ambiguity-2015.rs:21:47 | LL | if let Range { start: _, end: _ } = true..true && false { } @@ -7,7 +7,7 @@ LL | if let Range { start: _, end: _ } = true..true && false { } = note: this will be a error until the `let_chains` feature is stabilized = note: see rust-lang/rust#53668 for more information -error: ambigious use of `||` +error: ambiguous use of `||` --> $DIR/syntax-ambiguity-2015.rs:24:47 | LL | if let Range { start: _, end: _ } = true..true || false { } @@ -16,7 +16,7 @@ LL | if let Range { start: _, end: _ } = true..true || false { } = note: this will be a error until the `let_chains` feature is stabilized = note: see rust-lang/rust#53668 for more information -error: ambigious use of `&&` +error: ambiguous use of `&&` --> $DIR/syntax-ambiguity-2015.rs:27:50 | LL | while let Range { start: _, end: _ } = true..true && false { } @@ -25,7 +25,7 @@ LL | while let Range { start: _, end: _ } = true..true && false { } = note: this will be a error until the `let_chains` feature is stabilized = note: see rust-lang/rust#53668 for more information -error: ambigious use of `||` +error: ambiguous use of `||` --> $DIR/syntax-ambiguity-2015.rs:30:50 | LL | while let Range { start: _, end: _ } = true..true || false { } @@ -34,7 +34,7 @@ LL | while let Range { start: _, end: _ } = true..true || false { } = note: this will be a error until the `let_chains` feature is stabilized = note: see rust-lang/rust#53668 for more information -error: ambigious use of `&&` +error: ambiguous use of `&&` --> $DIR/syntax-ambiguity-2015.rs:33:19 | LL | if let true = false && false { } @@ -43,7 +43,7 @@ LL | if let true = false && false { } = note: this will be a error until the `let_chains` feature is stabilized = note: see rust-lang/rust#53668 for more information -error: ambigious use of `&&` +error: ambiguous use of `&&` --> $DIR/syntax-ambiguity-2015.rs:36:22 | LL | while let true = (1 == 2) && false { } diff --git a/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2018.rs b/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2018.rs index baa90bcf8e971..99495717c3a89 100644 --- a/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2018.rs +++ b/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2018.rs @@ -19,22 +19,22 @@ fn main() { use std::ops::Range; if let Range { start: _, end: _ } = true..true && false { } - //~^ ERROR ambigious use of `&&` + //~^ ERROR ambiguous use of `&&` if let Range { start: _, end: _ } = true..true || false { } - //~^ ERROR ambigious use of `||` + //~^ ERROR ambiguous use of `||` while let Range { start: _, end: _ } = true..true && false { } - //~^ ERROR ambigious use of `&&` + //~^ ERROR ambiguous use of `&&` while let Range { start: _, end: _ } = true..true || false { } - //~^ ERROR ambigious use of `||` + //~^ ERROR ambiguous use of `||` if let true = false && false { } - //~^ ERROR ambigious use of `&&` + //~^ ERROR ambiguous use of `&&` while let true = (1 == 2) && false { } - //~^ ERROR ambigious use of `&&` + //~^ ERROR ambiguous use of `&&` // The following cases are not an error as parenthesis are used to // clarify intent: diff --git a/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2018.stderr b/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2018.stderr index 86ee04747b29d..bd49abeb7b247 100644 --- a/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2018.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2018.stderr @@ -1,4 +1,4 @@ -error: ambigious use of `&&` +error: ambiguous use of `&&` --> $DIR/syntax-ambiguity-2018.rs:21:47 | LL | if let Range { start: _, end: _ } = true..true && false { } @@ -7,7 +7,7 @@ LL | if let Range { start: _, end: _ } = true..true && false { } = note: this will be a error until the `let_chains` feature is stabilized = note: see rust-lang/rust#53668 for more information -error: ambigious use of `||` +error: ambiguous use of `||` --> $DIR/syntax-ambiguity-2018.rs:24:47 | LL | if let Range { start: _, end: _ } = true..true || false { } @@ -16,7 +16,7 @@ LL | if let Range { start: _, end: _ } = true..true || false { } = note: this will be a error until the `let_chains` feature is stabilized = note: see rust-lang/rust#53668 for more information -error: ambigious use of `&&` +error: ambiguous use of `&&` --> $DIR/syntax-ambiguity-2018.rs:27:50 | LL | while let Range { start: _, end: _ } = true..true && false { } @@ -25,7 +25,7 @@ LL | while let Range { start: _, end: _ } = true..true && false { } = note: this will be a error until the `let_chains` feature is stabilized = note: see rust-lang/rust#53668 for more information -error: ambigious use of `||` +error: ambiguous use of `||` --> $DIR/syntax-ambiguity-2018.rs:30:50 | LL | while let Range { start: _, end: _ } = true..true || false { } @@ -34,7 +34,7 @@ LL | while let Range { start: _, end: _ } = true..true || false { } = note: this will be a error until the `let_chains` feature is stabilized = note: see rust-lang/rust#53668 for more information -error: ambigious use of `&&` +error: ambiguous use of `&&` --> $DIR/syntax-ambiguity-2018.rs:33:19 | LL | if let true = false && false { } @@ -43,7 +43,7 @@ LL | if let true = false && false { } = note: this will be a error until the `let_chains` feature is stabilized = note: see rust-lang/rust#53668 for more information -error: ambigious use of `&&` +error: ambiguous use of `&&` --> $DIR/syntax-ambiguity-2018.rs:36:22 | LL | while let true = (1 == 2) && false { } diff --git a/src/test/ui/rust-2018/edition-lint-infer-outlives.fixed b/src/test/ui/rust-2018/edition-lint-infer-outlives.fixed index d70c847e9fe68..f13f8ef2bb4cf 100644 --- a/src/test/ui/rust-2018/edition-lint-infer-outlives.fixed +++ b/src/test/ui/rust-2018/edition-lint-infer-outlives.fixed @@ -24,7 +24,7 @@ use std::fmt::{Debug, Display}; // • one generic parameter (T) bound inline // • one parameter (T) with a where clause // • two parameters (T and U), both bound inline -// • two paramters (T and U), one bound inline, one with a where clause +// • two parameters (T and U), one bound inline, one with a where clause // • two parameters (T and U), both with where clauses // // —and for every permutation of 0, 1, or 2 lifetimes to outlive and 0 or 1 diff --git a/src/test/ui/rust-2018/edition-lint-infer-outlives.rs b/src/test/ui/rust-2018/edition-lint-infer-outlives.rs index 0e4436fe1632f..f47b3fcb9be9a 100644 --- a/src/test/ui/rust-2018/edition-lint-infer-outlives.rs +++ b/src/test/ui/rust-2018/edition-lint-infer-outlives.rs @@ -24,7 +24,7 @@ use std::fmt::{Debug, Display}; // • one generic parameter (T) bound inline // • one parameter (T) with a where clause // • two parameters (T and U), both bound inline -// • two paramters (T and U), one bound inline, one with a where clause +// • two parameters (T and U), one bound inline, one with a where clause // • two parameters (T and U), both with where clauses // // —and for every permutation of 0, 1, or 2 lifetimes to outlive and 0 or 1 diff --git a/src/test/ui/rust-2018/local-path-suggestions-2018.stderr b/src/test/ui/rust-2018/local-path-suggestions-2018.stderr index 97bf748881f29..2293f4b001749 100644 --- a/src/test/ui/rust-2018/local-path-suggestions-2018.stderr +++ b/src/test/ui/rust-2018/local-path-suggestions-2018.stderr @@ -3,6 +3,8 @@ error[E0432]: unresolved import `foo` | LL | use foo::Bar; | ^^^ Did you mean `crate::foo`? + | + = note: `use` statements changed in Rust 2018; read more at error[E0432]: unresolved import `foo` --> $DIR/local-path-suggestions-2018.rs:27:5 diff --git a/src/test/ui/specialization/issue-52050.rs b/src/test/ui/specialization/issue-52050.rs index 70cdb4899c421..00d8d126e0573 100644 --- a/src/test/ui/specialization/issue-52050.rs +++ b/src/test/ui/specialization/issue-52050.rs @@ -12,7 +12,7 @@ // Regression test for #52050: when inserting the blanket impl `I` // into the tree, we had to replace the child node for `Foo`, which -// led to the struture of the tree being messed up. +// led to the structure of the tree being messed up. use std::iter::Iterator; diff --git a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr index bccecd60e1c9e..e56d008d2665f 100644 --- a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr +++ b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr @@ -20,10 +20,9 @@ error[E0106]: missing lifetime specifier --> $DIR/underscore-lifetime-binders.rs:20:29 | LL | fn meh() -> Box Meh<'_>> //~ ERROR cannot be used here - | ^^ expected lifetime parameter + | ^^ help: consider giving it a 'static lifetime: `'static` | = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from - = help: consider giving it a 'static lifetime error[E0106]: missing lifetime specifier --> $DIR/underscore-lifetime-binders.rs:26:35 diff --git a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs index 1d3f8ff12d865..a3b99deac233b 100644 --- a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs +++ b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs @@ -20,10 +20,10 @@ fn main() { let _ = match x {}; //~ ERROR non-exhaustive let x: (Void,) = unsafe { std::mem::uninitialized() }; - let _ = match x {}; //~ ERROR non-exhaustive + let _ = match x {}; // okay let x: [Void; 1] = unsafe { std::mem::uninitialized() }; - let _ = match x {}; //~ ERROR non-exhaustive + let _ = match x {}; // okay let x: &[Void] = unsafe { std::mem::uninitialized() }; let _ = match x { //~ ERROR non-exhaustive diff --git a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr index d86ebda027efb..abaad8958dbe6 100644 --- a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr +++ b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr @@ -16,30 +16,6 @@ help: Please ensure that all possible cases are being handled; possibly adding w LL | let _ = match x {}; //~ ERROR non-exhaustive | ^ -error[E0004]: non-exhaustive patterns: type (Void,) is non-empty - --> $DIR/uninhabited-matches-feature-gated.rs:23:19 - | -LL | let _ = match x {}; //~ ERROR non-exhaustive - | ^ - | -help: Please ensure that all possible cases are being handled; possibly adding wildcards or more match arms. - --> $DIR/uninhabited-matches-feature-gated.rs:23:19 - | -LL | let _ = match x {}; //~ ERROR non-exhaustive - | ^ - -error[E0004]: non-exhaustive patterns: type [Void; 1] is non-empty - --> $DIR/uninhabited-matches-feature-gated.rs:26:19 - | -LL | let _ = match x {}; //~ ERROR non-exhaustive - | ^ - | -help: Please ensure that all possible cases are being handled; possibly adding wildcards or more match arms. - --> $DIR/uninhabited-matches-feature-gated.rs:26:19 - | -LL | let _ = match x {}; //~ ERROR non-exhaustive - | ^ - error[E0004]: non-exhaustive patterns: `&[_]` not covered --> $DIR/uninhabited-matches-feature-gated.rs:29:19 | @@ -58,7 +34,7 @@ error[E0005]: refutable pattern in local binding: `Err(_)` not covered LL | let Ok(x) = x; | ^^^^^ pattern `Err(_)` not covered -error: aborting due to 7 previous errors +error: aborting due to 5 previous errors Some errors occurred: E0004, E0005. For more information about an error, try `rustc --explain E0004`. diff --git a/src/tools/clippy b/src/tools/clippy index 5afdf8b78507d..b1d0343749bdc 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit 5afdf8b78507ddf015d192858aef56e72c17de16 +Subproject commit b1d0343749bdc87e5cbbe7f1aeaa9d2a2c9dbc5b diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs index 69a4c09c2285d..3d5e18e37b070 100644 --- a/src/tools/tidy/src/pal.rs +++ b/src/tools/tidy/src/pal.rs @@ -163,7 +163,7 @@ fn check_cfgs(contents: &mut String, file: &Path, fn find_test_mod(contents: &str) -> usize { if let Some(mod_tests_idx) = contents.find("mod tests") { - // Also capture a previos line indicating "mod tests" in cfg-ed out + // Also capture a previous line indicating "mod tests" in cfg-ed out let prev_newline_idx = contents[..mod_tests_idx].rfind('\n').unwrap_or(mod_tests_idx); let prev_newline_idx = contents[..prev_newline_idx].rfind('\n'); if let Some(nl) = prev_newline_idx {