about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-08-18 00:12:59 +0000
committerbors <bors@rust-lang.org>2023-08-18 00:12:59 +0000
commit9b4119009eb99d4087042032ad93ac892a63aa4a (patch)
treeed91080d4f4bb09301d8690fb697d786b2e109ea
parentccc3ac0cae0d901a360c4f93f6d41d87ed459d20 (diff)
parentdf877c03532aa0cb9d82bbf0321246498b7eff45 (diff)
downloadrust-9b4119009eb99d4087042032ad93ac892a63aa4a.tar.gz
rust-9b4119009eb99d4087042032ad93ac892a63aa4a.zip
Auto merge of #114951 - cuviper:rollup-iitoep5, r=cuviper
Rollup of 5 pull requests

Successful merges:

 - #113715 (Unstable Book: update `lang_items` page and split it)
 - #114897 (Partially revert #107200)
 - #114913 (Fix suggestion for attempting to define a string with single quotes)
 - #114931 (Revert PR #114052 to fix invalid suggestion)
 - #114944 (update `thiserror` to version >= 1.0.46)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--Cargo.lock8
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0132.md2
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0152.md4
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/errors.rs29
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs11
-rw-r--r--compiler/rustc_parse/src/lexer/unescape_error_reporting.rs22
-rw-r--r--library/std/src/io/mod.rs6
-rw-r--r--src/doc/unstable-book/src/language-features/lang-items.md311
-rw-r--r--src/doc/unstable-book/src/language-features/start.md59
-rw-r--r--tests/ui/associated-types/dont-suggest-cyclic-constraint.fixed13
-rw-r--r--tests/ui/associated-types/dont-suggest-cyclic-constraint.rs2
-rw-r--r--tests/ui/associated-types/dont-suggest-cyclic-constraint.stderr6
-rw-r--r--tests/ui/inference/str-as-char.fixed1
-rw-r--r--tests/ui/inference/str-as-char.rs1
-rw-r--r--tests/ui/inference/str-as-char.stderr13
-rw-r--r--tests/ui/suggestions/copied-and-cloned.fixed18
-rw-r--r--tests/ui/suggestions/copied-and-cloned.rs16
-rw-r--r--tests/ui/suggestions/copied-and-cloned.stderr37
19 files changed, 223 insertions, 338 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 8d707067bb9..47d6b3c44a8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5126,9 +5126,9 @@ checksum = "aac81b6fd6beb5884b0cf3321b8117e6e5d47ecb6fc89f414cfdcca8b2fe2dd8"
 
 [[package]]
 name = "thiserror"
-version = "1.0.40"
+version = "1.0.47"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
+checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f"
 dependencies = [
  "thiserror-impl",
 ]
@@ -5155,9 +5155,9 @@ dependencies = [
 
 [[package]]
 name = "thiserror-impl"
-version = "1.0.40"
+version = "1.0.47"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
+checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b"
 dependencies = [
  "proc-macro2",
  "quote",
diff --git a/compiler/rustc_error_codes/src/error_codes/E0132.md b/compiler/rustc_error_codes/src/error_codes/E0132.md
index a23cc988bdb..51258739b89 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0132.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0132.md
@@ -13,7 +13,7 @@ It is not possible to declare type parameters on a function that has the `start`
 attribute. Such a function must have the following type signature (for more
 information, view [the unstable book][1]):
 
-[1]: https://doc.rust-lang.org/unstable-book/language-features/lang-items.html#writing-an-executable-without-stdlib
+[1]: https://doc.rust-lang.org/unstable-book/language-features/start.html
 
 ```
 # let _:
diff --git a/compiler/rustc_error_codes/src/error_codes/E0152.md b/compiler/rustc_error_codes/src/error_codes/E0152.md
index ef17b8b4c75..d862766571d 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0152.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0152.md
@@ -20,6 +20,6 @@ attributes:
 #![no_std]
 ```
 
-See also the [unstable book][1].
+See also [this section of the Rustonomicon][beneath std].
 
-[1]: https://doc.rust-lang.org/unstable-book/language-features/lang-items.html#writing-an-executable-without-stdlib
+[beneath std]: https://doc.rust-lang.org/nomicon/beneath-std.html
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index 5b06088c348..6aeabc1bebb 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -53,7 +53,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             || self.suggest_no_capture_closure(err, expected, expr_ty)
             || self.suggest_boxing_when_appropriate(err, expr.span, expr.hir_id, expected, expr_ty)
             || self.suggest_block_to_brackets_peeling_refs(err, expr, expr_ty, expected)
-            || self.suggest_copied_cloned_or_as_ref(err, expr, expr_ty, expected, expected_ty_expr)
+            || self.suggest_copied_cloned_or_as_ref(err, expr, expr_ty, expected)
             || self.suggest_clone_for_ref(err, expr, expr_ty, expected)
             || self.suggest_into(err, expr, expr_ty, expected)
             || self.suggest_floating_point_literal(err, expr, expected)
diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs
index 36096aa35d4..054d23c71d4 100644
--- a/compiler/rustc_hir_typeck/src/errors.rs
+++ b/compiler/rustc_hir_typeck/src/errors.rs
@@ -253,7 +253,7 @@ impl HelpUseLatestEdition {
 }
 
 #[derive(Subdiagnostic)]
-pub enum OptionResultRefMismatch<'tcx> {
+pub enum OptionResultRefMismatch {
     #[suggestion(
         hir_typeck_option_result_copied,
         code = ".copied()",
@@ -276,19 +276,20 @@ pub enum OptionResultRefMismatch<'tcx> {
         span: Span,
         def_path: String,
     },
-    #[suggestion(
-        hir_typeck_option_result_asref,
-        code = ".as_ref()",
-        style = "verbose",
-        applicability = "machine-applicable"
-    )]
-    AsRef {
-        #[primary_span]
-        span: Span,
-        def_path: String,
-        expected_ty: Ty<'tcx>,
-        expr_ty: Ty<'tcx>,
-    },
+    // FIXME: #114050
+    // #[suggestion(
+    //     hir_typeck_option_result_asref,
+    //     code = ".as_ref()",
+    //     style = "verbose",
+    //     applicability = "machine-applicable"
+    // )]
+    // AsRef {
+    //     #[primary_span]
+    //     span: Span,
+    //     def_path: String,
+    //     expected_ty: Ty<'tcx>,
+    //     expr_ty: Ty<'tcx>,
+    // },
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 48358e338da..d2a53ee8b5e 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -1097,7 +1097,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expr: &hir::Expr<'_>,
         expr_ty: Ty<'tcx>,
         expected_ty: Ty<'tcx>,
-        expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
     ) -> bool {
         let ty::Adt(adt_def, args) = expr_ty.kind() else {
             return false;
@@ -1115,7 +1114,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         {
             let expr_inner_ty = args.type_at(0);
             let expected_inner_ty = expected_args.type_at(0);
-            if let &ty::Ref(_, ty, mutability) = expr_inner_ty.kind()
+            if let &ty::Ref(_, ty, _mutability) = expr_inner_ty.kind()
                     && self.can_eq(self.param_env, ty, expected_inner_ty)
                 {
                     let def_path = self.tcx.def_path_str(adt_def.did());
@@ -1124,14 +1123,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         errors::OptionResultRefMismatch::Copied {
                             span, def_path
                         }
-                    } else if let Some(expected_ty_expr) = expected_ty_expr
-                            // FIXME: suggest changes to both expressions to convert both to
-                            // Option/Result<&T>
-                            && mutability.is_not()
-                        {
-                        errors::OptionResultRefMismatch::AsRef {
-                            span: expected_ty_expr.span.shrink_to_hi(), expected_ty, expr_ty, def_path
-                        }
                     } else if let Some(clone_did) = self.tcx.lang_items().clone_trait()
                         && rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions(
                             self,
diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
index 446472d1294..b659c40b233 100644
--- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
+++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
@@ -80,20 +80,14 @@ pub(crate) fn emit_unescape_error(
             let sugg = sugg.unwrap_or_else(|| {
                 let prefix = mode.prefix_noraw();
                 let mut escaped = String::with_capacity(lit.len());
-                let mut chrs = lit.chars().peekable();
-                while let Some(first) = chrs.next() {
-                    match (first, chrs.peek()) {
-                        ('\\', Some('"')) => {
-                            escaped.push('\\');
-                            escaped.push('"');
-                            chrs.next();
-                        }
-                        ('"', _) => {
-                            escaped.push('\\');
-                            escaped.push('"')
-                        }
-                        (c, _) => escaped.push(c),
-                    };
+                let mut in_escape = false;
+                for c in lit.chars() {
+                    match c {
+                        '\\' => in_escape = !in_escape,
+                        '"' if !in_escape => escaped.push('\\'),
+                        _ => in_escape = false,
+                    }
+                    escaped.push(c);
                 }
                 let sugg = format!("{prefix}\"{escaped}\"");
                 MoreThanOneCharSugg::Quotes {
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 5c1d2d8f46c..71d91f21362 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -1425,9 +1425,9 @@ pub trait Write {
     ///
     /// If this method consumed `n > 0` bytes of `buf` it must return [`Ok(n)`].
     /// If the return value is `Ok(n)` then `n` must satisfy `n <= buf.len()`.
-    /// Unless `buf` is empty, this function shouldn’t return `Ok(0)` since the
-    /// caller may interpret that as an error.  To indicate lack of space,
-    /// implementors should return [`ErrorKind::StorageFull`] error instead.
+    /// A return value of `Ok(0)` typically means that the underlying object is
+    /// no longer able to accept bytes and will likely not be able to in the
+    /// future as well, or that the buffer provided is empty.
     ///
     /// # Errors
     ///
diff --git a/src/doc/unstable-book/src/language-features/lang-items.md b/src/doc/unstable-book/src/language-features/lang-items.md
index 1f3d472c3aa..9e20662fff3 100644
--- a/src/doc/unstable-book/src/language-features/lang-items.md
+++ b/src/doc/unstable-book/src/language-features/lang-items.md
@@ -9,26 +9,60 @@ functionality that isn't hard-coded into the language, but is
 implemented in libraries, with a special marker to tell the compiler
 it exists. The marker is the attribute `#[lang = "..."]` and there are
 various different values of `...`, i.e. various different 'lang
-items'.
+items'. Most of them can only be defined once.
 
-For example, `Box` pointers require a lang item for allocation.
-A freestanding program that uses the `Box`
-sugar for dynamic allocations via `malloc` and `free`:
+Lang items are loaded lazily by the compiler; e.g. if one never uses `Box`
+then there is no need to define a function for `exchange_malloc`.
+`rustc` will emit an error when an item is needed but not found in the current
+crate or any that it depends on.
+
+Some features provided by lang items:
+
+- overloadable operators via traits: the traits corresponding to the
+  `==`, `<`, dereferencing (`*`) and `+` (etc.) operators are all
+  marked with lang items; those specific four are `eq`, `partial_ord`,
+  `deref`/`deref_mut`, and `add` respectively.
+- panicking: the `panic` and `panic_impl` lang items, among others.
+- stack unwinding: the lang item `eh_personality` is a function used by the
+  failure mechanisms of the compiler. This is often mapped to GCC's personality
+  function (see the [`std` implementation][personality] for more information),
+  but programs which don't trigger a panic can be assured that this function is
+  never called. Additionally, a `eh_catch_typeinfo` static is needed for certain
+  targets which implement Rust panics on top of C++ exceptions.
+- the traits in `core::marker` used to indicate types of
+  various kinds; e.g. lang items `sized`, `sync` and `copy`.
+- memory allocation, see below.
+
+Most lang items are defined by `core`, but if you're trying to build
+an executable without the `std` crate, you might run into the need
+for lang item definitions.
+
+[personality]: https://github.com/rust-lang/rust/blob/master/library/std/src/personality/gcc.rs
+
+## Example: Implementing a `Box`
+
+`Box` pointers require two lang items: one for the type itself and one for
+allocation. A freestanding program that uses the `Box` sugar for dynamic
+allocations via `malloc` and `free`:
 
 ```rust,ignore (libc-is-finicky)
-#![feature(lang_items, start, libc, core_intrinsics, rustc_private, rustc_attrs)]
+#![feature(lang_items, start, core_intrinsics, rustc_private, panic_unwind, rustc_attrs)]
 #![allow(internal_features)]
 #![no_std]
+
+extern crate libc;
+extern crate unwind;
+
+use core::ffi::c_void;
 use core::intrinsics;
 use core::panic::PanicInfo;
 use core::ptr::NonNull;
 
-extern crate libc;
-
+pub struct Global; // the global allocator
 struct Unique<T>(NonNull<T>);
 
 #[lang = "owned_box"]
-pub struct Box<T>(Unique<T>);
+pub struct Box<T, A = Global>(Unique<T>, A);
 
 impl<T> Box<T> {
     pub fn new(x: T) -> Self {
@@ -37,24 +71,26 @@ impl<T> Box<T> {
     }
 }
 
+impl<T, A> Drop for Box<T, A> {
+    fn drop(&mut self) {
+        unsafe {
+            libc::free(self.0.0.as_ptr() as *mut c_void);
+        }
+    }
+}
+
 #[lang = "exchange_malloc"]
 unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
-    let p = libc::malloc(size as libc::size_t) as *mut u8;
+    let p = libc::malloc(size) as *mut u8;
 
     // Check if `malloc` failed:
-    if p as usize == 0 {
+    if p.is_null() {
         intrinsics::abort();
     }
 
     p
 }
 
-impl<T> Drop for Box<T> {
-    fn drop(&mut self) {
-      libc::free(self.0.0.0 as *mut libc::c_void)
-    }
-}
-
 #[start]
 fn main(_argc: isize, _argv: *const *const u8) -> isize {
     let _x = Box::new(1);
@@ -62,247 +98,18 @@ fn main(_argc: isize, _argv: *const *const u8) -> isize {
     0
 }
 
-#[lang = "eh_personality"] extern fn rust_eh_personality() {}
-#[lang = "panic_impl"] extern fn rust_begin_panic(_info: &PanicInfo) -> ! { intrinsics::abort() }
-#[no_mangle] pub extern fn rust_eh_register_frames () {}
-#[no_mangle] pub extern fn rust_eh_unregister_frames () {}
-```
-
-Note the use of `abort`: the `exchange_malloc` lang item is assumed to
-return a valid pointer, and so needs to do the check internally.
-
-Other features provided by lang items include:
-
-- overloadable operators via traits: the traits corresponding to the
-  `==`, `<`, dereferencing (`*`) and `+` (etc.) operators are all
-  marked with lang items; those specific four are `eq`, `ord`,
-  `deref`, and `add` respectively.
-- stack unwinding and general failure; the `eh_personality`,
-  `panic` and `panic_bounds_check` lang items.
-- the traits in `std::marker` used to indicate types of
-  various kinds; lang items `send`, `sync` and `copy`.
-- the marker types and variance indicators found in
-  `std::marker`; lang items `covariant_type`,
-  `contravariant_lifetime`, etc.
-
-Lang items are loaded lazily by the compiler; e.g. if one never uses
-`Box` then there is no need to define a function for `exchange_malloc`.
-`rustc` will emit an error when an item is needed
-but not found in the current crate or any that it depends on.
-
-Most lang items are defined by `libcore`, but if you're trying to build
-an executable without the standard library, you'll run into the need
-for lang items. The rest of this page focuses on this use-case, even though
-lang items are a bit broader than that.
-
-### Using libc
-
-In order to build a `#[no_std]` executable we will need libc as a dependency.
-We can specify this using our `Cargo.toml` file:
-
-```toml
-[dependencies]
-libc = { version = "0.2.14", default-features = false }
-```
-
-Note that the default features have been disabled. This is a critical step -
-**the default features of libc include the standard library and so must be
-disabled.**
-
-### Writing an executable without stdlib
-
-Controlling the entry point is possible in two ways: the `#[start]` attribute,
-or overriding the default shim for the C `main` function with your own.
-
-The function marked `#[start]` is passed the command line parameters
-in the same format as C:
-
-```rust,ignore (libc-is-finicky)
-#![feature(lang_items, core_intrinsics, rustc_private)]
-#![feature(start)]
-#![allow(internal_features)]
-#![no_std]
-use core::intrinsics;
-use core::panic::PanicInfo;
-
-// Pull in the system libc library for what crt0.o likely requires.
-extern crate libc;
-
-// Entry point for this program.
-#[start]
-fn start(_argc: isize, _argv: *const *const u8) -> isize {
-    0
-}
-
-// These functions are used by the compiler, but not
-// for a bare-bones hello world. These are normally
-// provided by libstd.
-#[lang = "eh_personality"]
-#[no_mangle]
-pub extern fn rust_eh_personality() {
-}
-
-#[lang = "panic_impl"]
-#[no_mangle]
-pub extern fn rust_begin_panic(info: &PanicInfo) -> ! {
-    unsafe { intrinsics::abort() }
-}
-```
-
-To override the compiler-inserted `main` shim, one has to disable it
-with `#![no_main]` and then create the appropriate symbol with the
-correct ABI and the correct name, which requires overriding the
-compiler's name mangling too:
-
-```rust,ignore (libc-is-finicky)
-#![feature(lang_items, core_intrinsics, rustc_private)]
-#![feature(start)]
-#![allow(internal_features)]
-#![no_std]
-#![no_main]
-use core::intrinsics;
-use core::panic::PanicInfo;
-
-// Pull in the system libc library for what crt0.o likely requires.
-extern crate libc;
-
-// Entry point for this program.
-#[no_mangle] // ensure that this symbol is called `main` in the output
-pub extern fn main(_argc: i32, _argv: *const *const u8) -> i32 {
-    0
-}
-
-// These functions are used by the compiler, but not
-// for a bare-bones hello world. These are normally
-// provided by libstd.
 #[lang = "eh_personality"]
-#[no_mangle]
-pub extern fn rust_eh_personality() {
-}
+fn rust_eh_personality() {}
 
-#[lang = "panic_impl"]
-#[no_mangle]
-pub extern fn rust_begin_panic(info: &PanicInfo) -> ! {
-    unsafe { intrinsics::abort() }
-}
+#[panic_handler]
+fn panic_handler(_info: &PanicInfo) -> ! { intrinsics::abort() }
 ```
 
-In many cases, you may need to manually link to the `compiler_builtins` crate
-when building a `no_std` binary. You may observe this via linker error messages
-such as "```undefined reference to `__rust_probestack'```".
-
-## More about the language items
-
-The compiler currently makes a few assumptions about symbols which are
-available in the executable to call. Normally these functions are provided by
-the standard library, but without it you must define your own. These symbols
-are called "language items", and they each have an internal name, and then a
-signature that an implementation must conform to.
-
-The first of these functions, `rust_eh_personality`, is used by the failure
-mechanisms of the compiler. This is often mapped to GCC's personality function
-(see the [libstd implementation][unwind] for more information), but crates
-which do not trigger a panic can be assured that this function is never
-called. The language item's name is `eh_personality`.
-
-[unwind]: https://github.com/rust-lang/rust/blob/master/library/panic_unwind/src/gcc.rs
-
-The second function, `rust_begin_panic`, is also used by the failure mechanisms of the
-compiler. When a panic happens, this controls the message that's displayed on
-the screen. While the language item's name is `panic_impl`, the symbol name is
-`rust_begin_panic`.
-
-Finally, a `eh_catch_typeinfo` static is needed for certain targets which
-implement Rust panics on top of C++ exceptions.
+Note the use of `abort`: the `exchange_malloc` lang item is assumed to
+return a valid pointer, and so needs to do the check internally.
 
 ## List of all language items
 
-This is a list of all language items in Rust along with where they are located in
-the source code.
+An up-to-date list of all language items can be found [here] in the compiler code.
 
-- Primitives
-  - `i8`: `libcore/num/mod.rs`
-  - `i16`: `libcore/num/mod.rs`
-  - `i32`: `libcore/num/mod.rs`
-  - `i64`: `libcore/num/mod.rs`
-  - `i128`: `libcore/num/mod.rs`
-  - `isize`: `libcore/num/mod.rs`
-  - `u8`: `libcore/num/mod.rs`
-  - `u16`: `libcore/num/mod.rs`
-  - `u32`: `libcore/num/mod.rs`
-  - `u64`: `libcore/num/mod.rs`
-  - `u128`: `libcore/num/mod.rs`
-  - `usize`: `libcore/num/mod.rs`
-  - `f32`: `libstd/f32.rs`
-  - `f64`: `libstd/f64.rs`
-  - `char`: `libcore/char.rs`
-  - `slice`: `liballoc/slice.rs`
-  - `str`: `liballoc/str.rs`
-  - `const_ptr`: `libcore/ptr.rs`
-  - `mut_ptr`: `libcore/ptr.rs`
-  - `unsafe_cell`: `libcore/cell.rs`
-- Runtime
-  - `start`: `libstd/rt.rs`
-  - `eh_personality`: `libpanic_unwind/emcc.rs` (EMCC)
-  - `eh_personality`: `libpanic_unwind/gcc.rs` (GNU)
-  - `eh_personality`: `libpanic_unwind/seh.rs` (SEH)
-  - `eh_catch_typeinfo`: `libpanic_unwind/emcc.rs` (EMCC)
-  - `panic`: `libcore/panicking.rs`
-  - `panic_bounds_check`: `libcore/panicking.rs`
-  - `panic_impl`: `libcore/panicking.rs`
-  - `panic_impl`: `libstd/panicking.rs`
-- Allocations
-  - `owned_box`: `liballoc/boxed.rs`
-  - `exchange_malloc`: `liballoc/heap.rs`
-- Operands
-  - `not`: `libcore/ops/bit.rs`
-  - `bitand`: `libcore/ops/bit.rs`
-  - `bitor`: `libcore/ops/bit.rs`
-  - `bitxor`: `libcore/ops/bit.rs`
-  - `shl`: `libcore/ops/bit.rs`
-  - `shr`: `libcore/ops/bit.rs`
-  - `bitand_assign`: `libcore/ops/bit.rs`
-  - `bitor_assign`: `libcore/ops/bit.rs`
-  - `bitxor_assign`: `libcore/ops/bit.rs`
-  - `shl_assign`: `libcore/ops/bit.rs`
-  - `shr_assign`: `libcore/ops/bit.rs`
-  - `deref`: `libcore/ops/deref.rs`
-  - `deref_mut`: `libcore/ops/deref.rs`
-  - `index`: `libcore/ops/index.rs`
-  - `index_mut`: `libcore/ops/index.rs`
-  - `add`: `libcore/ops/arith.rs`
-  - `sub`: `libcore/ops/arith.rs`
-  - `mul`: `libcore/ops/arith.rs`
-  - `div`: `libcore/ops/arith.rs`
-  - `rem`: `libcore/ops/arith.rs`
-  - `neg`: `libcore/ops/arith.rs`
-  - `add_assign`: `libcore/ops/arith.rs`
-  - `sub_assign`: `libcore/ops/arith.rs`
-  - `mul_assign`: `libcore/ops/arith.rs`
-  - `div_assign`: `libcore/ops/arith.rs`
-  - `rem_assign`: `libcore/ops/arith.rs`
-  - `eq`: `libcore/cmp.rs`
-  - `ord`: `libcore/cmp.rs`
-- Functions
-  - `fn`: `libcore/ops/function.rs`
-  - `fn_mut`: `libcore/ops/function.rs`
-  - `fn_once`: `libcore/ops/function.rs`
-  - `generator_state`: `libcore/ops/generator.rs`
-  - `generator`: `libcore/ops/generator.rs`
-- Other
-  - `coerce_unsized`: `libcore/ops/unsize.rs`
-  - `drop`: `libcore/ops/drop.rs`
-  - `drop_in_place`: `libcore/ptr.rs`
-  - `clone`: `libcore/clone.rs`
-  - `copy`: `libcore/marker.rs`
-  - `send`: `libcore/marker.rs`
-  - `sized`: `libcore/marker.rs`
-  - `unsize`: `libcore/marker.rs`
-  - `sync`: `libcore/marker.rs`
-  - `phantom_data`: `libcore/marker.rs`
-  - `discriminant_kind`: `libcore/marker.rs`
-  - `freeze`: `libcore/marker.rs`
-  - `debug_trait`: `libcore/fmt/mod.rs`
-  - `non_zero`: `libcore/nonzero.rs`
-  - `arc`: `liballoc/sync.rs`
-  - `rc`: `liballoc/rc.rs`
+[here]: https://github.com/rust-lang/rust/blob/master/compiler/rustc_hir/src/lang_items.rs
diff --git a/src/doc/unstable-book/src/language-features/start.md b/src/doc/unstable-book/src/language-features/start.md
new file mode 100644
index 00000000000..09e4875a2e4
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/start.md
@@ -0,0 +1,59 @@
+# `start`
+
+The tracking issue for this feature is: [#29633]
+
+[#29633]: https://github.com/rust-lang/rust/issues/29633
+
+------------------------
+
+Allows you to mark a function as the entry point of the executable, which is
+necessary in `#![no_std]` environments.
+
+The function marked `#[start]` is passed the command line parameters in the same
+format as the C main function (aside from the integer types being used).
+It has to be non-generic and have the following signature:
+
+```rust,ignore (only-for-syntax-highlight)
+# let _:
+fn(isize, *const *const u8) -> isize
+# ;
+```
+
+This feature should not be confused with the `start` *lang item* which is
+defined by the `std` crate and is written `#[lang = "start"]`.
+
+## Usage together with the `std` crate
+
+`#[start]` can be used in combination with the `std` crate, in which case the
+normal `main` function (which would get called from the `std` crate) won't be
+used as an entry point.
+The initialization code in `std` will be skipped this way.
+
+Example:
+
+```rust
+#![feature(start)]
+
+#[start]
+fn start(_argc: isize, _argv: *const *const u8) -> isize {
+    0
+}
+```
+
+Unwinding the stack past the `#[start]` function is currently considered
+Undefined Behavior (for any unwinding implementation):
+
+```rust,ignore (UB)
+#![feature(start)]
+
+#[start]
+fn start(_argc: isize, _argv: *const *const u8) -> isize {
+    std::panic::catch_unwind(|| {
+        panic!(); // panic safely gets caught or safely aborts execution
+    });
+
+    panic!(); // UB!
+
+    0
+}
+```
diff --git a/tests/ui/associated-types/dont-suggest-cyclic-constraint.fixed b/tests/ui/associated-types/dont-suggest-cyclic-constraint.fixed
deleted file mode 100644
index ec4165cc71e..00000000000
--- a/tests/ui/associated-types/dont-suggest-cyclic-constraint.fixed
+++ /dev/null
@@ -1,13 +0,0 @@
-// run-rustfix
-
-use std::fmt::Debug;
-
-pub fn foo<I: Iterator>(mut iter: I, value: &I::Item)
-where
-    I::Item: Eq + Debug,
-{
-    debug_assert_eq!(iter.next().as_ref(), Some(value));
-    //~^ ERROR mismatched types
-}
-
-fn main() {}
diff --git a/tests/ui/associated-types/dont-suggest-cyclic-constraint.rs b/tests/ui/associated-types/dont-suggest-cyclic-constraint.rs
index 0b4df08783d..0848b4c559b 100644
--- a/tests/ui/associated-types/dont-suggest-cyclic-constraint.rs
+++ b/tests/ui/associated-types/dont-suggest-cyclic-constraint.rs
@@ -1,5 +1,3 @@
-// run-rustfix
-
 use std::fmt::Debug;
 
 pub fn foo<I: Iterator>(mut iter: I, value: &I::Item)
diff --git a/tests/ui/associated-types/dont-suggest-cyclic-constraint.stderr b/tests/ui/associated-types/dont-suggest-cyclic-constraint.stderr
index 65d18761b18..3ecac9c83e5 100644
--- a/tests/ui/associated-types/dont-suggest-cyclic-constraint.stderr
+++ b/tests/ui/associated-types/dont-suggest-cyclic-constraint.stderr
@@ -1,15 +1,11 @@
 error[E0308]: mismatched types
-  --> $DIR/dont-suggest-cyclic-constraint.rs:9:35
+  --> $DIR/dont-suggest-cyclic-constraint.rs:7:35
    |
 LL |     debug_assert_eq!(iter.next(), Some(value));
    |                                   ^^^^^^^^^^^ expected `Option<<I as Iterator>::Item>`, found `Option<&<I as Iterator>::Item>`
    |
    = note: expected enum `Option<<I as Iterator>::Item>`
               found enum `Option<&<I as Iterator>::Item>`
-help: use `Option::as_ref` to convert `Option<<I as Iterator>::Item>` to `Option<&<I as Iterator>::Item>`
-   |
-LL |     debug_assert_eq!(iter.next().as_ref(), Some(value));
-   |                                 +++++++++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/inference/str-as-char.fixed b/tests/ui/inference/str-as-char.fixed
index 6aea809cbdb..911b067c4d1 100644
--- a/tests/ui/inference/str-as-char.fixed
+++ b/tests/ui/inference/str-as-char.fixed
@@ -7,4 +7,5 @@ fn main() {
     let _: &str = "a";   //~ ERROR mismatched types
     let _: &str = "\"\"\""; //~ ERROR character literal may only contain one codepoint
     let _: &str = "\"\"\""; //~ ERROR character literal may only contain one codepoint
+    let _: &str = "\"\"\\\"\\\"\\\\\""; //~ ERROR character literal may only contain one codepoint
 }
diff --git a/tests/ui/inference/str-as-char.rs b/tests/ui/inference/str-as-char.rs
index eaa8d788c34..832bc871a9e 100644
--- a/tests/ui/inference/str-as-char.rs
+++ b/tests/ui/inference/str-as-char.rs
@@ -7,4 +7,5 @@ fn main() {
     let _: &str = 'a';   //~ ERROR mismatched types
     let _: &str = '"""'; //~ ERROR character literal may only contain one codepoint
     let _: &str = '\"\"\"'; //~ ERROR character literal may only contain one codepoint
+    let _: &str = '"\"\\"\\\"\\\\"'; //~ ERROR character literal may only contain one codepoint
 }
diff --git a/tests/ui/inference/str-as-char.stderr b/tests/ui/inference/str-as-char.stderr
index 2c84dac8e0c..216f4cda698 100644
--- a/tests/ui/inference/str-as-char.stderr
+++ b/tests/ui/inference/str-as-char.stderr
@@ -20,6 +20,17 @@ help: if you meant to write a `str` literal, use double quotes
 LL |     let _: &str = "\"\"\"";
    |                   ~~~~~~~~
 
+error: character literal may only contain one codepoint
+  --> $DIR/str-as-char.rs:10:19
+   |
+LL |     let _: &str = '"\"\"\\"\\"';
+   |                   ^^^^^^^^^^^^^^^^^
+   |
+help: if you meant to write a `str` literal, use double quotes
+   |
+LL |     let _: &str = "\"\"\\"\\"\\\"";
+   |                   ~~~~~~~~~~~~~~~~~~~~
+
 error[E0308]: mismatched types
   --> $DIR/str-as-char.rs:7:19
    |
@@ -33,6 +44,6 @@ help: if you meant to write a `str` literal, use double quotes
 LL |     let _: &str = "a";
    |                   ~~~
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/suggestions/copied-and-cloned.fixed b/tests/ui/suggestions/copied-and-cloned.fixed
index 77159d5075a..4cecf9e26f9 100644
--- a/tests/ui/suggestions/copied-and-cloned.fixed
+++ b/tests/ui/suggestions/copied-and-cloned.fixed
@@ -2,6 +2,16 @@
 
 fn expect<T>(_: T) {}
 
+struct Issue114925 {
+    x: Option<String>,
+}
+
+fn issue_114925(lol: &mut Issue114925, x: Option<&String>) {
+    lol.x = x.clone().cloned();
+    //~^ ERROR mismatched types
+    //~| HELP use `Option::cloned` to clone the value inside the `Option`
+}
+
 fn main() {
     let x = Some(&());
     expect::<Option<()>>(x.copied());
@@ -24,10 +34,10 @@ fn main() {
     let s = String::new();
     let x = Some(s.clone());
     let y = Some(&s);
-    println!("{}", x.as_ref() == y);
+    println!("{}", x == y.cloned());
     //~^ ERROR mismatched types
-    //~| HELP use `Option::as_ref` to convert `Option<String>` to `Option<&String>`
-
+    //~| HELP use `Option::cloned` to clone the value inside the `Option`
+    //FIXME(#114050) ~| HELP use `Option::as_ref` to convert `Option<String>` to `Option<&String>`
 
     let mut s = ();
     let x = Some(s);
@@ -42,4 +52,6 @@ fn main() {
     println!("{}", x == y.cloned());
     //~^ ERROR mismatched types
     //~| HELP use `Option::cloned` to clone the value inside the `Option`
+
+    issue_114925(&mut Issue114925 { x: None }, None);
 }
diff --git a/tests/ui/suggestions/copied-and-cloned.rs b/tests/ui/suggestions/copied-and-cloned.rs
index c506494ee14..a79928c50d5 100644
--- a/tests/ui/suggestions/copied-and-cloned.rs
+++ b/tests/ui/suggestions/copied-and-cloned.rs
@@ -2,6 +2,16 @@
 
 fn expect<T>(_: T) {}
 
+struct Issue114925 {
+    x: Option<String>,
+}
+
+fn issue_114925(lol: &mut Issue114925, x: Option<&String>) {
+    lol.x = x.clone();
+    //~^ ERROR mismatched types
+    //~| HELP use `Option::cloned` to clone the value inside the `Option`
+}
+
 fn main() {
     let x = Some(&());
     expect::<Option<()>>(x);
@@ -26,8 +36,8 @@ fn main() {
     let y = Some(&s);
     println!("{}", x == y);
     //~^ ERROR mismatched types
-    //~| HELP use `Option::as_ref` to convert `Option<String>` to `Option<&String>`
-
+    //~| HELP use `Option::cloned` to clone the value inside the `Option`
+    //FIXME(#114050) ~| HELP use `Option::as_ref` to convert `Option<String>` to `Option<&String>`
 
     let mut s = ();
     let x = Some(s);
@@ -42,4 +52,6 @@ fn main() {
     println!("{}", x == y);
     //~^ ERROR mismatched types
     //~| HELP use `Option::cloned` to clone the value inside the `Option`
+
+    issue_114925(&mut Issue114925 { x: None }, None);
 }
diff --git a/tests/ui/suggestions/copied-and-cloned.stderr b/tests/ui/suggestions/copied-and-cloned.stderr
index f8712d0a39e..87b0624d48b 100644
--- a/tests/ui/suggestions/copied-and-cloned.stderr
+++ b/tests/ui/suggestions/copied-and-cloned.stderr
@@ -1,5 +1,20 @@
 error[E0308]: mismatched types
-  --> $DIR/copied-and-cloned.rs:7:26
+  --> $DIR/copied-and-cloned.rs:10:13
+   |
+LL |     lol.x = x.clone();
+   |     -----   ^^^^^^^^^ expected `Option<String>`, found `Option<&String>`
+   |     |
+   |     expected due to the type of this binding
+   |
+   = note: expected enum `Option<String>`
+              found enum `Option<&String>`
+help: use `Option::cloned` to clone the value inside the `Option`
+   |
+LL |     lol.x = x.clone().cloned();
+   |                      +++++++++
+
+error[E0308]: mismatched types
+  --> $DIR/copied-and-cloned.rs:17:26
    |
 LL |     expect::<Option<()>>(x);
    |     -------------------- ^ expected `Option<()>`, found `Option<&()>`
@@ -19,7 +34,7 @@ LL |     expect::<Option<()>>(x.copied());
    |                           +++++++++
 
 error[E0308]: mismatched types
-  --> $DIR/copied-and-cloned.rs:11:30
+  --> $DIR/copied-and-cloned.rs:21:30
    |
 LL |     expect::<Result<(), ()>>(x);
    |     ------------------------ ^ expected `Result<(), ()>`, found `Result<&(), _>`
@@ -39,7 +54,7 @@ LL |     expect::<Result<(), ()>>(x.copied());
    |                               +++++++++
 
 error[E0308]: mismatched types
-  --> $DIR/copied-and-cloned.rs:16:30
+  --> $DIR/copied-and-cloned.rs:26:30
    |
 LL |     expect::<Option<String>>(x);
    |     ------------------------ ^ expected `Option<String>`, found `Option<&String>`
@@ -59,7 +74,7 @@ LL |     expect::<Option<String>>(x.cloned());
    |                               +++++++++
 
 error[E0308]: mismatched types
-  --> $DIR/copied-and-cloned.rs:20:34
+  --> $DIR/copied-and-cloned.rs:30:34
    |
 LL |     expect::<Result<String, ()>>(x);
    |     ---------------------------- ^ expected `Result<String, ()>`, found `Result<&String, _>`
@@ -79,20 +94,20 @@ LL |     expect::<Result<String, ()>>(x.cloned());
    |                                   +++++++++
 
 error[E0308]: mismatched types
-  --> $DIR/copied-and-cloned.rs:27:25
+  --> $DIR/copied-and-cloned.rs:37:25
    |
 LL |     println!("{}", x == y);
    |                         ^ expected `Option<String>`, found `Option<&String>`
    |
    = note: expected enum `Option<String>`
               found enum `Option<&String>`
-help: use `Option::as_ref` to convert `Option<String>` to `Option<&String>`
+help: use `Option::cloned` to clone the value inside the `Option`
    |
-LL |     println!("{}", x.as_ref() == y);
-   |                     +++++++++
+LL |     println!("{}", x == y.cloned());
+   |                          +++++++++
 
 error[E0308]: mismatched types
-  --> $DIR/copied-and-cloned.rs:35:25
+  --> $DIR/copied-and-cloned.rs:45:25
    |
 LL |     println!("{}", x == y);
    |                         ^ expected `Option<()>`, found `Option<&mut ()>`
@@ -105,7 +120,7 @@ LL |     println!("{}", x == y.copied());
    |                          +++++++++
 
 error[E0308]: mismatched types
-  --> $DIR/copied-and-cloned.rs:42:25
+  --> $DIR/copied-and-cloned.rs:52:25
    |
 LL |     println!("{}", x == y);
    |                         ^ expected `Option<String>`, found `Option<&mut String>`
@@ -117,6 +132,6 @@ help: use `Option::cloned` to clone the value inside the `Option`
 LL |     println!("{}", x == y.cloned());
    |                          +++++++++
 
-error: aborting due to 7 previous errors
+error: aborting due to 8 previous errors
 
 For more information about this error, try `rustc --explain E0308`.