diff --git a/RELEASES.md b/RELEASES.md index 7ae7dc9935b6d..70a7dab72272f 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -4,34 +4,31 @@ 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 - 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. + macros, it is recommended to export with the + `#[macro_export(local_inner_macros)]` attribute so users won't have to import + those macros. - [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 +51,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 +73,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 +150,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 +166,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 +181,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 +429,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 +492,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 +511,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 +575,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 +586,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 +613,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 +1049,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..dd21108352792 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]] 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/libcore/task/wake.rs b/src/libcore/task/wake.rs index ab4ae50c44367..c9fb22e0080dd 100644 --- a/src/libcore/task/wake.rs +++ b/src/libcore/task/wake.rs @@ -188,6 +188,11 @@ impl LocalWaker { } impl From for Waker { + /// Converts a `LocalWaker` into a `Waker`. + /// + /// This conversion turns a `!Sync` `LocalWaker` into a `Sync` `Waker`, allowing a wakeup + /// object to be sent to another thread, but giving up its ability to do specialized + /// thread-local wakeup behavior. #[inline] fn from(local_waker: LocalWaker) -> Self { local_waker.0 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/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/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 9e54b146fd02a..4304f08a78f0c 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -181,7 +181,7 @@ impl<'tcx, Tag> Scalar { #[inline] pub fn is_null_ptr(self, cx: impl HasDataLayout) -> bool { match self { - Scalar::Bits { bits, size } => { + Scalar::Bits { bits, size } => { assert_eq!(size as u64, cx.data_layout().pointer_size.bytes()); bits == 0 }, @@ -189,14 +189,6 @@ impl<'tcx, Tag> Scalar { } } - #[inline] - pub fn is_null(self) -> bool { - match self { - Scalar::Bits { bits, .. } => bits == 0, - Scalar::Ptr(_) => false - } - } - #[inline] pub fn from_bool(b: bool) -> Self { Scalar::Bits { bits: b as u128, size: 1 } diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 571beaae4596b..9d296e67da1ae 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, @@ -2065,9 +2065,8 @@ pub struct SourceScopeLocalData { /////////////////////////////////////////////////////////////////////////// // Operands -/// These are values that can appear inside an rvalue (or an index -/// place). They are intentionally limited to prevent rvalues from -/// being nested in one another. +/// These are values that can appear inside an rvalue. They are intentionally +/// limited to prevent rvalues from being nested in one another. #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable)] pub enum Operand<'tcx> { /// Copy: The value must be available for use afterwards. 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/ty/sty.rs b/src/librustc/ty/sty.rs index cd9679c876355..62e38ad9bfa66 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 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_lint/unused.rs b/src/librustc_lint/unused.rs index 4cf2072e792ca..96d04253cc485 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -284,8 +284,13 @@ impl UnusedParens { parser::contains_exterior_struct_lit(&inner) }; if !necessary { - let pattern = pprust::expr_to_string(value); - Self::remove_outer_parens(cx, value.span, &pattern, msg); + let expr_text = if let Ok(snippet) = cx.sess().source_map() + .span_to_snippet(value.span) { + snippet + } else { + pprust::expr_to_string(value) + }; + Self::remove_outer_parens(cx, value.span, &expr_text, msg); } } } @@ -295,8 +300,13 @@ impl UnusedParens { value: &ast::Pat, msg: &str) { if let ast::PatKind::Paren(_) = value.node { - let pattern = pprust::pat_to_string(value); - Self::remove_outer_parens(cx, value.span, &pattern, msg); + let pattern_text = if let Ok(snippet) = cx.sess().source_map() + .span_to_snippet(value.span) { + snippet + } else { + pprust::pat_to_string(value) + }; + Self::remove_outer_parens(cx, value.span, &pattern_text, msg); } } 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_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/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..6fe490c6efc8f 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, @@ -1098,7 +1098,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_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/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/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/f32.rs b/src/libstd/f32.rs index c3f225d1eb013..7d17aaf2f261b 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -198,12 +198,12 @@ impl f32 { } } - /// Returns a number composed of the magnitude of one number and the sign of - /// another. + /// Returns a number composed of the magnitude of `self` and the sign of + /// `y`. /// /// Equal to `self` if the sign of `self` and `y` are the same, otherwise - /// equal to `-y`. If `self` is a `NAN`, then a `NAN` with the sign of `y` - /// is returned. + /// equal to `-self`. If `self` is a `NAN`, then a `NAN` with the sign of + /// `y` is returned. /// /// # Examples /// diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs index da062dda77a47..ecaaf8323ab91 100644 --- a/src/libstd/f64.rs +++ b/src/libstd/f64.rs @@ -176,12 +176,12 @@ impl f64 { } } - /// Returns a number composed of the magnitude of one number and the sign of - /// another. + /// Returns a number composed of the magnitude of `self` and the sign of + /// `y`. /// /// Equal to `self` if the sign of `self` and `y` are the same, otherwise - /// equal to `-y`. If `self` is a `NAN`, then a `NAN` with the sign of `y` - /// is returned. + /// equal to `-self`. If `self` is a `NAN`, then a `NAN` with the sign of + /// `y` is returned. /// /// # Examples /// diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs index d70cf132b3c3a..6c95854c66cbf 100644 --- a/src/libstd/keyword_docs.rs +++ b/src/libstd/keyword_docs.rs @@ -8,72 +8,713 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[doc(keyword = "as")] +// +/// The keyword for casting a value to a type. +/// +/// `as` is most commonly used to turn primitive types into other primitive types, but it has other +/// uses that include turning pointers into addresses, addresses into pointers, and pointers into +/// other pointers. +/// +/// ```rust +/// let thing1: u8 = 89.0 as u8; +/// assert_eq!('B' as u32, 66); +/// assert_eq!(thing1 as char, 'Y'); +/// let thing2: f32 = thing1 as f32 + 10.5; +/// assert_eq!(true as u8 + thing2 as u8, 100); +/// ``` +/// +/// In general, any cast that can be performed via ascribing the type can also be done using `as`, +/// so instead of writing `let x: u32 = 123`, you can write `let x = 123 as u32` (Note: `let x: u32 +/// = 123` would be best in that situation). The same is not true in the other direction, however, +/// explicitly using `as` allows a few more coercions that aren't allowed implicitly, such as +/// changing the type of a raw pointer or turning closures into raw pointers. +/// +/// Other places `as` is used include as extra syntax for [`crate`] and `use`, to change the name +/// something is imported as. +/// +/// For more information on what `as` is capable of, see the [Reference] +/// +/// [Reference]: +/// https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions +/// [`crate`]: keyword.crate.html +mod as_keyword { } + +#[doc(keyword = "const")] +// +/// The keyword for defining constants. +/// +/// Sometimes a certain value is used many times throughout a program, and it can become +/// inconvenient to copy it over and over. What's more, it's not always possible or desirable to +/// make it a variable that gets carried around to each function that needs it. In these cases, the +/// `const` keyword provides a convenient alternative to code duplication. +/// +/// ```rust +/// const THING: u32 = 0xABAD1DEA; +/// +/// let foo = 123 + THING; +/// ``` +/// +/// Constants must be explicitly typed, unlike with `let` you can't ignore its type and let the +/// compiler figure it out. Any constant value can be defined in a const, which in practice happens +/// to be most things that would be reasonable to have a constant (barring `const fn`s, coming +/// soon). For example, you can't have a File as a `const`. +/// +/// The only lifetime allowed in a constant is `'static`, which is the lifetime that encompasses +/// all others in a Rust program. For example, if you wanted to define a constant string, it would +/// look like this: +/// +/// ```rust +/// const WORDS: &'static str = "hello rust!"; +/// ``` +/// +/// Thanks to static lifetime elision, you usually don't have to explicitly use 'static: +/// +/// ```rust +/// const WORDS: &str = "hello convenience!"; +/// ``` +/// +/// `const` items looks remarkably similar to `static` items, which introduces some confusion as +/// to which one should be used at which times. To put it simply, constants are inlined wherever +/// they're used, making using them identical to simply replacing the name of the const with its +/// value. Static variables on the other hand point to a single location in memory, which all +/// accesses share. This means that, unlike with constants, they can't have destructors, and act as +/// a single value across the entire codebase. +/// +/// Constants, as with statics, should always be in SCREAMING_SNAKE_CASE. +/// +/// The `const` keyword is also used in raw pointers in combination with `mut`, as seen in `*const +/// T` and `*mut T`. More about that can be read at the [pointer] primitive part of the Rust docs. +/// +/// For more detail on `const`, see the [Rust Book] or the [Reference] +/// +/// [pointer]: primitive.pointer.html +/// [Rust Book]: +/// https://doc.rust-lang.org/stable/book/2018-edition/ch03-01-variables-and-mutability.html#differences-between-variables-and-constants +/// [Reference]: https://doc.rust-lang.org/reference/items/constant-items.html +mod const_keyword { } + +#[doc(keyword = "crate")] +// +/// The `crate` keyword. +/// +/// The primary use of the `crate` keyword is as a part of `extern crate` declarations, which are +/// used to specify a dependency on a crate external to the one it's declared in. Crates are the +/// fundamental compilation unit of Rust code, and can be seen as libraries or projects. More can +/// be read about crates in the [Reference]. +/// +/// ```rust ignore +/// extern crate rand; +/// extern crate my_crate as thing; +/// extern crate std; // implicitly added to the root of every Rust project +/// ``` +/// +/// The `as` keyword can be used to change what the crate is referred to as in your project. If a +/// crate name includes a dash, it is implicitly imported with the dashes replaced by underscores. +/// +/// `crate` is also used as in conjunction with `pub` to signify that the item it's attached to +/// is public only to other members of the same crate it's in. +/// +/// ```rust +/// # #[allow(unused_imports)] +/// pub(crate) use std::io::Error as IoError; +/// pub(crate) enum CoolMarkerType { } +/// pub struct PublicThing { +/// pub(crate) semi_secret_thing: bool, +/// } +/// ``` +/// +/// [Reference]: https://doc.rust-lang.org/reference/items/extern-crates.html +mod crate_keyword { } + +#[doc(keyword = "enum")] +// +/// For defining enumerations. +/// +/// Enums in Rust are similar to those of other compiled languages like C, but have important +/// differences that make them considerably more powerful. What Rust calls enums are more commonly +/// known as [Algebraic Data Types] if you're coming from a functional programming background. The +/// important detail is that each enum variant can have data to go along with it. +/// +/// ```rust +/// # struct Coord; +/// enum SimpleEnum { +/// FirstVariant, +/// SecondVariant, +/// ThirdVariant, +/// } +/// +/// enum Location { +/// Unknown, +/// Anonymous, +/// Known(Coord), +/// } +/// +/// enum ComplexEnum { +/// Nothing, +/// Something(u32), +/// LotsOfThings { +/// usual_struct_stuff: bool, +/// blah: String, +/// } +/// } +/// +/// enum EmptyEnum { } +/// ``` +/// +/// The first enum shown is the usual kind of enum you'd find in a C-style language. The second +/// shows off a hypothetical example of something storing location data, with `Coord` being any +/// other type that's needed, for example a struct. The third example demonstrates the kind of +/// data a variant can store, ranging from nothing, to a tuple, to an anonymous struct. +/// +/// Instantiating enum variants involves explicitly using the enum's name as its namespace, +/// followed by one of its variants. `SimpleEnum::SecondVariant` would be an example from above. +/// When data follows along with a variant, such as with rust's built-in [`Option`] type, the data +/// is added as the type describes, for example `Option::Some(123)`. The same follows with +/// struct-like variants, with things looking like `ComplexEnum::LotsOfThings { usual_struct_stuff: +/// true, blah: "hello!".to_string(), }`. Empty Enums are similar to () in that they cannot be +/// instantiated at all, and are used mainly to mess with the type system in interesting ways. +/// +/// For more information, take a look at the [Rust Book] or the [Reference] +/// +/// [Algebraic Data Types]: https://en.wikipedia.org/wiki/Algebraic_data_type +/// [`Option`]: option/enum.Option.html +/// [Rust Book]: https://doc.rust-lang.org/book/second-edition/ch06-01-defining-an-enum.html +/// [Reference]: https://doc.rust-lang.org/reference/items/enumerations.html +mod enum_keyword { } + +#[doc(keyword = "extern")] +// +/// For external connections in Rust code. +/// +/// The `extern` keyword is used in two places in Rust. One is in conjunction with the [`crate`] +/// keyword to make your Rust code aware of other Rust crates in your project, i.e. `extern crate +/// lazy_static;`. The other use is in foreign function interfaces (FFI). +/// +/// `extern` is used in two different contexts within FFI. The first is in the form of external +/// blocks, for declaring function interfaces that Rust code can call foreign code by. +/// +/// ```rust ignore +/// #[link(name = "my_c_library")] +/// extern "C" { +/// fn my_c_function(x: i32) -> bool; +/// } +/// ``` +/// +/// This code would attempt to link with `libmy_c_library.so` on unix-like systems and +/// `my_c_library.dll` on Windows at runtime, and panic if it can't find something to link to. Rust +/// code could then use `my_c_function` as if it were any other unsafe Rust function. Working with +/// non-Rust languages and FFI is inherently unsafe, so wrappers are usually built around C APIs. +/// +/// The mirror use case of FFI is also done via the `extern` keyword: +/// +/// ```rust +/// #[no_mangle] +/// pub extern fn callable_from_c(x: i32) -> bool { +/// x % 3 == 0 +/// } +/// ``` +/// +/// If compiled as a dylib, the resulting .so could then be linked to from a C library, and the +/// function could be used as if it was from any other library. +/// +/// For more information on FFI, check the [Rust book] or the [Reference]. +/// +/// [Rust book]: +/// https://doc.rust-lang.org/book/second-edition/ch19-01-unsafe-rust.html#using-extern-functions-to-call-external-code +/// [Reference]: https://doc.rust-lang.org/reference/items/external-blocks.html +mod extern_keyword { } + #[doc(keyword = "fn")] // -/// The `fn` keyword. +/// The keyword for defining functions. /// -/// The `fn` keyword is used to declare a function. +/// Functions are the primary way code is executed within Rust. Function blocks, usually just +/// called functions, can be defined in a variety of different places and be assigned many +/// different attributes and modifiers. /// -/// Example: +/// Standalone functions that just sit within a module not attached to anything else are common, +/// but most functions will end up being inside [`impl`] blocks, either on another type itself, or +/// as a trait impl for that type. /// /// ```rust -/// fn some_function() { -/// // code goes in here +/// fn standalone_function() { +/// // code +/// } +/// +/// pub fn public_thing(argument: bool) -> String { +/// // code +/// # "".to_string() +/// } +/// +/// struct Thing { +/// foo: i32, +/// } +/// +/// impl Thing { +/// pub fn new() -> Self { +/// Self { +/// foo: 42, +/// } +/// } /// } /// ``` /// -/// For more information about functions, take a look at the [Rust Book][book]. +/// In addition to presenting fixed types in the form of `fn name(arg: type, ..) -> return_type`, +/// functions can also declare a list of type parameters along with trait bounds that they fall +/// into. /// -/// [book]: https://doc.rust-lang.org/book/second-edition/ch03-03-how-functions-work.html +/// ```rust +/// fn generic_function(x: T) -> (T, T, T) { +/// (x.clone(), x.clone(), x.clone()) +/// } +/// +/// fn generic_where(x: T) -> T +/// where T: std::ops::Add + Copy +/// { +/// x + x + x +/// } +/// ``` +/// +/// Declaring trait bounds in the angle brackets is functionally identical to using a `where` +/// clause. It's up to the programmer to decide which works better in each situation, but `where` +/// tends to be better when things get longer than one line. +/// +/// Along with being made public via `pub`, `fn` can also have an [`extern`] added for use in +/// FFI. +/// +/// For more information on the various types of functions and how they're used, consult the [Rust +/// book] or the [Reference]. +/// +/// [`impl`]: keyword.impl.html +/// [`extern`]: keyword.extern.html +/// [Rust book]: https://doc.rust-lang.org/book/second-edition/ch03-03-how-functions-work.html +/// [Reference]: https://doc.rust-lang.org/reference/items/functions.html mod fn_keyword { } -#[doc(keyword = "let")] +#[doc(keyword = "for")] // -/// The `let` keyword. +/// The `for` keyword. +/// +/// `for` is primarily used in for-in-loops, but it has a few other pieces of syntactic uses such as +/// `impl Trait for Type` (see [`impl`] for more info on that). for-in-loops, or to be more +/// precise, iterator loops, are a simple syntactic sugar over an exceedingly common practice +/// within Rust, which is to loop over an iterator until that iterator returns None (or `break` +/// is called). +/// +/// ```rust +/// for i in 0..5 { +/// println!("{}", i * 2); +/// } /// -/// The `let` keyword is used to declare a variable. +/// for i in std::iter::repeat(5) { +/// println!("turns out {} never stops being 5", i); +/// break; // would loop forever otherwise +/// } /// -/// Example: +/// 'outer: for x in 5..50 { +/// for y in 0..10 { +/// if x == y { +/// break 'outer; +/// } +/// } +/// } +/// ``` +/// +/// As shown in the example above, `for` loops (along with all other loops) can be tagged, using +/// similar syntax to lifetimes (only visually similar, entirely distinct in practice). Giving the +/// same tag to `break` breaks the tagged loop, which is useful for inner loops. It is definitely +/// not a goto. +/// +/// A `for` loop expands as shown: /// /// ```rust -/// # #![allow(unused_assignments)] -/// let x = 3; // We create a variable named `x` with the value `3`. +/// # fn code() { } +/// # let iterator = 0..2; +/// for loop_variable in iterator { +/// code() +/// } +/// ``` +/// +/// ```rust +/// # fn code() { } +/// # let iterator = 0..2; +/// { +/// let mut _iter = std::iter::IntoIterator::into_iter(iterator); +/// loop { +/// match _iter.next() { +/// Some(loop_variable) => { +/// code() +/// }, +/// None => break, +/// } +/// } +/// } +/// ``` +/// +/// More details on the functionality shown can be seen at the [`IntoIterator`] docs. +/// +/// For more information on for-loops, see the [Rust book] or the [Reference]. +/// +/// [`impl`]: keyword.impl.html +/// [`IntoIterator`]: iter/trait.IntoIterator.html +/// [Rust book]: +/// https://doc.rust-lang.org/book/2018-edition/ch03-05-control-flow.html#looping-through-a-collection-with-for +/// [Reference]: https://doc.rust-lang.org/reference/expressions/loop-expr.html#iterator-loops +mod for_keyword { } + +#[doc(keyword = "if")] +// +/// If statements and expressions. +/// +/// `if` is a familiar construct to most programmers, and is the main way you'll often do logic in +/// your code. However, unlike in most languages, `if` blocks can also act as expressions. +/// +/// ```rust +/// # let rude = true; +/// if 1 == 2 { +/// println!("whoops, mathematics broke"); +/// } else { +/// println!("everything's fine!"); +/// } +/// +/// let greeting = if rude { +/// "sup nerd." +/// } else { +/// "hello, friend!" +/// }; +/// +/// if let Ok(x) = "123".parse::() { +/// println!("{} double that and you get {}!", greeting, x * 2); +/// } +/// ``` +/// +/// Shown above are the three typical forms an `if` block comes in. First is the usual kind of +/// thing you'd see in many languages, with an optional `else` block. Second uses `if` as an +/// expression, which is only possible if all branches return the same type. An `if` expression can +/// be used everywhere you'd expect. The third kind of `if` block is an `if let` block, which +/// behaves similarly to using a `match` expression: +/// +/// ```rust +/// if let Some(x) = Some(123) { +/// // code +/// # let _ = x; +/// } else { +/// // something else +/// } +/// +/// match Some(123) { +/// Some(x) => { +/// // code +/// # let _ = x; +/// }, +/// _ => { +/// // something else +/// }, +/// } +/// ``` +/// +/// Each kind of `if` expression can be mixed and matched as needed. +/// +/// ```rust +/// if true == false { +/// println!("oh no"); +/// } else if "something" == "other thing" { +/// println!("oh dear"); +/// } else if let Some(200) = "blarg".parse::().ok() { +/// println!("uh oh"); +/// } else { +/// println!("phew, nothing's broken"); +/// } +/// ``` +/// +/// The `if` keyword is used in one other place in Rust, namely as a part of pattern matching +/// itself, allowing patterns such as `Some(x) if x > 200` to be used. +/// +/// For more information on `if` expressions, see the [Rust book] or the [Reference]. +/// +/// [Rust book]: +/// https://doc.rust-lang.org/stable/book/2018-edition/ch03-05-control-flow.html#if-expressions +/// [Reference]: https://doc.rust-lang.org/reference/expressions/if-expr.html +mod if_keyword { } + +#[doc(keyword = "impl")] +// +/// The implementation-defining keyword. +/// +/// The `impl` keyword is primarily used to define implementations on types. Inherent +/// implementations are standalone, while trait implementations are used to implement traits for +/// types, or other traits. +/// +/// Functions and consts can both be defined in an implementation. A function defined in an +/// `impl` block can be standalone, meaning it would be called like `Foo::bar()`. If the function +/// takes `self`, `&self`, or `&mut self` as its first argument, it can also be called using +/// method-call syntax, a familiar feature to any object oriented programmer, like `foo.bar()`. +/// +/// ```rust +/// struct Example { +/// number: i32, +/// } +/// +/// impl Example { +/// fn boo() { +/// println!("boo! Example::boo() was called!"); +/// } +/// +/// fn answer(&mut self) { +/// self.number += 42; +/// } +/// +/// fn get_number(&self) -> i32 { +/// self.number +/// } +/// } +/// +/// trait Thingy { +/// fn do_thingy(&self); +/// } +/// +/// impl Thingy for Example { +/// fn do_thingy(&self) { +/// println!("doing a thing! also, number is {}!", self.number); +/// } +/// } /// ``` /// -/// By default, all variables are **not** mutable. If you want a mutable variable, -/// you'll have to use the `mut` keyword. +/// For more information on implementations, see the [Rust book][book1] or the [Reference]. /// -/// Example: +/// The other use of the `impl` keyword is in `impl Trait` syntax, which can be seen as a shorthand +/// for "a concrete type that implements this trait". Its primary use is working with closures, +/// which have type definitions generated at compile time that can't be simply typed out. +/// +/// ```rust +/// fn thing_returning_closure() -> impl Fn(i32) -> bool { +/// println!("here's a closure for you!"); +/// |x: i32| x % 3 == 0 +/// } +/// ``` +/// +/// For more information on `impl Trait` syntax, see the [Rust book][book2]. +/// +/// [book1]: https://doc.rust-lang.org/stable/book/2018-edition/ch05-03-method-syntax.html +/// [Reference]: https://doc.rust-lang.org/reference/items/implementations.html +/// [book2]: +/// https://doc.rust-lang.org/stable/book/2018-edition/ch10-02-traits.html#returning-traits +mod impl_keyword { } + +#[doc(keyword = "let")] +// +/// The variable binding keyword. +/// +/// The primary use for the `let` keyword is in `let` statements, which are used to introduce a new +/// set of variables into the current scope, as given by a pattern. /// /// ```rust /// # #![allow(unused_assignments)] -/// let mut x = 3; // We create a mutable variable named `x` with the value `3`. +/// let thing1: i32 = 100; +/// let thing2 = 200 + thing1; +/// +/// let mut changing_thing = true; +/// changing_thing = false; /// -/// x += 4; // `x` is now equal to `7`. +/// let (part1, part2) = ("first", "second"); +/// +/// struct Example { +/// a: bool, +/// b: u64, +/// } +/// +/// let Example { a, b: _ } = Example { +/// a: true, +/// b: 10004, +/// }; +/// assert!(a); +/// ``` +/// +/// The pattern is most commonly a single variable, which means no pattern matching is done and +/// the expression given is bound to the variable. Apart from that, patterns used in `let` bindings +/// can be as complicated as needed, given that the pattern is exhaustive. See the [Rust +/// book][book1] for more information on pattern matching. The type of the pattern is optionally +/// given afterwards, but if left blank is automatically inferred by the compiler if possible. +/// +/// Variables in Rust are immutable by default, and require the `mut` keyword to be made mutable. +/// +/// Multiple variables can be defined with the same name, known as shadowing. This doesn't affect +/// the original variable in any way beyond being unable to directly access it beyond the point of +/// shadowing. It continues to remain in scope, getting dropped only when it falls out of scope. +/// Shadowed variables don't need to have the same type as the variables shadowing them. +/// +/// ```rust +/// let shadowing_example = true; +/// let shadowing_example = 123.4; +/// let shadowing_example = shadowing_example as u32; +/// let mut shadowing_example = format!("cool! {}", shadowing_example); +/// shadowing_example += " something else!"; // not shadowing /// ``` /// -/// For more information about the `let` keyword, take a look at the [Rust Book][book]. +/// Other places the `let` keyword is used include along with [`if`], in the form of `if let` +/// expressions. They're useful if the pattern being matched isn't exhaustive, such as with +/// enumerations. `while let` also exists, which runs a loop with a pattern matched value until +/// that pattern can't be matched. /// -/// [book]: https://doc.rust-lang.org/book/second-edition/ch03-01-variables-and-mutability.html +/// For more information on the `let` keyword, see the [Rust book] or the [Reference] +/// +/// [book1]: https://doc.rust-lang.org/stable/book/2018-edition/ch06-02-match.html +/// [`if`]: keyword.if.html +/// [book2]: +/// https://doc.rust-lang.org/stable/book/2018-edition/ch18-01-all-the-places-for-patterns.html#let-statements +/// [Reference]: https://doc.rust-lang.org/reference/statements.html#let-statements mod let_keyword { } -#[doc(keyword = "struct")] +#[doc(keyword = "loop")] // -/// The `struct` keyword. +/// The loop-defining keyword. /// -/// The `struct` keyword is used to define a struct type. +/// `loop` is used to define the simplest kind of loop supported in Rust. It runs the code inside +/// it until the code uses `break` or the program exits. /// -/// Example: +/// ```rust +/// loop { +/// println!("hello world forever!"); +/// # break; +/// } /// +/// let mut i = 0; +/// loop { +/// println!("i is {}", i); +/// if i > 10 { +/// break; +/// } +/// i += 1; +/// } /// ``` -/// struct Foo { -/// field1: u32, +/// +/// Unlike the other kinds of loops in Rust (`while`, `while let`, and `for`), loops can be used as +/// expressions that return values via `break`. +/// +/// ```rust +/// let mut i = 1; +/// let something = loop { +/// i *= 2; +/// if i > 100 { +/// break i; +/// } +/// }; +/// assert_eq!(something, 128); +/// ``` +/// +/// Every `break` in a loop has to have the same type. When it's not explicitly giving something, +/// `break;` returns `()`. +/// +/// For more information on `loop` and loops in general, see the [Reference]. +/// +/// [Reference]: https://doc.rust-lang.org/reference/expressions/loop-expr.html +mod loop_keyword { } + +#[doc(keyword = "struct")] +// +/// The keyword used to define structs. +/// +/// Structs in Rust come in three flavours: Structs with named fields, tuple structs, and unit +/// structs. +/// +/// ```rust +/// struct Regular { +/// field1: f32, /// field2: String, +/// pub field3: bool +/// } +/// +/// struct Tuple(u32, String); +/// +/// struct Unit; +/// ``` +/// +/// Regular structs are the most commonly used. Each field defined within them has a name and a +/// type, and once defined can be accessed using `example_struct.field` syntax. The fields of a +/// struct share its mutability, so `foo.bar = 2;` would only be valid if `foo` was mutable. Adding +/// `pub` to a field makes it visible to code in other modules, as well as allowing it to be +/// directly accessed and modified. +/// +/// Tuple structs are similar to regular structs, but its fields have no names. They are used like +/// tuples, with deconstruction possible via `let TupleStruct(x, y) = foo;` syntax. For accessing +/// individual variables, the same syntax is used as with regular tuples, namely `foo.0`, `foo.1`, +/// etc, starting at zero. +/// +/// Unit structs are most commonly used as marker. They have a size of zero bytes, but unlike empty +/// enums they can be instantiated, making them isomorphic to the unit type `()`. Unit structs are +/// useful when you need to implement a trait on something, but don't need to store any data inside +/// it. +/// +/// # Instantiation +/// +/// Structs can be instantiated in different ways, all of which can be mixed and +/// matched as needed. The most common way to make a new struct is via a constructor method such as +/// `new()`, but when that isn't available (or you're writing the constructor itself), struct +/// literal syntax is used: +/// +/// ```rust +/// # struct Foo { field1: f32, field2: String, etc: bool } +/// let example = Foo { +/// field1: 42.0, +/// field2: "blah".to_string(), +/// etc: true, +/// }; +/// ``` +/// +/// It's only possible to directly instantiate a struct using struct literal syntax when all of its +/// fields are visible to you. +/// +/// There are a handful of shortcuts provided to make writing constructors more convenient, most +/// common of which is the Field Init shorthand. When there is a variable and a field of the same +/// name, the assignment can be simplified from `field: field` into simply `field`. The following +/// example of a hypothetical constructor demonstrates this: +/// +/// ```rust +/// struct User { +/// name: String, +/// admin: bool, +/// } +/// +/// impl User { +/// pub fn new(name: String) -> Self { +/// Self { +/// name, +/// admin: false, +/// } +/// } /// } /// ``` /// -/// There are different kinds of structs. For more information, take a look at the -/// [Rust Book][book]. +/// Another shortcut for struct instantiation is available, used when you need to make a new +/// struct that has the same values as most of a previous struct of the same type, called struct +/// update syntax: +/// +/// ```rust +/// # struct Foo { field1: String, field2: () } +/// # let thing = Foo { field1: "".to_string(), field2: () }; +/// let updated_thing = Foo { +/// field1: "a new value".to_string(), +/// ..thing +/// }; +/// ``` +/// +/// Tuple structs are instantiated in the same way as tuples themselves, except with the struct's +/// name as a prefix: `Foo(123, false, 0.1)`. +/// +/// Empty structs are instantiated with just their name, and don't need anything else. `let thing = +/// EmptyStruct;` +/// +/// # Style conventions +/// +/// Structs are always written in CamelCase, with few exceptions. While the trailing comma on a +/// struct's list of fields can be omitted, it's usually kept for convenience in adding and +/// removing fields down the line. +/// +/// For more information on structs, take a look at the [Rust Book][book] or the +/// [Reference][reference]. /// +/// [`PhantomData`]: marker/struct.PhantomData.html /// [book]: https://doc.rust-lang.org/book/second-edition/ch05-01-defining-structs.html +/// [reference]: https://doc.rust-lang.org/reference/items/structs.html mod struct_keyword { } 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/process.rs b/src/libstd/process.rs index 58ac4e944087e..a9219f75362db 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -1016,6 +1016,28 @@ impl fmt::Debug for Stdio { #[stable(feature = "stdio_from", since = "1.20.0")] impl From for Stdio { + /// Converts a `ChildStdin` into a `Stdio` + /// + /// # Examples + /// + /// `ChildStdin` will be converted to `Stdio` using `Stdio::from` under the hood. + /// + /// ```rust + /// use std::process::{Command, Stdio}; + /// + /// let reverse = Command::new("rev") + /// .stdin(Stdio::piped()) + /// .spawn() + /// .expect("failed reverse command"); + /// + /// let _echo = Command::new("echo") + /// .arg("Hello, world!") + /// .stdout(reverse.stdin.unwrap()) // Converted into a Stdio here + /// .output() + /// .expect("failed echo command"); + /// + /// // "!dlrow ,olleH" echoed to console + /// ``` fn from(child: ChildStdin) -> Stdio { Stdio::from_inner(child.into_inner().into()) } @@ -1023,6 +1045,28 @@ impl From for Stdio { #[stable(feature = "stdio_from", since = "1.20.0")] impl From for Stdio { + /// Converts a `ChildStdout` into a `Stdio` + /// + /// # Examples + /// + /// `ChildStdout` will be converted to `Stdio` using `Stdio::from` under the hood. + /// + /// ```rust + /// use std::process::{Command, Stdio}; + /// + /// let hello = Command::new("echo") + /// .arg("Hello, world!") + /// .stdout(Stdio::piped()) + /// .spawn() + /// .expect("failed echo command"); + /// + /// let reverse = Command::new("rev") + /// .stdin(hello.stdout.unwrap()) // Converted into a Stdio here + /// .output() + /// .expect("failed reverse command"); + /// + /// assert_eq!(reverse.stdout, b"!dlrow ,olleH\n"); + /// ``` fn from(child: ChildStdout) -> Stdio { Stdio::from_inner(child.into_inner().into()) } @@ -1030,6 +1074,30 @@ impl From for Stdio { #[stable(feature = "stdio_from", since = "1.20.0")] impl From for Stdio { + /// Converts a `ChildStderr` into a `Stdio` + /// + /// # Examples + /// + /// ```rust,no_run + /// use std::process::{Command, Stdio}; + /// + /// let reverse = Command::new("rev") + /// .arg("non_existing_file.txt") + /// .stderr(Stdio::piped()) + /// .spawn() + /// .expect("failed reverse command"); + /// + /// let cat = Command::new("cat") + /// .arg("-") + /// .stdin(reverse.stderr.unwrap()) // Converted into a Stdio here + /// .output() + /// .expect("failed echo command"); + /// + /// assert_eq!( + /// String::from_utf8_lossy(&cat.stdout), + /// "rev: cannot open non_existing_file.txt: No such file or directory\n" + /// ); + /// ``` fn from(child: ChildStderr) -> Stdio { Stdio::from_inner(child.into_inner().into()) } @@ -1037,6 +1105,26 @@ impl From for Stdio { #[stable(feature = "stdio_from", since = "1.20.0")] impl From for Stdio { + /// Converts a `File` into a `Stdio` + /// + /// # Examples + /// + /// `File` will be converted to `Stdio` using `Stdio::from` under the hood. + /// + /// ```rust,no_run + /// use std::fs::File; + /// use std::process::Command; + /// + /// // With the `foo.txt` file containing `Hello, world!" + /// let file = File::open("foo.txt").unwrap(); + /// + /// let reverse = Command::new("rev") + /// .stdin(file) // Implicit File convertion into a Stdio + /// .output() + /// .expect("failed reverse command"); + /// + /// assert_eq!(reverse.stdout, b"!dlrow ,olleH"); + /// ``` fn from(file: fs::File) -> Stdio { Stdio::from_inner(file.into_inner().into()) } 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/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 87ade278c685a..805aa9bef227d 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -905,7 +905,8 @@ fn is_in_follow(tok: "ed::TokenTree, frag: &str) -> Result match *tok { TokenTree::Token(_, ref tok) => match *tok { OpenDelim(token::DelimToken::Brace) | OpenDelim(token::DelimToken::Bracket) | - Comma | FatArrow | Colon | Eq | Gt | Semi | BinOp(token::Or) => Ok(true), + Comma | FatArrow | Colon | Eq | Gt | BinOp(token::Shr) | Semi | + BinOp(token::Or) => Ok(true), Ident(i, false) if i.name == "as" || i.name == "where" => Ok(true), _ => Ok(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/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/run-pass/macros/issue-25274.rs b/src/test/run-pass/macros/issue-25274.rs new file mode 100644 index 0000000000000..e81b2c7a7233b --- /dev/null +++ b/src/test/run-pass/macros/issue-25274.rs @@ -0,0 +1,16 @@ +macro_rules! test { + ( + fn fun() -> Option>; + ) => { + fn fun(x: $t) -> Option> + { Some(Box::new(x)) } + } +} + +test! { + fn fun() -> Option>; +} + +fn main() { + println!("{}", fun(0).unwrap()); +} diff --git a/src/test/rustdoc-ui/failed-doctest-output.rs b/src/test/rustdoc-ui/failed-doctest-output.rs index 62e495288cb9b..932fe1c8eb0b2 100644 --- a/src/test/rustdoc-ui/failed-doctest-output.rs +++ b/src/test/rustdoc-ui/failed-doctest-output.rs @@ -15,6 +15,7 @@ // compile-flags:--test // normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR" // failure-status: 101 +// rustc-env:RUST_BACKTRACE=0 // doctest fails at runtime /// ``` diff --git a/src/test/rustdoc-ui/failed-doctest-output.stdout b/src/test/rustdoc-ui/failed-doctest-output.stdout index cf417f8d412ee..876f6c0a80b1d 100644 --- a/src/test/rustdoc-ui/failed-doctest-output.stdout +++ b/src/test/rustdoc-ui/failed-doctest-output.stdout @@ -1,22 +1,22 @@ running 2 tests -test $DIR/failed-doctest-output.rs - OtherStruct (line 26) ... FAILED -test $DIR/failed-doctest-output.rs - SomeStruct (line 20) ... FAILED +test $DIR/failed-doctest-output.rs - OtherStruct (line 27) ... FAILED +test $DIR/failed-doctest-output.rs - SomeStruct (line 21) ... FAILED failures: ----- $DIR/failed-doctest-output.rs - OtherStruct (line 26) stdout ---- +---- $DIR/failed-doctest-output.rs - OtherStruct (line 27) stdout ---- error[E0425]: cannot find value `no` in this scope - --> $DIR/failed-doctest-output.rs:27:1 + --> $DIR/failed-doctest-output.rs:28:1 | 3 | no | ^^ not found in this scope -thread '$DIR/failed-doctest-output.rs - OtherStruct (line 26)' panicked at 'couldn't compile the test', librustdoc/test.rs:332:13 +thread '$DIR/failed-doctest-output.rs - OtherStruct (line 27)' panicked at 'couldn't compile the test', librustdoc/test.rs:332:13 note: Run with `RUST_BACKTRACE=1` for a backtrace. ----- $DIR/failed-doctest-output.rs - SomeStruct (line 20) stdout ---- -thread '$DIR/failed-doctest-output.rs - SomeStruct (line 20)' panicked at 'test executable failed: +---- $DIR/failed-doctest-output.rs - SomeStruct (line 21) stdout ---- +thread '$DIR/failed-doctest-output.rs - SomeStruct (line 21)' panicked at 'test executable failed: thread 'main' panicked at 'oh no', $DIR/failed-doctest-output.rs:3:1 note: Run with `RUST_BACKTRACE=1` for a backtrace. @@ -25,8 +25,8 @@ note: Run with `RUST_BACKTRACE=1` for a backtrace. failures: - $DIR/failed-doctest-output.rs - OtherStruct (line 26) - $DIR/failed-doctest-output.rs - SomeStruct (line 20) + $DIR/failed-doctest-output.rs - OtherStruct (line 27) + $DIR/failed-doctest-output.rs - SomeStruct (line 21) test result: FAILED. 0 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out diff --git a/src/test/rustdoc/issue-54478-demo-allocator.rs b/src/test/rustdoc/issue-54478-demo-allocator.rs new file mode 100644 index 0000000000000..4811f363bc97a --- /dev/null +++ b/src/test/rustdoc/issue-54478-demo-allocator.rs @@ -0,0 +1,42 @@ +// Issue #54478: regression test showing that we can demonstrate +// `#[global_allocator]` in code blocks built by `rustdoc`. +// +// ## Background +// +// Changes in lang-item visibility injected failures that were only +// exposed when compiling with `-C prefer-dynamic`. But `rustdoc` used +// `-C prefer-dynamic` (and had done so for years, for reasons we did +// not document at that time). +// +// Rather than try to revise the visbility semanics, we instead +// decided to change `rustdoc` to behave more like the compiler's +// default setting, by leaving off `-C prefer-dynamic`. + +// compile-flags:--test + +//! This is a doc comment +//! +//! ```rust +//! use std::alloc::*; +//! +//! #[global_allocator] +//! static ALLOC: A = A; +//! +//! static mut HIT: bool = false; +//! +//! struct A; +//! +//! unsafe impl GlobalAlloc for A { +//! unsafe fn alloc(&self, layout: Layout) -> *mut u8 { +//! HIT = true; +//! System.alloc(layout) +//! } +//! unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { +//! System.dealloc(ptr, layout); +//! } +//! } +//! +//! fn main() { +//! assert!(unsafe { HIT }); +//! } +//! ``` 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/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/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-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/lint/suggestions.rs b/src/test/ui/lint/suggestions.rs index ff50b3b1ab68f..77d546a00ecd4 100644 --- a/src/test/ui/lint/suggestions.rs +++ b/src/test/ui/lint/suggestions.rs @@ -56,7 +56,7 @@ fn main() { while true { //~^ WARN denote infinite loops //~| HELP use `loop` - let mut a = (1); + let mut registry_no = (format!("NX-{}", 74205)); //~^ WARN does not need to be mutable //~| HELP remove this `mut` //~| WARN unnecessary parentheses @@ -72,6 +72,6 @@ fn main() { //~^ WARN this pattern is redundant //~| HELP remove this } - println!("{} {}", a, b); + println!("{} {}", registry_no, b); } } diff --git a/src/test/ui/lint/suggestions.stderr b/src/test/ui/lint/suggestions.stderr index 340a4a48512e2..73704614815be 100644 --- a/src/test/ui/lint/suggestions.stderr +++ b/src/test/ui/lint/suggestions.stderr @@ -1,8 +1,8 @@ warning: unnecessary parentheses around assigned value - --> $DIR/suggestions.rs:59:21 + --> $DIR/suggestions.rs:59:31 | -LL | let mut a = (1); - | ^^^ help: remove these parentheses +LL | let mut registry_no = (format!("NX-{}", 74205)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove these parentheses | note: lint level defined here --> $DIR/suggestions.rs:13:21 @@ -21,8 +21,8 @@ LL | #[no_debug] // should suggest removal of deprecated attribute warning: variable does not need to be mutable --> $DIR/suggestions.rs:59:13 | -LL | let mut a = (1); - | ----^ +LL | let mut registry_no = (format!("NX-{}", 74205)); + | ----^^^^^^^^^^^ | | | help: remove this `mut` | 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/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/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 {