about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-09-26 17:50:26 +0000
committerbors <bors@rust-lang.org>2020-09-26 17:50:26 +0000
commite37c99fa1ca2341d652a1b1859ea9aa2ae993e1e (patch)
treeb9e095a23ea81994bc8aaeffe492b6cd4aa5c7b8
parent6f9a8a7f9b9732c55511d2a2a3914e8feafc7c52 (diff)
parent9e02642fb3f1f78793c24bbad9c39368e2024968 (diff)
downloadrust-e37c99fa1ca2341d652a1b1859ea9aa2ae993e1e.tar.gz
rust-e37c99fa1ca2341d652a1b1859ea9aa2ae993e1e.zip
Auto merge of #77224 - RalfJung:rollup-hdvb96c, r=RalfJung
Rollup of 12 pull requests

Successful merges:

 - #75454 (Explicitly document the size guarantees that Option makes.)
 - #76631 (Add `x.py setup`)
 - #77076 (Add missing code examples on slice iter types)
 - #77093 (merge `need_type_info_err(_const)`)
 - #77122 (Add `#![feature(const_fn_floating_point_arithmetic)]`)
 - #77127 (Update mdBook)
 - #77161 (Remove TrustedLen requirement from BuilderMethods::switch)
 - #77166 (update Miri)
 - #77181 (Add doc alias for pointer primitive)
 - #77204 (Remove stray word from `ClosureKind::extends` docs)
 - #77207 (Rename `whence` to `span`)
 - #77211 (Remove unused #[allow(...)] statements from compiler/)

Failed merges:

 - #77170 (Remove `#[rustc_allow_const_fn_ptr]` and add `#![feature(const_fn_fn_ptr_basics)]`)

r? `@ghost`
-rw-r--r--Cargo.lock4
-rw-r--r--compiler/rustc_arena/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/common.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/va_arg.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/common.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/builder.rs3
-rw-r--r--compiler/rustc_data_structures/src/lib.rs1
-rw-r--r--compiler/rustc_feature/src/active.rs3
-rw-r--r--compiler/rustc_hir/src/intravisit.rs3
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs277
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs6
-rw-r--r--compiler/rustc_lint/src/types.rs2
-rw-r--r--compiler/rustc_llvm/src/lib.rs1
-rw-r--r--compiler/rustc_macros/src/query.rs1
-rw-r--r--compiler/rustc_macros/src/symbols.rs1
-rw-r--r--compiler/rustc_middle/src/infer/unify_key.rs18
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs2
-rw-r--r--compiler/rustc_middle/src/util/common.rs2
-rw-r--r--compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs10
-rw-r--r--compiler/rustc_mir/src/borrow_check/prefixes.rs1
-rw-r--r--compiler/rustc_mir/src/dataflow/move_paths/mod.rs1
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/ops.rs24
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/validation.rs31
-rw-r--r--compiler/rustc_session/src/filesearch.rs2
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/auto_trait.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs37
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs1
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt.rs2
-rw-r--r--compiler/rustc_typeck/src/check/writeback.rs11
-rw-r--r--compiler/rustc_typeck/src/lib.rs1
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/option.rs21
-rw-r--r--library/core/src/slice/iter.rs164
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/primitive_docs.rs1
-rw-r--r--src/bootstrap/CHANGELOG.md1
-rw-r--r--src/bootstrap/bin/main.rs19
-rw-r--r--src/bootstrap/builder.rs4
-rw-r--r--src/bootstrap/config.rs7
-rw-r--r--src/bootstrap/flags.rs32
-rw-r--r--src/bootstrap/lib.rs7
-rw-r--r--src/bootstrap/run.rs2
-rw-r--r--src/bootstrap/setup.rs88
-rw-r--r--src/librustdoc/clean/mod.rs38
-rw-r--r--src/librustdoc/doctree.rs34
-rw-r--r--src/librustdoc/visit_ast.rs34
-rw-r--r--src/test/ui/const-generics/infer/cannot-infer-const-args.full.stderr4
-rw-r--r--src/test/ui/const-generics/infer/cannot-infer-const-args.min.stderr4
-rw-r--r--src/test/ui/const-generics/infer/issue-77092.rs16
-rw-r--r--src/test/ui/const-generics/infer/issue-77092.stderr9
-rw-r--r--src/test/ui/const-generics/infer/method-chain.full.stderr4
-rw-r--r--src/test/ui/const-generics/infer/method-chain.min.stderr4
-rw-r--r--src/test/ui/const-generics/infer/uninferred-consts.full.stderr4
-rw-r--r--src/test/ui/const-generics/infer/uninferred-consts.min.stderr4
-rw-r--r--src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs2
-rw-r--r--src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr6
-rw-r--r--src/test/ui/consts/const_fn_floating_point_arithmetic.gated.stderr8
-rw-r--r--src/test/ui/consts/const_fn_floating_point_arithmetic.rs20
-rw-r--r--src/test/ui/consts/const_fn_floating_point_arithmetic.stock.stderr48
-rw-r--r--src/test/ui/consts/const_let_eq_float.rs4
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn.rs8
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn.stderr72
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs6
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr2
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs4
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr2
m---------src/tools/miri16
-rw-r--r--src/tools/rustbook/Cargo.toml2
74 files changed, 815 insertions, 351 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 9a5ba741749..05d77ec0c8f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1848,9 +1848,9 @@ dependencies = [
 
 [[package]]
 name = "mdbook"
-version = "0.4.2"
+version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b75e31ae4eaa0e45e17ee2b6b9e3ed969c3c6ff12bb4c2e352c42493f4ebb706"
+checksum = "29be448fcafb00c5a8966c4020c2a5ffbbc333e5b96d0bb5ef54b5bd0524d9ff"
 dependencies = [
  "ammonia",
  "anyhow",
diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs
index b4bf31b1aba..166f7f53c41 100644
--- a/compiler/rustc_arena/src/lib.rs
+++ b/compiler/rustc_arena/src/lib.rs
@@ -15,7 +15,6 @@
 #![feature(new_uninit)]
 #![feature(maybe_uninit_slice)]
 #![cfg_attr(test, feature(test))]
-#![allow(deprecated)]
 
 use rustc_data_structures::cold_path;
 use smallvec::SmallVec;
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index 23a3be1a2f2..0c172dc33ba 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -21,7 +21,6 @@ use rustc_target::abi::{self, Align, Size};
 use rustc_target::spec::{HasTargetSpec, Target};
 use std::borrow::Cow;
 use std::ffi::CStr;
-use std::iter::TrustedLen;
 use std::ops::{Deref, Range};
 use std::ptr;
 use tracing::debug;
@@ -179,7 +178,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         &mut self,
         v: &'ll Value,
         else_llbb: &'ll BasicBlock,
-        cases: impl ExactSizeIterator<Item = (u128, &'ll BasicBlock)> + TrustedLen,
+        cases: impl ExactSizeIterator<Item = (u128, &'ll BasicBlock)>,
     ) {
         let switch =
             unsafe { llvm::LLVMBuildSwitch(self.llbuilder, v, else_llbb, cases.len() as c_uint) };
@@ -931,7 +930,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         unsafe { llvm::LLVMBuildSelect(self.llbuilder, cond, then_val, else_val, UNNAMED) }
     }
 
-    #[allow(dead_code)]
     fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value {
         unsafe { llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED) }
     }
diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs
index 0b1cf03fa7e..0992410a728 100644
--- a/compiler/rustc_codegen_llvm/src/common.rs
+++ b/compiler/rustc_codegen_llvm/src/common.rs
@@ -1,5 +1,3 @@
-#![allow(non_camel_case_types, non_snake_case)]
-
 //! Code that is useful in various codegen modules.
 
 use crate::consts::{self, const_alloc_to_llvm};
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 868eb74cf09..987149cb4c2 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -1845,7 +1845,6 @@ impl<'tcx> VariantInfo<'_, 'tcx> {
         None
     }
 
-    #[allow(dead_code)]
     fn is_artificial(&self) -> bool {
         match self {
             VariantInfo::Generator { .. } => true,
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index 456e9c7ce75..f14493e6043 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -12,7 +12,6 @@
 #![feature(in_band_lifetimes)]
 #![feature(nll)]
 #![feature(or_patterns)]
-#![feature(trusted_len)]
 #![recursion_limit = "256"]
 
 use back::write::{create_informational_target_machine, create_target_machine};
diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs
index 54efa05aee8..22ed4dd7576 100644
--- a/compiler/rustc_codegen_llvm/src/va_arg.rs
+++ b/compiler/rustc_codegen_llvm/src/va_arg.rs
@@ -11,7 +11,6 @@ use rustc_middle::ty::layout::HasTyCtxt;
 use rustc_middle::ty::Ty;
 use rustc_target::abi::{Align, HasDataLayout, LayoutOf, Size};
 
-#[allow(dead_code)]
 fn round_pointer_up_to_alignment(
     bx: &mut Builder<'a, 'll, 'tcx>,
     addr: &'ll Value,
diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs
index e04ed531bbf..780b1d2cd94 100644
--- a/compiler/rustc_codegen_ssa/src/common.rs
+++ b/compiler/rustc_codegen_ssa/src/common.rs
@@ -1,4 +1,4 @@
-#![allow(non_camel_case_types, non_snake_case)]
+#![allow(non_camel_case_types)]
 
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
@@ -25,7 +25,6 @@ pub enum IntPredicate {
     IntSLE,
 }
 
-#[allow(dead_code)]
 pub enum RealPredicate {
     RealPredicateFalse,
     RealOEQ,
@@ -60,7 +59,6 @@ pub enum AtomicRmwBinOp {
 }
 
 pub enum AtomicOrdering {
-    #[allow(dead_code)]
     NotAtomic,
     Unordered,
     Monotonic,
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index 8568bd64f4c..d4f3bf37797 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -6,7 +6,6 @@
 #![feature(in_band_lifetimes)]
 #![feature(nll)]
 #![feature(or_patterns)]
-#![feature(trusted_len)]
 #![feature(associated_type_bounds)]
 #![recursion_limit = "256"]
 
diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs
index 5142922260a..b35b0f24208 100644
--- a/compiler/rustc_codegen_ssa/src/traits/builder.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs
@@ -18,7 +18,6 @@ use rustc_middle::ty::Ty;
 use rustc_target::abi::{Abi, Align, Scalar, Size};
 use rustc_target::spec::HasTargetSpec;
 
-use std::iter::TrustedLen;
 use std::ops::Range;
 
 #[derive(Copy, Clone)]
@@ -60,7 +59,7 @@ pub trait BuilderMethods<'a, 'tcx>:
         &mut self,
         v: Self::Value,
         else_llbb: Self::BasicBlock,
-        cases: impl ExactSizeIterator<Item = (u128, Self::BasicBlock)> + TrustedLen,
+        cases: impl ExactSizeIterator<Item = (u128, Self::BasicBlock)>,
     );
     fn invoke(
         &mut self,
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index 9ded10e9c26..90b0f254751 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -7,7 +7,6 @@
 //! This API is completely unstable and subject to change.
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
-#![allow(incomplete_features)]
 #![feature(array_windows)]
 #![feature(control_flow_enum)]
 #![feature(in_band_lifetimes)]
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 6452bda293e..17b9e1ee7e8 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -584,6 +584,9 @@ declare_features! (
     /// Allows non trivial generic constants which have to be manually propageted upwards.
     (active, const_evaluatable_checked, "1.48.0", Some(76560), None),
 
+    /// Allows basic arithmetic on floating point types in a `const fn`.
+    (active, const_fn_floating_point_arithmetic, "1.48.0", Some(57241), None),
+
     // -------------------------------------------------------------------------
     // feature-group-end: actual feature gates
     // -------------------------------------------------------------------------
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 76cf6bd4776..820d664c07d 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -256,7 +256,6 @@ pub trait Visitor<'v>: Sized {
     /// patterns described on `itemlikevisit::ItemLikeVisitor`. The only
     /// reason to override this method is if you want a nested pattern
     /// but cannot supply a `Map`; see `nested_visit_map` for advice.
-    #[allow(unused_variables)]
     fn visit_nested_item(&mut self, id: ItemId) {
         let opt_item = self.nested_visit_map().inter().map(|map| map.item(id.id));
         walk_list!(self, visit_item, opt_item);
@@ -265,7 +264,6 @@ pub trait Visitor<'v>: Sized {
     /// Like `visit_nested_item()`, but for trait items. See
     /// `visit_nested_item()` for advice on when to override this
     /// method.
-    #[allow(unused_variables)]
     fn visit_nested_trait_item(&mut self, id: TraitItemId) {
         let opt_item = self.nested_visit_map().inter().map(|map| map.trait_item(id));
         walk_list!(self, visit_trait_item, opt_item);
@@ -274,7 +272,6 @@ pub trait Visitor<'v>: Sized {
     /// Like `visit_nested_item()`, but for impl items. See
     /// `visit_nested_item()` for advice on when to override this
     /// method.
-    #[allow(unused_variables)]
     fn visit_nested_impl_item(&mut self, id: ImplItemId) {
         let opt_item = self.nested_visit_map().inter().map(|map| map.impl_item(id));
         walk_list!(self, visit_impl_item, opt_item);
diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index f87406c2ce4..2f3089f1a92 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -176,7 +176,10 @@ fn closure_return_type_suggestion(
         suggestion,
         Applicability::HasPlaceholders,
     );
-    err.span_label(span, InferCtxt::missing_type_msg(&name, &descr, parent_name, parent_descr));
+    err.span_label(
+        span,
+        InferCtxt::cannot_infer_msg("type", &name, &descr, parent_name, parent_descr),
+    );
 }
 
 /// Given a closure signature, return a `String` containing a list of all its argument types.
@@ -217,65 +220,151 @@ impl Into<rustc_errors::DiagnosticId> for TypeAnnotationNeeded {
     }
 }
 
+/// Information about a constant or a type containing inference variables.
+pub struct InferenceDiagnosticsData {
+    pub name: String,
+    pub span: Option<Span>,
+    pub description: Cow<'static, str>,
+    pub parent_name: Option<String>,
+    pub parent_description: Option<&'static str>,
+}
+
 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
-    pub fn extract_type_name(
+    /// Extracts data used by diagnostic for either types or constants
+    /// which were stuck during inference.
+    pub fn extract_inference_diagnostics_data(
         &self,
-        ty: Ty<'tcx>,
+        arg: GenericArg<'tcx>,
         highlight: Option<ty::print::RegionHighlightMode>,
-    ) -> (String, Option<Span>, Cow<'static, str>, Option<String>, Option<&'static str>) {
-        if let ty::Infer(ty::TyVar(ty_vid)) = *ty.kind() {
-            let mut inner = self.inner.borrow_mut();
-            let ty_vars = &inner.type_variables();
-            let var_origin = ty_vars.var_origin(ty_vid);
-            if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) = var_origin.kind {
-                let parent_def_id = def_id.and_then(|def_id| self.tcx.parent(def_id));
-                let (parent_name, parent_desc) = if let Some(parent_def_id) = parent_def_id {
-                    let parent_name = self
-                        .tcx
-                        .def_key(parent_def_id)
-                        .disambiguated_data
-                        .data
-                        .get_opt_name()
-                        .map(|parent_symbol| parent_symbol.to_string());
-
-                    (parent_name, Some(self.tcx.def_kind(parent_def_id).descr(parent_def_id)))
-                } else {
-                    (None, None)
-                };
+    ) -> InferenceDiagnosticsData {
+        match arg.unpack() {
+            GenericArgKind::Type(ty) => {
+                if let ty::Infer(ty::TyVar(ty_vid)) = *ty.kind() {
+                    let mut inner = self.inner.borrow_mut();
+                    let ty_vars = &inner.type_variables();
+                    let var_origin = ty_vars.var_origin(ty_vid);
+                    if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) =
+                        var_origin.kind
+                    {
+                        let parent_def_id = def_id.and_then(|def_id| self.tcx.parent(def_id));
+                        let (parent_name, parent_description) =
+                            if let Some(parent_def_id) = parent_def_id {
+                                let parent_name = self
+                                    .tcx
+                                    .def_key(parent_def_id)
+                                    .disambiguated_data
+                                    .data
+                                    .get_opt_name()
+                                    .map(|parent_symbol| parent_symbol.to_string());
+
+                                (
+                                    parent_name,
+                                    Some(self.tcx.def_kind(parent_def_id).descr(parent_def_id)),
+                                )
+                            } else {
+                                (None, None)
+                            };
+
+                        if name != kw::SelfUpper {
+                            return InferenceDiagnosticsData {
+                                name: name.to_string(),
+                                span: Some(var_origin.span),
+                                description: "type parameter".into(),
+                                parent_name,
+                                parent_description,
+                            };
+                        }
+                    }
+                }
 
-                if name != kw::SelfUpper {
-                    return (
-                        name.to_string(),
-                        Some(var_origin.span),
-                        "type parameter".into(),
-                        parent_name,
-                        parent_desc,
-                    );
+                let mut s = String::new();
+                let mut printer = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS);
+                if let Some(highlight) = highlight {
+                    printer.region_highlight_mode = highlight;
+                }
+                let _ = ty.print(printer);
+                InferenceDiagnosticsData {
+                    name: s,
+                    span: None,
+                    description: ty.prefix_string(),
+                    parent_name: None,
+                    parent_description: None,
                 }
             }
-        }
+            GenericArgKind::Const(ct) => {
+                if let ty::ConstKind::Infer(InferConst::Var(vid)) = ct.val {
+                    let origin =
+                        self.inner.borrow_mut().const_unification_table().probe_value(vid).origin;
+                    if let ConstVariableOriginKind::ConstParameterDefinition(name, def_id) =
+                        origin.kind
+                    {
+                        let parent_def_id = self.tcx.parent(def_id);
+                        let (parent_name, parent_description) =
+                            if let Some(parent_def_id) = parent_def_id {
+                                let parent_name = self
+                                    .tcx
+                                    .def_key(parent_def_id)
+                                    .disambiguated_data
+                                    .data
+                                    .get_opt_name()
+                                    .map(|parent_symbol| parent_symbol.to_string());
+
+                                (
+                                    parent_name,
+                                    Some(self.tcx.def_kind(parent_def_id).descr(parent_def_id)),
+                                )
+                            } else {
+                                (None, None)
+                            };
+
+                        return InferenceDiagnosticsData {
+                            name: name.to_string(),
+                            span: Some(origin.span),
+                            description: "const parameter".into(),
+                            parent_name,
+                            parent_description,
+                        };
+                    }
 
-        let mut s = String::new();
-        let mut printer = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS);
-        if let Some(highlight) = highlight {
-            printer.region_highlight_mode = highlight;
+                    debug_assert!(!origin.span.is_dummy());
+                    let mut s = String::new();
+                    let mut printer =
+                        ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::ValueNS);
+                    if let Some(highlight) = highlight {
+                        printer.region_highlight_mode = highlight;
+                    }
+                    let _ = ct.print(printer);
+                    InferenceDiagnosticsData {
+                        name: s,
+                        span: Some(origin.span),
+                        description: "the constant".into(),
+                        parent_name: None,
+                        parent_description: None,
+                    }
+                } else {
+                    bug!("unexpect const: {:?}", ct);
+                }
+            }
+            GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"),
         }
-        let _ = ty.print(printer);
-        (s, None, ty.prefix_string(), None, None)
     }
 
-    // FIXME(eddyb) generalize all of this to handle `ty::Const` inference variables as well.
-    pub fn need_type_info_err(
+    pub fn emit_inference_failure_err(
         &self,
         body_id: Option<hir::BodyId>,
         span: Span,
-        ty: Ty<'tcx>,
+        arg: GenericArg<'tcx>,
         error_code: TypeAnnotationNeeded,
     ) -> DiagnosticBuilder<'tcx> {
-        let ty = self.resolve_vars_if_possible(&ty);
-        let (name, name_sp, descr, parent_name, parent_descr) = self.extract_type_name(&ty, None);
+        let arg = self.resolve_vars_if_possible(&arg);
+        let arg_data = self.extract_inference_diagnostics_data(arg, None);
+        let kind_str = match arg.unpack() {
+            GenericArgKind::Type(_) => "type",
+            GenericArgKind::Const(_) => "the value",
+            GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"),
+        };
 
-        let mut local_visitor = FindHirNodeVisitor::new(&self, ty.into(), span);
+        let mut local_visitor = FindHirNodeVisitor::new(&self, arg, span);
         let ty_to_string = |ty: Ty<'tcx>| -> String {
             let mut s = String::new();
             let mut printer = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS);
@@ -305,7 +394,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         }
         let err_span = if let Some(pattern) = local_visitor.found_arg_pattern {
             pattern.span
-        } else if let Some(span) = name_sp {
+        } else if let Some(span) = arg_data.span {
             // `span` here lets us point at `sum` instead of the entire right hand side expr:
             // error[E0282]: type annotations needed
             //  --> file2.rs:3:15
@@ -352,7 +441,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             _ => String::new(),
         };
 
-        // When `name` corresponds to a type argument, show the path of the full type we're
+        // When `arg_data.name` corresponds to a type argument, show the path of the full type we're
         // trying to infer. In the following example, `ty_msg` contains
         // " in `std::result::Result<i32, E>`":
         // ```
@@ -391,11 +480,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                         &mut err,
                         &decl.output,
                         self.tcx.hir().body(body_id),
-                        &descr,
-                        &name,
+                        &arg_data.description,
+                        &arg_data.name,
                         &ret,
-                        parent_name,
-                        parent_descr,
+                        arg_data.parent_name,
+                        arg_data.parent_description,
                     );
                     // We don't want to give the other suggestions when the problem is the
                     // closure return type.
@@ -409,15 +498,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 // nudge them in the right direction.
                 format!("a boxed closure type like `Box<dyn Fn({}) -> {}>`", args, ret)
             }
-            Some(ty) if is_named_and_not_impl_trait(ty) && name == "_" => {
+            Some(ty) if is_named_and_not_impl_trait(ty) && arg_data.name == "_" => {
                 let ty = ty_to_string(ty);
                 format!("the explicit type `{}`, with the type parameters specified", ty)
             }
-            Some(ty) if is_named_and_not_impl_trait(ty) && ty.to_string() != name => {
+            Some(ty) if is_named_and_not_impl_trait(ty) && ty.to_string() != arg_data.name => {
                 let ty = ty_to_string(ty);
                 format!(
                     "the explicit type `{}`, where the type parameter `{}` is specified",
-                    ty, name,
+                    ty, arg_data.name,
                 )
             }
             _ => "a type".to_string(),
@@ -534,7 +623,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         //   |               ^^^ cannot infer type for `S`
         //   |
         //   = note: type must be known at this point
-        let span = name_sp.unwrap_or(err_span);
+        let span = arg_data.span.unwrap_or(err_span);
         if !err
             .span
             .span_labels()
@@ -545,55 +634,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             // Avoid multiple labels pointing at `span`.
             err.span_label(
                 span,
-                InferCtxt::missing_type_msg(&name, &descr, parent_name, parent_descr),
+                InferCtxt::cannot_infer_msg(
+                    kind_str,
+                    &arg_data.name,
+                    &arg_data.description,
+                    arg_data.parent_name,
+                    arg_data.parent_description,
+                ),
             );
         }
 
         err
     }
 
-    // FIXME(const_generics): We should either try and merge this with `need_type_info_err`
-    // or improve the errors created here.
-    //
-    // Unlike for type inference variables, we don't yet store the origin of const inference variables.
-    // This is needed for to get a more relevant error span.
-    pub fn need_type_info_err_const(
-        &self,
-        body_id: Option<hir::BodyId>,
-        span: Span,
-        ct: &'tcx ty::Const<'tcx>,
-        error_code: TypeAnnotationNeeded,
-    ) -> DiagnosticBuilder<'tcx> {
-        let mut local_visitor = FindHirNodeVisitor::new(&self, ct.into(), span);
-        if let Some(body_id) = body_id {
-            let expr = self.tcx.hir().expect_expr(body_id.hir_id);
-            local_visitor.visit_expr(expr);
-        }
-
-        let mut param_name = None;
-        let span = if let ty::ConstKind::Infer(InferConst::Var(vid)) = ct.val {
-            let origin = self.inner.borrow_mut().const_unification_table().probe_value(vid).origin;
-            if let ConstVariableOriginKind::ConstParameterDefinition(param) = origin.kind {
-                param_name = Some(param);
-            }
-            origin.span
-        } else {
-            local_visitor.target_span
-        };
-
-        let error_code = error_code.into();
-        let mut err =
-            self.tcx.sess.struct_span_err_with_code(span, "type annotations needed", error_code);
-
-        if let Some(param_name) = param_name {
-            err.note(&format!("cannot infer the value of the const parameter `{}`", param_name));
-        } else {
-            err.note("unable to infer the value of a const parameter");
-        }
-
-        err
-    }
-
     /// If the `FnSig` for the method call can be found and type arguments are identified as
     /// needed, suggest annotating the call, otherwise point out the resulting type of the call.
     fn annotate_method_call(
@@ -647,7 +700,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         ty: Ty<'tcx>,
     ) -> DiagnosticBuilder<'tcx> {
         let ty = self.resolve_vars_if_possible(&ty);
-        let (name, _, descr, parent_name, parent_descr) = self.extract_type_name(&ty, None);
+        let data = self.extract_inference_diagnostics_data(ty.into(), None);
 
         let mut err = struct_span_err!(
             self.tcx.sess,
@@ -656,18 +709,28 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             "type inside {} must be known in this context",
             kind,
         );
-        err.span_label(span, InferCtxt::missing_type_msg(&name, &descr, parent_name, parent_descr));
+        err.span_label(
+            span,
+            InferCtxt::cannot_infer_msg(
+                "type",
+                &data.name,
+                &data.description,
+                data.parent_name,
+                data.parent_description,
+            ),
+        );
         err
     }
 
-    fn missing_type_msg(
+    fn cannot_infer_msg(
+        kind_str: &str,
         type_name: &str,
         descr: &str,
         parent_name: Option<String>,
         parent_descr: Option<&str>,
-    ) -> Cow<'static, str> {
+    ) -> String {
         if type_name == "_" {
-            "cannot infer type".into()
+            format!("cannot infer {}", kind_str)
         } else {
             let parent_desc = if let Some(parent_name) = parent_name {
                 let parent_type_descr = if let Some(parent_descr) = parent_descr {
@@ -681,7 +744,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 "".to_string()
             };
 
-            format!("cannot infer type for {} `{}`{}", descr, type_name, parent_desc).into()
+            // FIXME: We really shouldn't be dealing with strings here
+            // but instead use a sensible enum for cases like this.
+            let preposition = if "the value" == kind_str { "of" } else { "for" };
+            // For example: "cannot infer type for type parameter `T`"
+            format!(
+                "cannot infer {} {} {} `{}`{}",
+                kind_str, preposition, descr, type_name, parent_desc
+            )
+            .into()
         }
     }
 }
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 2cbdc954e20..07a55c7f859 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -1163,7 +1163,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             }
             GenericParamDefKind::Const { .. } => {
                 let origin = ConstVariableOrigin {
-                    kind: ConstVariableOriginKind::ConstParameterDefinition(param.name),
+                    kind: ConstVariableOriginKind::ConstParameterDefinition(
+                        param.name,
+                        param.def_id,
+                    ),
                     span,
                 };
                 let const_var_id =
@@ -1275,7 +1278,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     }
 
     /// Gives temporary access to the region constraint data.
-    #[allow(non_camel_case_types)] // bug with impl trait
     pub fn with_region_constraints<R>(
         &self,
         op: impl FnOnce(&RegionConstraintData<'tcx>) -> R,
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 6aa28d04ae1..9925444b869 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -1,5 +1,3 @@
-#![allow(non_snake_case)]
-
 use crate::{LateContext, LateLintPass, LintContext};
 use rustc_ast as ast;
 use rustc_attr as attr;
diff --git a/compiler/rustc_llvm/src/lib.rs b/compiler/rustc_llvm/src/lib.rs
index a7a10b91b4e..a381290d46f 100644
--- a/compiler/rustc_llvm/src/lib.rs
+++ b/compiler/rustc_llvm/src/lib.rs
@@ -21,7 +21,6 @@ impl RustString {
 
 /// Appending to a Rust string -- used by RawRustStringOstream.
 #[no_mangle]
-#[allow(improper_ctypes_definitions)]
 pub unsafe extern "C" fn LLVMRustStringWriteImpl(
     sr: &RustString,
     ptr: *const c_char,
diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs
index 204e8e800cd..e7c054653ac 100644
--- a/compiler/rustc_macros/src/query.rs
+++ b/compiler/rustc_macros/src/query.rs
@@ -9,7 +9,6 @@ use syn::{
     ReturnType, Token, Type,
 };
 
-#[allow(non_camel_case_types)]
 mod kw {
     syn::custom_keyword!(query);
 }
diff --git a/compiler/rustc_macros/src/symbols.rs b/compiler/rustc_macros/src/symbols.rs
index 352665f0ab1..94d4ad78e8d 100644
--- a/compiler/rustc_macros/src/symbols.rs
+++ b/compiler/rustc_macros/src/symbols.rs
@@ -4,7 +4,6 @@ use std::collections::HashSet;
 use syn::parse::{Parse, ParseStream, Result};
 use syn::{braced, parse_macro_input, Ident, LitStr, Token};
 
-#[allow(non_camel_case_types)]
 mod kw {
     syn::custom_keyword!(Keywords);
     syn::custom_keyword!(Symbols);
diff --git a/compiler/rustc_middle/src/infer/unify_key.rs b/compiler/rustc_middle/src/infer/unify_key.rs
index a60a17befef..4d884dde393 100644
--- a/compiler/rustc_middle/src/infer/unify_key.rs
+++ b/compiler/rustc_middle/src/infer/unify_key.rs
@@ -4,8 +4,9 @@ use rustc_data_structures::undo_log::UndoLogs;
 use rustc_data_structures::unify::{
     self, EqUnifyValue, InPlace, NoError, UnificationTable, UnifyKey, UnifyValue,
 };
+use rustc_span::def_id::DefId;
 use rustc_span::symbol::Symbol;
-use rustc_span::{Span, DUMMY_SP};
+use rustc_span::Span;
 
 use std::cmp;
 use std::marker::PhantomData;
@@ -124,8 +125,7 @@ pub struct ConstVariableOrigin {
 pub enum ConstVariableOriginKind {
     MiscVariable,
     ConstInference,
-    // FIXME(const_generics): Consider storing the `DefId` of the param here.
-    ConstParameterDefinition(Symbol),
+    ConstParameterDefinition(Symbol, DefId),
     SubstitutionPlaceholder,
 }
 
@@ -176,17 +176,17 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
     type Error = (&'tcx ty::Const<'tcx>, &'tcx ty::Const<'tcx>);
 
     fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
-        let val = match (value1.val, value2.val) {
+        let (val, span) = match (value1.val, value2.val) {
             (ConstVariableValue::Known { .. }, ConstVariableValue::Known { .. }) => {
                 bug!("equating two const variables, both of which have known values")
             }
 
             // If one side is known, prefer that one.
             (ConstVariableValue::Known { .. }, ConstVariableValue::Unknown { .. }) => {
-                Ok(value1.val)
+                (value1.val, value1.origin.span)
             }
             (ConstVariableValue::Unknown { .. }, ConstVariableValue::Known { .. }) => {
-                Ok(value2.val)
+                (value2.val, value2.origin.span)
             }
 
             // If both sides are *unknown*, it hardly matters, does it?
@@ -200,14 +200,14 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
                 // universe is the minimum of the two universes, because that is
                 // the one which contains the fewest names in scope.
                 let universe = cmp::min(universe1, universe2);
-                Ok(ConstVariableValue::Unknown { universe })
+                (ConstVariableValue::Unknown { universe }, value1.origin.span)
             }
-        }?;
+        };
 
         Ok(ConstVarValue {
             origin: ConstVariableOrigin {
                 kind: ConstVariableOriginKind::ConstInference,
-                span: DUMMY_SP,
+                span: span,
             },
             val,
         })
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 637ef4c17eb..492afa54445 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -2675,7 +2675,7 @@ impl<'tcx> ClosureKind {
         }
     }
 
-    /// Returns `true` if this a type that impls this closure kind
+    /// Returns `true` if a type that impls this closure kind
     /// must also implement `other`.
     pub fn extends(self, other: ty::ClosureKind) -> bool {
         match (self, other) {
diff --git a/compiler/rustc_middle/src/util/common.rs b/compiler/rustc_middle/src/util/common.rs
index 1e09702bf27..da857b0a403 100644
--- a/compiler/rustc_middle/src/util/common.rs
+++ b/compiler/rustc_middle/src/util/common.rs
@@ -1,5 +1,3 @@
-#![allow(non_camel_case_types)]
-
 use rustc_data_structures::sync::Lock;
 
 use std::fmt::Debug;
diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs
index da7bc1564c0..5f64eb3dba8 100644
--- a/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs
+++ b/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs
@@ -396,7 +396,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
     ) -> Option<RegionNameHighlight> {
         let mut highlight = RegionHighlightMode::default();
         highlight.highlighting_region_vid(needle_fr, counter);
-        let type_name = self.infcx.extract_type_name(&ty, Some(highlight)).0;
+        let type_name =
+            self.infcx.extract_inference_diagnostics_data(ty.into(), Some(highlight)).name;
 
         debug!(
             "highlight_if_we_cannot_match_hir_ty: type_name={:?} needle_fr={:?}",
@@ -404,7 +405,6 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
         );
         if type_name.find(&format!("'{}", counter)).is_some() {
             // Only add a label if we can confirm that a region was labelled.
-
             Some(RegionNameHighlight::CannotMatchHirTy(span, type_name))
         } else {
             None
@@ -646,7 +646,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
 
         let mut highlight = RegionHighlightMode::default();
         highlight.highlighting_region_vid(fr, *self.next_region_name.try_borrow().unwrap());
-        let type_name = self.infcx.extract_type_name(&return_ty, Some(highlight)).0;
+        let type_name =
+            self.infcx.extract_inference_diagnostics_data(return_ty.into(), Some(highlight)).name;
 
         let mir_hir_id = tcx.hir().local_def_id_to_hir_id(self.mir_def_id);
 
@@ -698,7 +699,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
 
         let mut highlight = RegionHighlightMode::default();
         highlight.highlighting_region_vid(fr, *self.next_region_name.try_borrow().unwrap());
-        let type_name = self.infcx.extract_type_name(&yield_ty, Some(highlight)).0;
+        let type_name =
+            self.infcx.extract_inference_diagnostics_data(yield_ty.into(), Some(highlight)).name;
 
         let mir_hir_id = tcx.hir().local_def_id_to_hir_id(self.mir_def_id);
 
diff --git a/compiler/rustc_mir/src/borrow_check/prefixes.rs b/compiler/rustc_mir/src/borrow_check/prefixes.rs
index 5bfe02ff3b0..6c5d42296f7 100644
--- a/compiler/rustc_mir/src/borrow_check/prefixes.rs
+++ b/compiler/rustc_mir/src/borrow_check/prefixes.rs
@@ -33,7 +33,6 @@ pub(super) struct Prefixes<'cx, 'tcx> {
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
-#[allow(dead_code)]
 pub(super) enum PrefixSet {
     /// Doesn't stop until it returns the base case (a Local or
     /// Static prefix).
diff --git a/compiler/rustc_mir/src/dataflow/move_paths/mod.rs b/compiler/rustc_mir/src/dataflow/move_paths/mod.rs
index d66d2625d78..7c630259186 100644
--- a/compiler/rustc_mir/src/dataflow/move_paths/mod.rs
+++ b/compiler/rustc_mir/src/dataflow/move_paths/mod.rs
@@ -144,7 +144,6 @@ impl<'tcx> fmt::Display for MovePath<'tcx> {
     }
 }
 
-#[allow(unused)]
 struct MovePathLinearIter<'a, 'tcx, F> {
     next: Option<(MovePathIndex, &'a MovePath<'tcx>)>,
     fetch_next: F,
diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs
index 496e620dd9d..1d741085853 100644
--- a/compiler/rustc_mir/src/transform/check_consts/ops.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs
@@ -113,6 +113,30 @@ impl NonConstOp for Abort {
 }
 
 #[derive(Debug)]
+pub struct FloatingPointOp;
+impl NonConstOp for FloatingPointOp {
+    const STOPS_CONST_CHECKING: bool = true;
+
+    fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
+        if ccx.const_kind() == hir::ConstContext::ConstFn {
+            Status::Unstable(sym::const_fn_floating_point_arithmetic)
+        } else {
+            Status::Allowed
+        }
+    }
+
+    fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
+        feature_err(
+            &ccx.tcx.sess.parse_sess,
+            sym::const_fn_floating_point_arithmetic,
+            span,
+            &format!("floating point arithmetic is not allowed in {}s", ccx.const_kind()),
+        )
+        .emit();
+    }
+}
+
+#[derive(Debug)]
 pub struct NonPrimitiveOp;
 impl NonConstOp for NonPrimitiveOp {
     const STOPS_CONST_CHECKING: bool = true;
diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs
index dc28ba46d7c..73725c7b98e 100644
--- a/compiler/rustc_mir/src/transform/check_consts/validation.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs
@@ -540,8 +540,12 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
 
             Rvalue::UnaryOp(_, ref operand) => {
                 let ty = operand.ty(self.body, self.tcx);
-                if !(ty.is_integral() || ty.is_bool()) {
-                    self.check_op(ops::NonPrimitiveOp)
+                if is_int_bool_or_char(ty) {
+                    // Int, bool, and char operations are fine.
+                } else if ty.is_floating_point() {
+                    self.check_op(ops::FloatingPointOp);
+                } else {
+                    span_bug!(self.span, "non-primitive type in `Rvalue::UnaryOp`: {:?}", ty);
                 }
             }
 
@@ -550,7 +554,9 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
                 let lhs_ty = lhs.ty(self.body, self.tcx);
                 let rhs_ty = rhs.ty(self.body, self.tcx);
 
-                if let ty::RawPtr(_) | ty::FnPtr(..) = lhs_ty.kind() {
+                if is_int_bool_or_char(lhs_ty) && is_int_bool_or_char(rhs_ty) {
+                    // Int, bool, and char operations are fine.
+                } else if lhs_ty.is_fn_ptr() || lhs_ty.is_unsafe_ptr() {
                     assert_eq!(lhs_ty, rhs_ty);
                     assert!(
                         op == BinOp::Eq
@@ -563,12 +569,15 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
                     );
 
                     self.check_op(ops::RawPtrComparison);
-                }
-
-                if !(lhs_ty.is_integral() || lhs_ty.is_bool() || lhs_ty.is_char())
-                    || !(rhs_ty.is_integral() || rhs_ty.is_bool() || rhs_ty.is_char())
-                {
-                    self.check_op(ops::NonPrimitiveOp)
+                } else if lhs_ty.is_floating_point() || rhs_ty.is_floating_point() {
+                    self.check_op(ops::FloatingPointOp);
+                } else {
+                    span_bug!(
+                        self.span,
+                        "non-primitive type in `Rvalue::BinaryOp`: {:?} ⚬ {:?}",
+                        lhs_ty,
+                        rhs_ty
+                    );
                 }
             }
         }
@@ -867,3 +876,7 @@ fn place_as_reborrow(
         }
     })
 }
+
+fn is_int_bool_or_char(ty: Ty<'_>) -> bool {
+    ty.is_bool() || ty.is_integral() || ty.is_char()
+}
diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs
index 284fca652ec..12a268d5b1d 100644
--- a/compiler/rustc_session/src/filesearch.rs
+++ b/compiler/rustc_session/src/filesearch.rs
@@ -1,5 +1,3 @@
-#![allow(non_camel_case_types)]
-
 pub use self::FileMatch::*;
 
 use std::borrow::Cow;
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 602bb4a44a9..12134a85f45 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -352,6 +352,7 @@ symbols! {
         const_evaluatable_checked,
         const_extern_fn,
         const_fn,
+        const_fn_floating_point_arithmetic,
         const_fn_transmute,
         const_fn_union,
         const_generics,
diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index 35bfeff10b4..e40067202e1 100644
--- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs
+++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
@@ -32,6 +32,7 @@ pub enum AutoTraitResult<A> {
     NegativeImpl,
 }
 
+#[allow(dead_code)]
 impl<A> AutoTraitResult<A> {
     fn is_auto(&self) -> bool {
         match *self {
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index bda4351b2f2..1b234a1535c 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -20,7 +20,6 @@ use rustc_hir::Node;
 use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::ty::error::ExpectedFound;
 use rustc_middle::ty::fold::TypeFolder;
-use rustc_middle::ty::subst::GenericArgKind;
 use rustc_middle::ty::{
     self, fast_reject, AdtKind, SubtypePredicate, ToPolyTraitRef, ToPredicate, Ty, TyCtxt,
     TypeFoldable, WithConstness,
@@ -1513,10 +1512,21 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
                 // check upstream for type errors and don't add the obligations to
                 // begin with in those cases.
                 if self.tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) {
-                    self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0282).emit();
+                    self.emit_inference_failure_err(
+                        body_id,
+                        span,
+                        self_ty.into(),
+                        ErrorCode::E0282,
+                    )
+                    .emit();
                     return;
                 }
-                let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0283);
+                let mut err = self.emit_inference_failure_err(
+                    body_id,
+                    span,
+                    self_ty.into(),
+                    ErrorCode::E0283,
+                );
                 err.note(&format!("cannot satisfy `{}`", predicate));
                 if let ObligationCauseCode::ItemObligation(def_id) = obligation.cause.code {
                     self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id());
@@ -1580,17 +1590,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
                     return;
                 }
 
-                match arg.unpack() {
-                    GenericArgKind::Lifetime(lt) => {
-                        span_bug!(span, "unexpected well formed predicate: {:?}", lt)
-                    }
-                    GenericArgKind::Type(ty) => {
-                        self.need_type_info_err(body_id, span, ty, ErrorCode::E0282)
-                    }
-                    GenericArgKind::Const(ct) => {
-                        self.need_type_info_err_const(body_id, span, ct, ErrorCode::E0282)
-                    }
-                }
+                self.emit_inference_failure_err(body_id, span, arg, ErrorCode::E0282)
             }
 
             ty::PredicateAtom::Subtype(data) => {
@@ -1601,7 +1601,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
                 let SubtypePredicate { a_is_expected: _, a, b } = data;
                 // both must be type variables, or the other would've been instantiated
                 assert!(a.is_ty_var() && b.is_ty_var());
-                self.need_type_info_err(body_id, span, a, ErrorCode::E0282)
+                self.emit_inference_failure_err(body_id, span, a.into(), ErrorCode::E0282)
             }
             ty::PredicateAtom::Projection(data) => {
                 let trait_ref = ty::Binder::bind(data).to_poly_trait_ref(self.tcx);
@@ -1612,7 +1612,12 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
                 }
                 if self_ty.needs_infer() && ty.needs_infer() {
                     // We do this for the `foo.collect()?` case to produce a suggestion.
-                    let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0284);
+                    let mut err = self.emit_inference_failure_err(
+                        body_id,
+                        span,
+                        self_ty.into(),
+                        ErrorCode::E0284,
+                    );
                     err.note(&format!("cannot satisfy `{}`", predicate));
                     err
                 } else {
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 79495ba7f9b..c93087a18cf 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -2,7 +2,6 @@
 //!
 //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/resolution.html
 
-#[allow(dead_code)]
 pub mod auto_trait;
 mod chalk_fulfill;
 pub mod codegen;
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 5e2f7d81d00..57f1fedacbe 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -2148,7 +2148,6 @@ trait TraitObligationExt<'tcx> {
 }
 
 impl<'tcx> TraitObligationExt<'tcx> for TraitObligation<'tcx> {
-    #[allow(unused_comparisons)]
     fn derived_cause(
         &self,
         variant: fn(DerivedObligationCause<'tcx>) -> ObligationCauseCode<'tcx>,
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt.rs b/compiler/rustc_typeck/src/check/fn_ctxt.rs
index a03b8064b59..79d6c7dbfda 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt.rs
@@ -2991,7 +2991,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             ty
         } else {
             if !self.is_tainted_by_errors() {
-                self.need_type_info_err((**self).body_id, sp, ty, E0282)
+                self.emit_inference_failure_err((**self).body_id, sp, ty.into(), E0282)
                     .note("type must be known at this point")
                     .emit();
             }
diff --git a/compiler/rustc_typeck/src/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs
index b55f62ee436..6fd7277a1c3 100644
--- a/compiler/rustc_typeck/src/check/writeback.rs
+++ b/compiler/rustc_typeck/src/check/writeback.rs
@@ -653,7 +653,12 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
     fn report_type_error(&self, t: Ty<'tcx>) {
         if !self.tcx.sess.has_errors() {
             self.infcx
-                .need_type_info_err(Some(self.body.id()), self.span.to_span(self.tcx), t, E0282)
+                .emit_inference_failure_err(
+                    Some(self.body.id()),
+                    self.span.to_span(self.tcx),
+                    t.into(),
+                    E0282,
+                )
                 .emit();
         }
     }
@@ -661,10 +666,10 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
     fn report_const_error(&self, c: &'tcx ty::Const<'tcx>) {
         if !self.tcx.sess.has_errors() {
             self.infcx
-                .need_type_info_err_const(
+                .emit_inference_failure_err(
                     Some(self.body.id()),
                     self.span.to_span(self.tcx),
-                    c,
+                    c.into(),
                     E0282,
                 )
                 .emit();
diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs
index 84efb92582e..e8fa2b13a9f 100644
--- a/compiler/rustc_typeck/src/lib.rs
+++ b/compiler/rustc_typeck/src/lib.rs
@@ -56,7 +56,6 @@ This API is completely unstable and subject to change.
 */
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
-#![allow(non_camel_case_types)]
 #![feature(bool_to_option)]
 #![feature(box_syntax)]
 #![feature(crate_visibility_modifier)]
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 63ca6e517d2..30fb87b0226 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -82,6 +82,7 @@
 #![feature(const_pin)]
 #![feature(const_fn_union)]
 #![feature(const_fn)]
+#![cfg_attr(not(bootstrap), feature(const_fn_floating_point_arithmetic))]
 #![feature(const_generics)]
 #![feature(const_option)]
 #![feature(const_precise_live_drops)]
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index b1589008be0..0cfb4af59b9 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -70,10 +70,23 @@
 //! }
 //! ```
 //!
-//! This usage of [`Option`] to create safe nullable pointers is so
-//! common that Rust does special optimizations to make the
-//! representation of [`Option`]`<`[`Box<T>`]`>` a single pointer. Optional pointers
-//! in Rust are stored as efficiently as any other pointer type.
+//! # Representation
+//!
+//! Rust guarantees to optimize the following types `T` such that
+//! [`Option<T>`] has the same size as `T`:
+//!
+//! * [`Box<U>`]
+//! * `&U`
+//! * `&mut U`
+//! * `fn`, `extern "C" fn`
+//! * [`num::NonZero*`]
+//! * [`ptr::NonNull<U>`]
+//! * `#[repr(transparent)]` struct around one of the types in this list.
+//!
+//! It is further guaranteed that, for the cases above, one can
+//! [`mem::transmute`] from all valid values of `T` to `Option<T>` and
+//! from `Some::<T>(_)` to `T` (but transmuting `None::<T>` to `T`
+//! is undefined behaviour).
 //!
 //! # Examples
 //!
diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs
index 76b8aa7d821..793cbf99495 100644
--- a/library/core/src/slice/iter.rs
+++ b/library/core/src/slice/iter.rs
@@ -319,6 +319,13 @@ pub(super) trait SplitIter: DoubleEndedIterator {
 ///
 /// This struct is created by the [`split`] method on [slices].
 ///
+/// # Example
+///
+/// ```
+/// let slice = [10, 40, 33, 20];
+/// let mut iter = slice.split(|num| num % 3 == 0);
+/// ```
+///
 /// [`split`]: ../../std/primitive.slice.html#method.split
 /// [slices]: ../../std/primitive.slice.html
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -434,6 +441,15 @@ impl<T, P> FusedIterator for Split<'_, T, P> where P: FnMut(&T) -> bool {}
 ///
 /// This struct is created by the [`split_inclusive`] method on [slices].
 ///
+/// # Example
+///
+/// ```
+/// #![feature(split_inclusive)]
+///
+/// let slice = [10, 40, 33, 20];
+/// let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+/// ```
+///
 /// [`split_inclusive`]: ../../std/primitive.slice.html#method.split_inclusive
 /// [slices]: ../../std/primitive.slice.html
 #[unstable(feature = "split_inclusive", issue = "72360")]
@@ -539,6 +555,13 @@ impl<T, P> FusedIterator for SplitInclusive<'_, T, P> where P: FnMut(&T) -> bool
 ///
 /// This struct is created by the [`split_mut`] method on [slices].
 ///
+/// # Example
+///
+/// ```
+/// let mut v = [10, 40, 30, 20, 60, 50];
+/// let iter = v.split_mut(|num| *num % 3 == 0);
+/// ```
+///
 /// [`split_mut`]: ../../std/primitive.slice.html#method.split_mut
 /// [slices]: ../../std/primitive.slice.html
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -661,6 +684,15 @@ impl<T, P> FusedIterator for SplitMut<'_, T, P> where P: FnMut(&T) -> bool {}
 ///
 /// This struct is created by the [`split_inclusive_mut`] method on [slices].
 ///
+/// # Example
+///
+/// ```
+/// #![feature(split_inclusive)]
+///
+/// let mut v = [10, 40, 30, 20, 60, 50];
+/// let iter = v.split_inclusive_mut(|num| *num % 3 == 0);
+/// ```
+///
 /// [`split_inclusive_mut`]: ../../std/primitive.slice.html#method.split_inclusive_mut
 /// [slices]: ../../std/primitive.slice.html
 #[unstable(feature = "split_inclusive", issue = "72360")]
@@ -775,6 +807,13 @@ impl<T, P> FusedIterator for SplitInclusiveMut<'_, T, P> where P: FnMut(&T) -> b
 ///
 /// This struct is created by the [`rsplit`] method on [slices].
 ///
+/// # Example
+///
+/// ```
+/// let slice = [11, 22, 33, 0, 44, 55];
+/// let iter = slice.rsplit(|num| *num == 0);
+/// ```
+///
 /// [`rsplit`]: ../../std/primitive.slice.html#method.rsplit
 /// [slices]: ../../std/primitive.slice.html
 #[stable(feature = "slice_rsplit", since = "1.27.0")]
@@ -854,6 +893,13 @@ impl<T, P> FusedIterator for RSplit<'_, T, P> where P: FnMut(&T) -> bool {}
 ///
 /// This struct is created by the [`rsplit_mut`] method on [slices].
 ///
+/// # Example
+///
+/// ```
+/// let mut slice = [11, 22, 33, 0, 44, 55];
+/// let iter = slice.rsplit_mut(|num| *num == 0);
+/// ```
+///
 /// [`rsplit_mut`]: ../../std/primitive.slice.html#method.rsplit_mut
 /// [slices]: ../../std/primitive.slice.html
 #[stable(feature = "slice_rsplit", since = "1.27.0")]
@@ -966,6 +1012,13 @@ impl<T, I: SplitIter<Item = T>> Iterator for GenericSplitN<I> {
 ///
 /// This struct is created by the [`splitn`] method on [slices].
 ///
+/// # Example
+///
+/// ```
+/// let slice = [10, 40, 30, 20, 60, 50];
+/// let iter = slice.splitn(2, |num| *num % 3 == 0);
+/// ```
+///
 /// [`splitn`]: ../../std/primitive.slice.html#method.splitn
 /// [slices]: ../../std/primitive.slice.html
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -999,6 +1052,13 @@ where
 ///
 /// This struct is created by the [`rsplitn`] method on [slices].
 ///
+/// # Example
+///
+/// ```
+/// let slice = [10, 40, 30, 20, 60, 50];
+/// let iter = slice.rsplitn(2, |num| *num % 3 == 0);
+/// ```
+///
 /// [`rsplitn`]: ../../std/primitive.slice.html#method.rsplitn
 /// [slices]: ../../std/primitive.slice.html
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1031,6 +1091,13 @@ where
 ///
 /// This struct is created by the [`splitn_mut`] method on [slices].
 ///
+/// # Example
+///
+/// ```
+/// let mut slice = [10, 40, 30, 20, 60, 50];
+/// let iter = slice.splitn_mut(2, |num| *num % 3 == 0);
+/// ```
+///
 /// [`splitn_mut`]: ../../std/primitive.slice.html#method.splitn_mut
 /// [slices]: ../../std/primitive.slice.html
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1064,6 +1131,13 @@ where
 ///
 /// This struct is created by the [`rsplitn_mut`] method on [slices].
 ///
+/// # Example
+///
+/// ```
+/// let mut slice = [10, 40, 30, 20, 60, 50];
+/// let iter = slice.rsplitn_mut(2, |num| *num % 3 == 0);
+/// ```
+///
 /// [`rsplitn_mut`]: ../../std/primitive.slice.html#method.rsplitn_mut
 /// [slices]: ../../std/primitive.slice.html
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1100,6 +1174,13 @@ forward_iterator! { RSplitNMut: T, &'a mut [T] }
 ///
 /// This struct is created by the [`windows`] method on [slices].
 ///
+/// # Example
+///
+/// ```
+/// let slice = ['r', 'u', 's', 't'];
+/// let iter = slice.windows(2);
+/// ```
+///
 /// [`windows`]: ../../std/primitive.slice.html#method.windows
 /// [slices]: ../../std/primitive.slice.html
 #[derive(Debug)]
@@ -1239,6 +1320,13 @@ unsafe impl<'a, T> TrustedRandomAccess for Windows<'a, T> {
 ///
 /// This struct is created by the [`chunks`] method on [slices].
 ///
+/// # Example
+///
+/// ```
+/// let slice = ['l', 'o', 'r', 'e', 'm'];
+/// let iter = slice.chunks(2);
+/// ```
+///
 /// [`chunks`]: ../../std/primitive.slice.html#method.chunks
 /// [slices]: ../../std/primitive.slice.html
 #[derive(Debug)]
@@ -1400,6 +1488,13 @@ unsafe impl<'a, T> TrustedRandomAccess for Chunks<'a, T> {
 ///
 /// This struct is created by the [`chunks_mut`] method on [slices].
 ///
+/// # Example
+///
+/// ```
+/// let mut slice = ['l', 'o', 'r', 'e', 'm'];
+/// let iter = slice.chunks_mut(2);
+/// ```
+///
 /// [`chunks_mut`]: ../../std/primitive.slice.html#method.chunks_mut
 /// [slices]: ../../std/primitive.slice.html
 #[derive(Debug)]
@@ -1559,6 +1654,13 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksMut<'a, T> {
 ///
 /// This struct is created by the [`chunks_exact`] method on [slices].
 ///
+/// # Example
+///
+/// ```
+/// let slice = ['l', 'o', 'r', 'e', 'm'];
+/// let iter = slice.chunks_exact(2);
+/// ```
+///
 /// [`chunks_exact`]: ../../std/primitive.slice.html#method.chunks_exact
 /// [`remainder`]: ChunksExact::remainder
 /// [slices]: ../../std/primitive.slice.html
@@ -1708,6 +1810,13 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExact<'a, T> {
 ///
 /// This struct is created by the [`chunks_exact_mut`] method on [slices].
 ///
+/// # Example
+///
+/// ```
+/// let mut slice = ['l', 'o', 'r', 'e', 'm'];
+/// let iter = slice.chunks_exact_mut(2);
+/// ```
+///
 /// [`chunks_exact_mut`]: ../../std/primitive.slice.html#method.chunks_exact_mut
 /// [`into_remainder`]: ChunksExactMut::into_remainder
 /// [slices]: ../../std/primitive.slice.html
@@ -1850,6 +1959,15 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> {
 ///
 /// This struct is created by the [`array_windows`] method on [slices].
 ///
+/// # Example
+///
+/// ```
+/// #![feature(array_windows)]
+///
+/// let slice = [0, 1, 2, 3];
+/// let iter = slice.array_windows::<2>();
+/// ```
+///
 /// [`array_windows`]: ../../std/primitive.slice.html#method.array_windows
 /// [slices]: ../../std/primitive.slice.html
 #[derive(Debug, Clone, Copy)]
@@ -1962,6 +2080,15 @@ impl<T, const N: usize> ExactSizeIterator for ArrayWindows<'_, T, N> {
 ///
 /// This struct is created by the [`array_chunks`] method on [slices].
 ///
+/// # Example
+///
+/// ```
+/// #![feature(array_chunks)]
+///
+/// let slice = ['l', 'o', 'r', 'e', 'm'];
+/// let iter = slice.array_chunks::<2>();
+/// ```
+///
 /// [`array_chunks`]: ../../std/primitive.slice.html#method.array_chunks
 /// [`remainder`]: ArrayChunks::remainder
 /// [slices]: ../../std/primitive.slice.html
@@ -2080,6 +2207,15 @@ unsafe impl<'a, T, const N: usize> TrustedRandomAccess for ArrayChunks<'a, T, N>
 ///
 /// This struct is created by the [`array_chunks_mut`] method on [slices].
 ///
+/// # Example
+///
+/// ```
+/// #![feature(array_chunks)]
+///
+/// let mut slice = ['l', 'o', 'r', 'e', 'm'];
+/// let iter = slice.array_chunks_mut::<2>();
+/// ```
+///
 /// [`array_chunks_mut`]: ../../std/primitive.slice.html#method.array_chunks_mut
 /// [`into_remainder`]: ../../std/slice/struct.ArrayChunksMut.html#method.into_remainder
 /// [slices]: ../../std/primitive.slice.html
@@ -2190,6 +2326,13 @@ unsafe impl<'a, T, const N: usize> TrustedRandomAccess for ArrayChunksMut<'a, T,
 ///
 /// This struct is created by the [`rchunks`] method on [slices].
 ///
+/// # Example
+///
+/// ```
+/// let slice = ['l', 'o', 'r', 'e', 'm'];
+/// let iter = slice.rchunks(2);
+/// ```
+///
 /// [`rchunks`]: ../../std/primitive.slice.html#method.rchunks
 /// [slices]: ../../std/primitive.slice.html
 #[derive(Debug)]
@@ -2347,6 +2490,13 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunks<'a, T> {
 ///
 /// This struct is created by the [`rchunks_mut`] method on [slices].
 ///
+/// # Example
+///
+/// ```
+/// let mut slice = ['l', 'o', 'r', 'e', 'm'];
+/// let iter = slice.rchunks_mut(2);
+/// ```
+///
 /// [`rchunks_mut`]: ../../std/primitive.slice.html#method.rchunks_mut
 /// [slices]: ../../std/primitive.slice.html
 #[derive(Debug)]
@@ -2504,6 +2654,13 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksMut<'a, T> {
 ///
 /// This struct is created by the [`rchunks_exact`] method on [slices].
 ///
+/// # Example
+///
+/// ```
+/// let slice = ['l', 'o', 'r', 'e', 'm'];
+/// let iter = slice.rchunks_exact(2);
+/// ```
+///
 /// [`rchunks_exact`]: ../../std/primitive.slice.html#method.rchunks_exact
 /// [`remainder`]: ChunksExact::remainder
 /// [slices]: ../../std/primitive.slice.html
@@ -2657,6 +2814,13 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExact<'a, T> {
 ///
 /// This struct is created by the [`rchunks_exact_mut`] method on [slices].
 ///
+/// # Example
+///
+/// ```
+/// let mut slice = ['l', 'o', 'r', 'e', 'm'];
+/// let iter = slice.rchunks_exact_mut(2);
+/// ```
+///
 /// [`rchunks_exact_mut`]: ../../std/primitive.slice.html#method.rchunks_exact_mut
 /// [`into_remainder`]: ChunksExactMut::into_remainder
 /// [slices]: ../../std/primitive.slice.html
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index ac0075ad129..d03428dd082 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -236,6 +236,7 @@
 #![feature(clamp)]
 #![feature(concat_idents)]
 #![feature(const_cstr_unchecked)]
+#![cfg_attr(not(bootstrap), feature(const_fn_floating_point_arithmetic))]
 #![feature(const_fn_transmute)]
 #![feature(const_fn)]
 #![feature(const_ip)]
diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs
index 2a4cb22cc52..81bbf376378 100644
--- a/library/std/src/primitive_docs.rs
+++ b/library/std/src/primitive_docs.rs
@@ -384,6 +384,7 @@ mod prim_char {}
 #[stable(feature = "rust1", since = "1.0.0")]
 mod prim_unit {}
 
+#[doc(alias = "ptr")]
 #[doc(primitive = "pointer")]
 //
 /// Raw, unsafe pointers, `*const T`, and `*mut T`.
diff --git a/src/bootstrap/CHANGELOG.md b/src/bootstrap/CHANGELOG.md
index 1510f4d59fa..dfb39c54c17 100644
--- a/src/bootstrap/CHANGELOG.md
+++ b/src/bootstrap/CHANGELOG.md
@@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 
 ## [Non-breaking changes since the last major version]
 
+- Add `x.py setup` [#76631](https://github.com/rust-lang/rust/pull/76631)
 - Add a changelog for x.py [#76626](https://github.com/rust-lang/rust/pull/76626)
 - Optionally, download LLVM from CI on Linux and NixOS
   + [#76439](https://github.com/rust-lang/rust/pull/76349)
diff --git a/src/bootstrap/bin/main.rs b/src/bootstrap/bin/main.rs
index 6af13fc83d0..637083e08d5 100644
--- a/src/bootstrap/bin/main.rs
+++ b/src/bootstrap/bin/main.rs
@@ -7,21 +7,34 @@
 
 use std::env;
 
-use bootstrap::{Build, Config};
+use bootstrap::{Build, Config, Subcommand};
 
 fn main() {
     let args = env::args().skip(1).collect::<Vec<_>>();
     let config = Config::parse(&args);
 
     let changelog_suggestion = check_version(&config);
-    if let Some(suggestion) = &changelog_suggestion {
+
+    // NOTE: Since `./configure` generates a `config.toml`, distro maintainers will see the
+    // changelog warning, not the `x.py setup` message.
+    let suggest_setup = !config.config.exists() && !matches!(config.cmd, Subcommand::Setup { .. });
+    if suggest_setup {
+        println!("warning: you have not made a `config.toml`");
+        println!("help: consider running `x.py setup` or copying `config.toml.example`");
+    } else if let Some(suggestion) = &changelog_suggestion {
         println!("{}", suggestion);
     }
 
     Build::new(config).build();
 
-    if let Some(suggestion) = changelog_suggestion {
+    if suggest_setup {
+        println!("warning: you have not made a `config.toml`");
+        println!("help: consider running `x.py setup` or copying `config.toml.example`");
+    } else if let Some(suggestion) = &changelog_suggestion {
         println!("{}", suggestion);
+    }
+
+    if suggest_setup || changelog_suggestion.is_some() {
         println!("note: this message was printed twice to make it more likely to be seen");
     }
 }
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index d2537d65e67..4aaaeb8a93b 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -549,7 +549,9 @@ impl<'a> Builder<'a> {
             Subcommand::Dist { ref paths } => (Kind::Dist, &paths[..]),
             Subcommand::Install { ref paths } => (Kind::Install, &paths[..]),
             Subcommand::Run { ref paths } => (Kind::Run, &paths[..]),
-            Subcommand::Format { .. } | Subcommand::Clean { .. } => panic!(),
+            Subcommand::Format { .. } | Subcommand::Clean { .. } | Subcommand::Setup { .. } => {
+                panic!()
+            }
         };
 
         Self::new_internal(build, kind, paths.to_owned())
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 53fef7a838d..b14746dabb9 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -73,6 +73,8 @@ pub struct Config {
     pub keep_stage: Vec<u32>,
     pub keep_stage_std: Vec<u32>,
     pub src: PathBuf,
+    // defaults to `config.toml`
+    pub config: PathBuf,
     pub jobs: Option<u32>,
     pub cmd: Subcommand,
     pub incremental: bool,
@@ -513,6 +515,7 @@ impl Config {
         config.rust_codegen_backends = vec![INTERNER.intern_str("llvm")];
         config.deny_warnings = true;
         config.missing_tools = false;
+        config.config = PathBuf::from("config.toml");
 
         // set by bootstrap.py
         config.build = TargetSelection::from_user(&env!("BUILD_TRIPLE"));
@@ -558,7 +561,7 @@ impl Config {
         let get_toml = |file: PathBuf| {
             use std::process;
 
-            let contents = t!(fs::read_to_string(&file), "configuration file did not exist");
+            let contents = t!(fs::read_to_string(&file), "`include` config not found");
             match toml::from_str(&contents) {
                 Ok(table) => table,
                 Err(err) => {
@@ -644,6 +647,7 @@ impl Config {
             | Subcommand::Clippy { .. }
             | Subcommand::Fix { .. }
             | Subcommand::Run { .. }
+            | Subcommand::Setup { .. }
             | Subcommand::Format { .. } => flags.stage.unwrap_or(0),
         };
 
@@ -668,6 +672,7 @@ impl Config {
                 | Subcommand::Clippy { .. }
                 | Subcommand::Fix { .. }
                 | Subcommand::Run { .. }
+                | Subcommand::Setup { .. }
                 | Subcommand::Format { .. } => {}
             }
         }
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index dad31fc77be..a12fc50afad 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -7,6 +7,7 @@ use std::env;
 use std::path::PathBuf;
 use std::process;
 
+use build_helper::t;
 use getopts::Options;
 
 use crate::builder::Builder;
@@ -89,6 +90,9 @@ pub enum Subcommand {
     Run {
         paths: Vec<PathBuf>,
     },
+    Setup {
+        path: String,
+    },
 }
 
 impl Default for Subcommand {
@@ -199,6 +203,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`",
                 || (s == "install")
                 || (s == "run")
                 || (s == "r")
+                || (s == "setup")
         });
         let subcommand = match subcommand {
             Some(s) => s,
@@ -453,10 +458,21 @@ Arguments:
     At least a tool needs to be called.",
                 );
             }
+            "setup" => {
+                subcommand_help.push_str(
+                    "\n
+Arguments:
+    This subcommand accepts a 'profile' to use for builds. For example:
+
+        ./x.py setup library
+
+    The profile is optional and you will be prompted interactively if it is not given.",
+                );
+            }
             _ => {}
         };
         // Get any optional paths which occur after the subcommand
-        let paths = matches.free[1..].iter().map(|p| p.into()).collect::<Vec<PathBuf>>();
+        let mut paths = matches.free[1..].iter().map(|p| p.into()).collect::<Vec<PathBuf>>();
 
         let cfg_file = env::var_os("BOOTSTRAP_CONFIG").map(PathBuf::from);
         let verbose = matches.opt_present("verbose");
@@ -508,6 +524,20 @@ Arguments:
                 }
                 Subcommand::Run { paths }
             }
+            "setup" => {
+                let path = if paths.len() > 1 {
+                    println!("\nat most one profile can be passed to setup\n");
+                    usage(1, &opts, verbose, &subcommand_help)
+                } else if let Some(path) = paths.pop() {
+                    t!(path.into_os_string().into_string().map_err(|path| format!(
+                        "{} is not a valid UTF8 string",
+                        path.to_string_lossy()
+                    )))
+                } else {
+                    t!(crate::setup::interactive_path())
+                };
+                Subcommand::Setup { path }
+            }
             _ => {
                 usage(1, &opts, verbose, &subcommand_help);
             }
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 3f7aeae0ed4..4cc72f5f39c 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -141,6 +141,7 @@ mod metadata;
 mod native;
 mod run;
 mod sanity;
+mod setup;
 mod test;
 mod tool;
 mod toolstate;
@@ -165,7 +166,7 @@ mod job {
 
 use crate::cache::{Interned, INTERNER};
 pub use crate::config::Config;
-use crate::flags::Subcommand;
+pub use crate::flags::Subcommand;
 
 const LLVM_TOOLS: &[&str] = &[
     "llvm-nm", // used to inspect binaries; it shows symbol names, their sizes and visibility
@@ -470,6 +471,10 @@ impl Build {
             return clean::clean(self, all);
         }
 
+        if let Subcommand::Setup { path: include_name } = &self.config.cmd {
+            return setup::setup(&self.config.src, include_name);
+        }
+
         {
             let builder = builder::Builder::new(&self);
             if let Some(path) = builder.paths.get(0) {
diff --git a/src/bootstrap/run.rs b/src/bootstrap/run.rs
index 90053471427..ba593cadbad 100644
--- a/src/bootstrap/run.rs
+++ b/src/bootstrap/run.rs
@@ -10,7 +10,7 @@ impl Step for ExpandYamlAnchors {
 
     /// Runs the `expand-yaml_anchors` tool.
     ///
-    /// This tool in `src/tools` read the CI configuration files written in YAML and expands the
+    /// This tool in `src/tools` reads the CI configuration files written in YAML and expands the
     /// anchors in them, since GitHub Actions doesn't support them.
     fn run(self, builder: &Builder<'_>) {
         builder.info("Expanding YAML anchors in the GitHub Actions configuration");
diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs
new file mode 100644
index 00000000000..9d3a889aa00
--- /dev/null
+++ b/src/bootstrap/setup.rs
@@ -0,0 +1,88 @@
+use crate::t;
+use std::path::{Path, PathBuf};
+use std::{
+    env, fs,
+    io::{self, Write},
+};
+
+pub fn setup(src_path: &Path, include_name: &str) {
+    let cfg_file = env::var_os("BOOTSTRAP_CONFIG").map(PathBuf::from);
+
+    if cfg_file.as_ref().map_or(false, |f| f.exists()) {
+        let file = cfg_file.unwrap();
+        println!(
+            "error: you asked `x.py` to setup a new config file, but one already exists at `{}`",
+            file.display()
+        );
+        println!(
+            "help: try adding `profile = \"{}\"` at the top of {}",
+            include_name,
+            file.display()
+        );
+        println!(
+            "note: this will use the configuration in {}/src/bootstrap/defaults/config.toml.{}",
+            src_path.display(),
+            include_name
+        );
+        std::process::exit(1);
+    }
+
+    let path = cfg_file.unwrap_or_else(|| src_path.join("config.toml"));
+    let settings = format!(
+        "# Includes one of the default files in src/bootstrap/defaults\n\
+    profile = \"{}\"\n",
+        include_name
+    );
+    t!(fs::write(path, settings));
+
+    let include_path =
+        format!("{}/src/bootstrap/defaults/config.toml.{}", src_path.display(), include_name);
+    println!("`x.py` will now use the configuration at {}", include_path);
+
+    let suggestions = match include_name {
+        "codegen" | "compiler" => &["check", "build", "test"][..],
+        "library" => &["check", "build", "test library/std", "doc"],
+        "user" => &["dist", "build"],
+        _ => return,
+    };
+
+    println!("To get started, try one of the following commands:");
+    for cmd in suggestions {
+        println!("- `x.py {}`", cmd);
+    }
+
+    if include_name != "user" {
+        println!(
+            "For more suggestions, see https://rustc-dev-guide.rust-lang.org/building/suggested.html"
+        );
+    }
+}
+
+// Used to get the path for `Subcommand::Setup`
+pub fn interactive_path() -> io::Result<String> {
+    let mut input = String::new();
+    println!(
+        "Welcome to the Rust project! What do you want to do with x.py?
+a) Contribute to the standard library
+b) Contribute to the compiler
+c) Contribute to the compiler, and also modify LLVM or codegen
+d) Install Rust from source"
+    );
+    let template = loop {
+        print!("Please choose one (a/b/c/d): ");
+        io::stdout().flush()?;
+        io::stdin().read_line(&mut input)?;
+        break match input.trim().to_lowercase().as_str() {
+            "a" | "lib" | "library" => "library",
+            "b" | "compiler" => "compiler",
+            "c" | "llvm" => "llvm",
+            "d" | "user" | "maintainer" => "maintainer",
+            _ => {
+                println!("error: unrecognized option '{}'", input.trim());
+                println!("note: press Ctrl+C to exit");
+                continue;
+            }
+        };
+    };
+    Ok(template.to_owned())
+}
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 46ba14aa67e..788bb5e787b 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -256,7 +256,7 @@ impl Clean<Item> for doctree::Module<'_> {
 
         // determine if we should display the inner contents or
         // the outer `mod` item for the source code.
-        let whence = {
+        let span = {
             let sm = cx.sess().source_map();
             let outer = sm.lookup_char_pos(self.where_outer.lo());
             let inner = sm.lookup_char_pos(self.where_inner.lo());
@@ -272,7 +272,7 @@ impl Clean<Item> for doctree::Module<'_> {
         Item {
             name: Some(name),
             attrs,
-            source: whence.clean(cx),
+            source: span.clean(cx),
             visibility: self.vis.clean(cx),
             stability: cx.stability(self.id).clean(cx),
             deprecation: cx.deprecation(self.id).clean(cx),
@@ -912,7 +912,7 @@ impl Clean<Item> for doctree::Function<'_> {
         Item {
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
-            source: self.whence.clean(cx),
+            source: self.span.clean(cx),
             visibility: self.vis.clean(cx),
             stability: cx.stability(self.id).clean(cx),
             deprecation: cx.deprecation(self.id).clean(cx),
@@ -1020,7 +1020,7 @@ impl Clean<Item> for doctree::Trait<'_> {
         Item {
             name: Some(self.name.clean(cx)),
             attrs,
-            source: self.whence.clean(cx),
+            source: self.span.clean(cx),
             def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
             visibility: self.vis.clean(cx),
             stability: cx.stability(self.id).clean(cx),
@@ -1044,7 +1044,7 @@ impl Clean<Item> for doctree::TraitAlias<'_> {
         Item {
             name: Some(self.name.clean(cx)),
             attrs,
-            source: self.whence.clean(cx),
+            source: self.span.clean(cx),
             def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
             visibility: self.vis.clean(cx),
             stability: cx.stability(self.id).clean(cx),
@@ -1830,7 +1830,7 @@ impl Clean<Item> for doctree::Struct<'_> {
         Item {
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
-            source: self.whence.clean(cx),
+            source: self.span.clean(cx),
             def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
             visibility: self.vis.clean(cx),
             stability: cx.stability(self.id).clean(cx),
@@ -1850,7 +1850,7 @@ impl Clean<Item> for doctree::Union<'_> {
         Item {
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
-            source: self.whence.clean(cx),
+            source: self.span.clean(cx),
             def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
             visibility: self.vis.clean(cx),
             stability: cx.stability(self.id).clean(cx),
@@ -1880,7 +1880,7 @@ impl Clean<Item> for doctree::Enum<'_> {
         Item {
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
-            source: self.whence.clean(cx),
+            source: self.span.clean(cx),
             def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
             visibility: self.vis.clean(cx),
             stability: cx.stability(self.id).clean(cx),
@@ -1899,7 +1899,7 @@ impl Clean<Item> for doctree::Variant<'_> {
         Item {
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
-            source: self.whence.clean(cx),
+            source: self.span.clean(cx),
             visibility: Inherited,
             stability: cx.stability(self.id).clean(cx),
             deprecation: cx.deprecation(self.id).clean(cx),
@@ -2047,7 +2047,7 @@ impl Clean<Item> for doctree::Typedef<'_> {
         Item {
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
-            source: self.whence.clean(cx),
+            source: self.span.clean(cx),
             def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
             visibility: self.vis.clean(cx),
             stability: cx.stability(self.id).clean(cx),
@@ -2062,7 +2062,7 @@ impl Clean<Item> for doctree::OpaqueTy<'_> {
         Item {
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
-            source: self.whence.clean(cx),
+            source: self.span.clean(cx),
             def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
             visibility: self.vis.clean(cx),
             stability: cx.stability(self.id).clean(cx),
@@ -2093,7 +2093,7 @@ impl Clean<Item> for doctree::Static<'_> {
         Item {
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
-            source: self.whence.clean(cx),
+            source: self.span.clean(cx),
             def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
             visibility: self.vis.clean(cx),
             stability: cx.stability(self.id).clean(cx),
@@ -2114,7 +2114,7 @@ impl Clean<Item> for doctree::Constant<'_> {
         Item {
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
-            source: self.whence.clean(cx),
+            source: self.span.clean(cx),
             def_id: def_id.to_def_id(),
             visibility: self.vis.clean(cx),
             stability: cx.stability(self.id).clean(cx),
@@ -2168,7 +2168,7 @@ impl Clean<Vec<Item>> for doctree::Impl<'_> {
         let make_item = |trait_: Option<Type>, for_: Type, items: Vec<Item>| Item {
             name: None,
             attrs: self.attrs.clean(cx),
-            source: self.whence.clean(cx),
+            source: self.span.clean(cx),
             def_id: def_id.to_def_id(),
             visibility: self.vis.clean(cx),
             stability: cx.stability(self.id).clean(cx),
@@ -2219,7 +2219,7 @@ impl Clean<Vec<Item>> for doctree::ExternCrate<'_> {
         vec![Item {
             name: None,
             attrs: self.attrs.clean(cx),
-            source: self.whence.clean(cx),
+            source: self.span.clean(cx),
             def_id: DefId { krate: self.cnum, index: CRATE_DEF_INDEX },
             visibility: self.vis.clean(cx),
             stability: None,
@@ -2284,7 +2284,7 @@ impl Clean<Vec<Item>> for doctree::Import<'_> {
         vec![Item {
             name: None,
             attrs: self.attrs.clean(cx),
-            source: self.whence.clean(cx),
+            source: self.span.clean(cx),
             def_id: DefId::local(CRATE_DEF_INDEX),
             visibility: self.vis.clean(cx),
             stability: None,
@@ -2326,7 +2326,7 @@ impl Clean<Item> for doctree::ForeignItem<'_> {
         Item {
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
-            source: self.whence.clean(cx),
+            source: self.span.clean(cx),
             def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
             visibility: self.vis.clean(cx),
             stability: cx.stability(self.id).clean(cx),
@@ -2342,7 +2342,7 @@ impl Clean<Item> for doctree::Macro<'_> {
         Item {
             name: Some(name.clone()),
             attrs: self.attrs.clean(cx),
-            source: self.whence.clean(cx),
+            source: self.span.clean(cx),
             visibility: Public,
             stability: cx.stability(self.hid).clean(cx),
             deprecation: cx.deprecation(self.hid).clean(cx),
@@ -2367,7 +2367,7 @@ impl Clean<Item> for doctree::ProcMacro<'_> {
         Item {
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
-            source: self.whence.clean(cx),
+            source: self.span.clean(cx),
             visibility: Public,
             stability: cx.stability(self.id).clean(cx),
             deprecation: cx.deprecation(self.id).clean(cx),
diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs
index 98125adbdea..cfa51dcf4f1 100644
--- a/src/librustdoc/doctree.rs
+++ b/src/librustdoc/doctree.rs
@@ -89,7 +89,7 @@ pub struct Struct<'hir> {
     pub generics: &'hir hir::Generics<'hir>,
     pub attrs: &'hir [ast::Attribute],
     pub fields: &'hir [hir::StructField<'hir>],
-    pub whence: Span,
+    pub span: Span,
 }
 
 pub struct Union<'hir> {
@@ -100,7 +100,7 @@ pub struct Union<'hir> {
     pub generics: &'hir hir::Generics<'hir>,
     pub attrs: &'hir [ast::Attribute],
     pub fields: &'hir [hir::StructField<'hir>],
-    pub whence: Span,
+    pub span: Span,
 }
 
 pub struct Enum<'hir> {
@@ -109,7 +109,7 @@ pub struct Enum<'hir> {
     pub generics: &'hir hir::Generics<'hir>,
     pub attrs: &'hir [ast::Attribute],
     pub id: hir::HirId,
-    pub whence: Span,
+    pub span: Span,
     pub name: Symbol,
 }
 
@@ -118,7 +118,7 @@ pub struct Variant<'hir> {
     pub id: hir::HirId,
     pub attrs: &'hir [ast::Attribute],
     pub def: &'hir hir::VariantData<'hir>,
-    pub whence: Span,
+    pub span: Span,
 }
 
 pub struct Function<'hir> {
@@ -128,7 +128,7 @@ pub struct Function<'hir> {
     pub name: Symbol,
     pub vis: &'hir hir::Visibility<'hir>,
     pub header: hir::FnHeader,
-    pub whence: Span,
+    pub span: Span,
     pub generics: &'hir hir::Generics<'hir>,
     pub body: hir::BodyId,
 }
@@ -139,7 +139,7 @@ pub struct Typedef<'hir> {
     pub name: Symbol,
     pub id: hir::HirId,
     pub attrs: &'hir [ast::Attribute],
-    pub whence: Span,
+    pub span: Span,
     pub vis: &'hir hir::Visibility<'hir>,
 }
 
@@ -148,7 +148,7 @@ pub struct OpaqueTy<'hir> {
     pub name: Symbol,
     pub id: hir::HirId,
     pub attrs: &'hir [ast::Attribute],
-    pub whence: Span,
+    pub span: Span,
     pub vis: &'hir hir::Visibility<'hir>,
 }
 
@@ -161,7 +161,7 @@ pub struct Static<'hir> {
     pub attrs: &'hir [ast::Attribute],
     pub vis: &'hir hir::Visibility<'hir>,
     pub id: hir::HirId,
-    pub whence: Span,
+    pub span: Span,
 }
 
 pub struct Constant<'hir> {
@@ -171,7 +171,7 @@ pub struct Constant<'hir> {
     pub attrs: &'hir [ast::Attribute],
     pub vis: &'hir hir::Visibility<'hir>,
     pub id: hir::HirId,
-    pub whence: Span,
+    pub span: Span,
 }
 
 pub struct Trait<'hir> {
@@ -183,7 +183,7 @@ pub struct Trait<'hir> {
     pub bounds: &'hir [hir::GenericBound<'hir>],
     pub attrs: &'hir [ast::Attribute],
     pub id: hir::HirId,
-    pub whence: Span,
+    pub span: Span,
     pub vis: &'hir hir::Visibility<'hir>,
 }
 
@@ -193,7 +193,7 @@ pub struct TraitAlias<'hir> {
     pub bounds: &'hir [hir::GenericBound<'hir>],
     pub attrs: &'hir [ast::Attribute],
     pub id: hir::HirId,
-    pub whence: Span,
+    pub span: Span,
     pub vis: &'hir hir::Visibility<'hir>,
 }
 
@@ -208,7 +208,7 @@ pub struct Impl<'hir> {
     pub for_: &'hir hir::Ty<'hir>,
     pub items: Vec<&'hir hir::ImplItem<'hir>>,
     pub attrs: &'hir [ast::Attribute],
-    pub whence: Span,
+    pub span: Span,
     pub vis: &'hir hir::Visibility<'hir>,
     pub id: hir::HirId,
 }
@@ -219,7 +219,7 @@ pub struct ForeignItem<'hir> {
     pub name: Symbol,
     pub kind: &'hir hir::ForeignItemKind<'hir>,
     pub attrs: &'hir [ast::Attribute],
-    pub whence: Span,
+    pub span: Span,
 }
 
 // For Macro we store the DefId instead of the NodeId, since we also create
@@ -229,7 +229,7 @@ pub struct Macro<'hir> {
     pub hid: hir::HirId,
     pub def_id: hir::def_id::DefId,
     pub attrs: &'hir [ast::Attribute],
-    pub whence: Span,
+    pub span: Span,
     pub matchers: Vec<Span>,
     pub imported_from: Option<Symbol>,
 }
@@ -240,7 +240,7 @@ pub struct ExternCrate<'hir> {
     pub path: Option<String>,
     pub vis: &'hir hir::Visibility<'hir>,
     pub attrs: &'hir [ast::Attribute],
-    pub whence: Span,
+    pub span: Span,
 }
 
 pub struct Import<'hir> {
@@ -250,7 +250,7 @@ pub struct Import<'hir> {
     pub attrs: &'hir [ast::Attribute],
     pub path: &'hir hir::Path<'hir>,
     pub glob: bool,
-    pub whence: Span,
+    pub span: Span,
 }
 
 pub struct ProcMacro<'hir> {
@@ -259,7 +259,7 @@ pub struct ProcMacro<'hir> {
     pub kind: MacroKind,
     pub helpers: Vec<Symbol>,
     pub attrs: &'hir [ast::Attribute],
-    pub whence: Span,
+    pub span: Span,
 }
 
 pub fn struct_type_from_def(vdata: &hir::VariantData<'_>) -> StructType {
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index ac9f839600b..33578dc0619 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -99,7 +99,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             attrs: &item.attrs,
             generics,
             fields: sd.fields(),
-            whence: item.span,
+            span: item.span,
         }
     }
 
@@ -120,7 +120,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             attrs: &item.attrs,
             generics,
             fields: sd.fields(),
-            whence: item.span,
+            span: item.span,
         }
     }
 
@@ -142,14 +142,14 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                     id: v.id,
                     attrs: &v.attrs,
                     def: &v.data,
-                    whence: v.span,
+                    span: v.span,
                 })
                 .collect(),
             vis: &it.vis,
             generics,
             attrs: &it.attrs,
             id: it.hir_id,
-            whence: it.span,
+            span: it.span,
         }
     }
 
@@ -208,7 +208,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                     kind,
                     helpers,
                     attrs: &item.attrs,
-                    whence: item.span,
+                    span: item.span,
                 });
             }
             None => {
@@ -218,7 +218,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                     attrs: &item.attrs,
                     decl,
                     name,
-                    whence: item.span,
+                    span: item.span,
                     generics,
                     header,
                     body,
@@ -402,7 +402,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                     path: orig_name.map(|x| x.to_string()),
                     vis: &item.vis,
                     attrs: &item.attrs,
-                    whence: item.span,
+                    span: item.span,
                 })
             }
             hir::ItemKind::Use(_, hir::UseKind::ListStem) => {}
@@ -444,7 +444,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                     attrs: &item.attrs,
                     path,
                     glob: is_glob,
-                    whence: item.span,
+                    span: item.span,
                 });
             }
             hir::ItemKind::Mod(ref m) => {
@@ -476,7 +476,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                     name: ident.name,
                     id: item.hir_id,
                     attrs: &item.attrs,
-                    whence: item.span,
+                    span: item.span,
                     vis: &item.vis,
                 };
                 om.typedefs.push(t);
@@ -487,7 +487,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                     name: ident.name,
                     id: item.hir_id,
                     attrs: &item.attrs,
-                    whence: item.span,
+                    span: item.span,
                     vis: &item.vis,
                 };
                 om.opaque_tys.push(t);
@@ -500,7 +500,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                     id: item.hir_id,
                     name: ident.name,
                     attrs: &item.attrs,
-                    whence: item.span,
+                    span: item.span,
                     vis: &item.vis,
                 };
                 om.statics.push(s);
@@ -515,7 +515,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                         id: item.hir_id,
                         name: ident.name,
                         attrs: &item.attrs,
-                        whence: item.span,
+                        span: item.span,
                         vis: &item.vis,
                     };
                     om.constants.push(s);
@@ -532,7 +532,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                     bounds,
                     id: item.hir_id,
                     attrs: &item.attrs,
-                    whence: item.span,
+                    span: item.span,
                     vis: &item.vis,
                 };
                 om.traits.push(t);
@@ -544,7 +544,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                     bounds,
                     id: item.hir_id,
                     attrs: &item.attrs,
-                    whence: item.span,
+                    span: item.span,
                     vis: &item.vis,
                 };
                 om.trait_aliases.push(t);
@@ -577,7 +577,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                         items,
                         attrs: &item.attrs,
                         id: item.hir_id,
-                        whence: item.span,
+                        span: item.span,
                         vis: &item.vis,
                     };
                     om.impls.push(i);
@@ -603,7 +603,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             kind: &item.kind,
             vis: &item.vis,
             attrs: &item.attrs,
-            whence: item.span,
+            span: item.span,
         });
     }
 
@@ -623,7 +623,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             def_id: self.cx.tcx.hir().local_def_id(def.hir_id).to_def_id(),
             attrs: &def.attrs,
             name: renamed.unwrap_or(def.ident.name),
-            whence: def.span,
+            span: def.span,
             matchers,
             imported_from: None,
         }
diff --git a/src/test/ui/const-generics/infer/cannot-infer-const-args.full.stderr b/src/test/ui/const-generics/infer/cannot-infer-const-args.full.stderr
index 84e75cc3764..b438ed3ad65 100644
--- a/src/test/ui/const-generics/infer/cannot-infer-const-args.full.stderr
+++ b/src/test/ui/const-generics/infer/cannot-infer-const-args.full.stderr
@@ -2,9 +2,7 @@ error[E0282]: type annotations needed
   --> $DIR/cannot-infer-const-args.rs:12:5
    |
 LL |     foo();
-   |     ^^^
-   |
-   = note: cannot infer the value of the const parameter `X`
+   |     ^^^ cannot infer the value of const parameter `X` declared on the function `foo`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/infer/cannot-infer-const-args.min.stderr b/src/test/ui/const-generics/infer/cannot-infer-const-args.min.stderr
index 84e75cc3764..b438ed3ad65 100644
--- a/src/test/ui/const-generics/infer/cannot-infer-const-args.min.stderr
+++ b/src/test/ui/const-generics/infer/cannot-infer-const-args.min.stderr
@@ -2,9 +2,7 @@ error[E0282]: type annotations needed
   --> $DIR/cannot-infer-const-args.rs:12:5
    |
 LL |     foo();
-   |     ^^^
-   |
-   = note: cannot infer the value of the const parameter `X`
+   |     ^^^ cannot infer the value of const parameter `X` declared on the function `foo`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/infer/issue-77092.rs b/src/test/ui/const-generics/infer/issue-77092.rs
new file mode 100644
index 00000000000..9a1dd1a8258
--- /dev/null
+++ b/src/test/ui/const-generics/infer/issue-77092.rs
@@ -0,0 +1,16 @@
+#![feature(min_const_generics)]
+
+use std::convert::TryInto;
+
+fn take_array_from_mut<T, const N: usize>(data: &mut [T], start: usize) -> &mut [T; N] {
+    (&mut data[start .. start + N]).try_into().unwrap()
+}
+
+fn main() {
+    let mut arr = [0, 1, 2, 3, 4, 5, 6, 7, 8];
+
+    for i in 1 .. 4 {
+        println!("{:?}", take_array_from_mut(&mut arr, i));
+        //~^ ERROR type annotations needed
+    }
+}
diff --git a/src/test/ui/const-generics/infer/issue-77092.stderr b/src/test/ui/const-generics/infer/issue-77092.stderr
new file mode 100644
index 00000000000..e84ff8baeea
--- /dev/null
+++ b/src/test/ui/const-generics/infer/issue-77092.stderr
@@ -0,0 +1,9 @@
+error[E0282]: type annotations needed
+  --> $DIR/issue-77092.rs:13:26
+   |
+LL |         println!("{:?}", take_array_from_mut(&mut arr, i));
+   |                          ^^^^^^^^^^^^^^^^^^^ cannot infer the value of the constant `{_: usize}`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/const-generics/infer/method-chain.full.stderr b/src/test/ui/const-generics/infer/method-chain.full.stderr
index e65bc3f1096..1fb0b23cf11 100644
--- a/src/test/ui/const-generics/infer/method-chain.full.stderr
+++ b/src/test/ui/const-generics/infer/method-chain.full.stderr
@@ -2,9 +2,7 @@ error[E0282]: type annotations needed
   --> $DIR/method-chain.rs:21:33
    |
 LL |     Foo.bar().bar().bar().bar().baz();
-   |                                 ^^^
-   |
-   = note: cannot infer the value of the const parameter `N`
+   |                                 ^^^ cannot infer the value of const parameter `N` declared on the associated function `baz`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/infer/method-chain.min.stderr b/src/test/ui/const-generics/infer/method-chain.min.stderr
index e65bc3f1096..1fb0b23cf11 100644
--- a/src/test/ui/const-generics/infer/method-chain.min.stderr
+++ b/src/test/ui/const-generics/infer/method-chain.min.stderr
@@ -2,9 +2,7 @@ error[E0282]: type annotations needed
   --> $DIR/method-chain.rs:21:33
    |
 LL |     Foo.bar().bar().bar().bar().baz();
-   |                                 ^^^
-   |
-   = note: cannot infer the value of the const parameter `N`
+   |                                 ^^^ cannot infer the value of const parameter `N` declared on the associated function `baz`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/infer/uninferred-consts.full.stderr b/src/test/ui/const-generics/infer/uninferred-consts.full.stderr
index e47b6bd5dc6..7a451903e96 100644
--- a/src/test/ui/const-generics/infer/uninferred-consts.full.stderr
+++ b/src/test/ui/const-generics/infer/uninferred-consts.full.stderr
@@ -2,9 +2,7 @@ error[E0282]: type annotations needed
   --> $DIR/uninferred-consts.rs:14:9
    |
 LL |     Foo.foo();
-   |         ^^^
-   |
-   = note: cannot infer the value of the const parameter `N`
+   |         ^^^ cannot infer the value of const parameter `N` declared on the associated function `foo`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/infer/uninferred-consts.min.stderr b/src/test/ui/const-generics/infer/uninferred-consts.min.stderr
index e47b6bd5dc6..7a451903e96 100644
--- a/src/test/ui/const-generics/infer/uninferred-consts.min.stderr
+++ b/src/test/ui/const-generics/infer/uninferred-consts.min.stderr
@@ -2,9 +2,7 @@ error[E0282]: type annotations needed
   --> $DIR/uninferred-consts.rs:14:9
    |
 LL |     Foo.foo();
-   |         ^^^
-   |
-   = note: cannot infer the value of the const parameter `N`
+   |         ^^^ cannot infer the value of const parameter `N` declared on the associated function `foo`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs b/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs
index e0b9e5f3375..094ae7378bc 100644
--- a/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs
+++ b/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs
@@ -4,7 +4,7 @@ const extern fn unsize(x: &[u8; 3]) -> &[u8] { x }
 const unsafe extern "C" fn closure() -> fn() { || {} }
 //~^ ERROR function pointers in const fn are unstable
 const unsafe extern fn use_float() { 1.0 + 1.0; }
-//~^ ERROR only int, `bool` and `char` operations are stable in const fn
+//~^ ERROR floating point arithmetic
 const extern "C" fn ptr_cast(val: *const u8) { val as usize; }
 //~^ ERROR casting pointers to integers
 
diff --git a/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr b/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr
index 5ca44b3fa7e..fcc34f358f9 100644
--- a/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr
+++ b/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr
@@ -7,14 +7,14 @@ LL | const unsafe extern "C" fn closure() -> fn() { || {} }
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
-error[E0723]: only int, `bool` and `char` operations are stable in const fn
+error[E0658]: floating point arithmetic is not allowed in constant functions
   --> $DIR/const-extern-fn-min-const-fn.rs:6:38
    |
 LL | const unsafe extern fn use_float() { 1.0 + 1.0; }
    |                                      ^^^^^^^^^
    |
-   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
-   = help: add `#![feature(const_fn)]` to the crate attributes to enable
+   = note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
+   = help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
 
 error[E0658]: casting pointers to integers in constant functions is unstable
   --> $DIR/const-extern-fn-min-const-fn.rs:8:48
diff --git a/src/test/ui/consts/const_fn_floating_point_arithmetic.gated.stderr b/src/test/ui/consts/const_fn_floating_point_arithmetic.gated.stderr
new file mode 100644
index 00000000000..ae24f8f6500
--- /dev/null
+++ b/src/test/ui/consts/const_fn_floating_point_arithmetic.gated.stderr
@@ -0,0 +1,8 @@
+error: fatal error triggered by #[rustc_error]
+  --> $DIR/const_fn_floating_point_arithmetic.rs:20:1
+   |
+LL | fn main() {}
+   | ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/consts/const_fn_floating_point_arithmetic.rs b/src/test/ui/consts/const_fn_floating_point_arithmetic.rs
new file mode 100644
index 00000000000..5e32482b21a
--- /dev/null
+++ b/src/test/ui/consts/const_fn_floating_point_arithmetic.rs
@@ -0,0 +1,20 @@
+// gate-test-const_fn_floating_point_arithmetic
+
+// revisions: stock gated
+
+#![feature(rustc_attrs)]
+#![cfg_attr(gated, feature(const_fn_floating_point_arithmetic))]
+
+const fn add(f: f32) -> f32 { f + 2.0 }
+//[stock]~^ floating point arithmetic
+const fn sub(f: f32) -> f32 { 2.0 - f }
+//[stock]~^ floating point arithmetic
+const fn mul(f: f32, g: f32) -> f32 { f * g }
+//[stock]~^ floating point arithmetic
+const fn div(f: f32, g: f32) -> f32 { f / g }
+//[stock]~^ floating point arithmetic
+const fn neg(f: f32) -> f32 { -f }
+//[stock]~^ floating point arithmetic
+
+#[rustc_error]
+fn main() {} //[gated]~ fatal error triggered by #[rustc_error]
diff --git a/src/test/ui/consts/const_fn_floating_point_arithmetic.stock.stderr b/src/test/ui/consts/const_fn_floating_point_arithmetic.stock.stderr
new file mode 100644
index 00000000000..ef7a60faf3f
--- /dev/null
+++ b/src/test/ui/consts/const_fn_floating_point_arithmetic.stock.stderr
@@ -0,0 +1,48 @@
+error[E0658]: floating point arithmetic is not allowed in constant functions
+  --> $DIR/const_fn_floating_point_arithmetic.rs:8:31
+   |
+LL | const fn add(f: f32) -> f32 { f + 2.0 }
+   |                               ^^^^^^^
+   |
+   = note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
+   = help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
+
+error[E0658]: floating point arithmetic is not allowed in constant functions
+  --> $DIR/const_fn_floating_point_arithmetic.rs:10:31
+   |
+LL | const fn sub(f: f32) -> f32 { 2.0 - f }
+   |                               ^^^^^^^
+   |
+   = note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
+   = help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
+
+error[E0658]: floating point arithmetic is not allowed in constant functions
+  --> $DIR/const_fn_floating_point_arithmetic.rs:12:39
+   |
+LL | const fn mul(f: f32, g: f32) -> f32 { f * g }
+   |                                       ^^^^^
+   |
+   = note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
+   = help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
+
+error[E0658]: floating point arithmetic is not allowed in constant functions
+  --> $DIR/const_fn_floating_point_arithmetic.rs:14:39
+   |
+LL | const fn div(f: f32, g: f32) -> f32 { f / g }
+   |                                       ^^^^^
+   |
+   = note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
+   = help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
+
+error[E0658]: floating point arithmetic is not allowed in constant functions
+  --> $DIR/const_fn_floating_point_arithmetic.rs:16:31
+   |
+LL | const fn neg(f: f32) -> f32 { -f }
+   |                               ^^
+   |
+   = note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
+   = help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/consts/const_let_eq_float.rs b/src/test/ui/consts/const_let_eq_float.rs
index bc0ef26eb2f..e15f4b804f7 100644
--- a/src/test/ui/consts/const_let_eq_float.rs
+++ b/src/test/ui/consts/const_let_eq_float.rs
@@ -1,6 +1,6 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// run-pass
 
-#![feature(const_fn)]
+#![feature(const_fn_floating_point_arithmetic)]
 
 struct Foo<T>(T);
 struct Bar<T> { x: T }
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.rs b/src/test/ui/consts/min_const_fn/min_const_fn.rs
index 336d754b06a..55a999d5cdc 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn.rs
+++ b/src/test/ui/consts/min_const_fn/min_const_fn.rs
@@ -77,14 +77,6 @@ const fn foo11<T: std::fmt::Display>(t: T) -> T { t }
 //~^ ERROR trait bounds other than `Sized` on const fn parameters are unstable
 const fn foo11_2<T: Send>(t: T) -> T { t }
 //~^ ERROR trait bounds other than `Sized` on const fn parameters are unstable
-const fn foo19(f: f32) -> f32 { f * 2.0 }
-//~^ ERROR int, `bool` and `char` operations
-const fn foo19_2(f: f32) -> f32 { 2.0 - f }
-//~^ ERROR int, `bool` and `char` operations
-const fn foo19_3(f: f32) -> f32 { -f }
-//~^ ERROR int, `bool` and `char` operations
-const fn foo19_4(f: f32, g: f32) -> f32 { f / g }
-//~^ ERROR int, `bool` and `char` operations
 
 static BAR: u32 = 42;
 const fn foo25() -> u32 { BAR } //~ ERROR cannot refer to statics
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.stderr
index c96500e38ec..a37e5203eee 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_fn.stderr
@@ -76,44 +76,8 @@ LL | const fn foo11_2<T: Send>(t: T) -> T { t }
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
-error[E0723]: only int, `bool` and `char` operations are stable in const fn
-  --> $DIR/min_const_fn.rs:80:33
-   |
-LL | const fn foo19(f: f32) -> f32 { f * 2.0 }
-   |                                 ^^^^^^^
-   |
-   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
-   = help: add `#![feature(const_fn)]` to the crate attributes to enable
-
-error[E0723]: only int, `bool` and `char` operations are stable in const fn
-  --> $DIR/min_const_fn.rs:82:35
-   |
-LL | const fn foo19_2(f: f32) -> f32 { 2.0 - f }
-   |                                   ^^^^^^^
-   |
-   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
-   = help: add `#![feature(const_fn)]` to the crate attributes to enable
-
-error[E0723]: only int, `bool` and `char` operations are stable in const fn
-  --> $DIR/min_const_fn.rs:84:35
-   |
-LL | const fn foo19_3(f: f32) -> f32 { -f }
-   |                                   ^^
-   |
-   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
-   = help: add `#![feature(const_fn)]` to the crate attributes to enable
-
-error[E0723]: only int, `bool` and `char` operations are stable in const fn
-  --> $DIR/min_const_fn.rs:86:43
-   |
-LL | const fn foo19_4(f: f32, g: f32) -> f32 { f / g }
-   |                                           ^^^^^
-   |
-   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
-   = help: add `#![feature(const_fn)]` to the crate attributes to enable
-
 error[E0013]: constant functions cannot refer to statics
-  --> $DIR/min_const_fn.rs:90:27
+  --> $DIR/min_const_fn.rs:82:27
    |
 LL | const fn foo25() -> u32 { BAR }
    |                           ^^^
@@ -121,7 +85,7 @@ LL | const fn foo25() -> u32 { BAR }
    = help: consider extracting the value of the `static` to a `const`, and referring to that
 
 error[E0013]: constant functions cannot refer to statics
-  --> $DIR/min_const_fn.rs:91:37
+  --> $DIR/min_const_fn.rs:83:37
    |
 LL | const fn foo26() -> &'static u32 { &BAR }
    |                                     ^^^
@@ -129,7 +93,7 @@ LL | const fn foo26() -> &'static u32 { &BAR }
    = help: consider extracting the value of the `static` to a `const`, and referring to that
 
 error[E0658]: casting pointers to integers in constant functions is unstable
-  --> $DIR/min_const_fn.rs:92:42
+  --> $DIR/min_const_fn.rs:84:42
    |
 LL | const fn foo30(x: *const u32) -> usize { x as usize }
    |                                          ^^^^^^^^^^
@@ -138,7 +102,7 @@ LL | const fn foo30(x: *const u32) -> usize { x as usize }
    = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
 
 error[E0658]: casting pointers to integers in constant functions is unstable
-  --> $DIR/min_const_fn.rs:94:63
+  --> $DIR/min_const_fn.rs:86:63
    |
 LL | const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } }
    |                                                               ^^^^^^^^^^
@@ -147,7 +111,7 @@ LL | const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize }
    = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
 
 error[E0658]: casting pointers to integers in constant functions is unstable
-  --> $DIR/min_const_fn.rs:96:42
+  --> $DIR/min_const_fn.rs:88:42
    |
 LL | const fn foo30_2(x: *mut u32) -> usize { x as usize }
    |                                          ^^^^^^^^^^
@@ -156,7 +120,7 @@ LL | const fn foo30_2(x: *mut u32) -> usize { x as usize }
    = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
 
 error[E0658]: casting pointers to integers in constant functions is unstable
-  --> $DIR/min_const_fn.rs:98:63
+  --> $DIR/min_const_fn.rs:90:63
    |
 LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } }
    |                                                               ^^^^^^^^^^
@@ -165,7 +129,7 @@ LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize }
    = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
 
 error[E0658]: mutable references are not allowed in constant functions
-  --> $DIR/min_const_fn.rs:101:14
+  --> $DIR/min_const_fn.rs:93:14
    |
 LL | const fn inc(x: &mut i32) { *x += 1 }
    |              ^
@@ -174,7 +138,7 @@ LL | const fn inc(x: &mut i32) { *x += 1 }
    = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
 
 error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:110:6
+  --> $DIR/min_const_fn.rs:102:6
    |
 LL | impl<T: std::fmt::Debug> Foo<T> {
    |      ^
@@ -183,7 +147,7 @@ LL | impl<T: std::fmt::Debug> Foo<T> {
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
 error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:115:6
+  --> $DIR/min_const_fn.rs:107:6
    |
 LL | impl<T: std::fmt::Debug + Sized> Foo<T> {
    |      ^
@@ -192,7 +156,7 @@ LL | impl<T: std::fmt::Debug + Sized> Foo<T> {
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
 error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:120:6
+  --> $DIR/min_const_fn.rs:112:6
    |
 LL | impl<T: Sync + Sized> Foo<T> {
    |      ^
@@ -201,7 +165,7 @@ LL | impl<T: Sync + Sized> Foo<T> {
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
 error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:126:34
+  --> $DIR/min_const_fn.rs:118:34
    |
 LL | const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
    |                                  ^^^^^^^^^^^^^^^^^^^^
@@ -210,7 +174,7 @@ LL | const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
 error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:128:22
+  --> $DIR/min_const_fn.rs:120:22
    |
 LL | const fn no_apit(_x: impl std::fmt::Debug) {}
    |                      ^^^^^^^^^^^^^^^^^^^^
@@ -219,7 +183,7 @@ LL | const fn no_apit(_x: impl std::fmt::Debug) {}
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
 error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:129:23
+  --> $DIR/min_const_fn.rs:121:23
    |
 LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
    |                       ^^
@@ -228,7 +192,7 @@ LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
 error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:130:32
+  --> $DIR/min_const_fn.rs:122:32
    |
 LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -237,7 +201,7 @@ LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
 error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:135:41
+  --> $DIR/min_const_fn.rs:127:41
    |
 LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -246,7 +210,7 @@ LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
 error[E0723]: function pointers in const fn are unstable
-  --> $DIR/min_const_fn.rs:138:21
+  --> $DIR/min_const_fn.rs:130:21
    |
 LL | const fn no_fn_ptrs(_x: fn()) {}
    |                     ^^
@@ -255,7 +219,7 @@ LL | const fn no_fn_ptrs(_x: fn()) {}
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
 error[E0723]: function pointers in const fn are unstable
-  --> $DIR/min_const_fn.rs:140:27
+  --> $DIR/min_const_fn.rs:132:27
    |
 LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
    |                           ^^^^
@@ -263,7 +227,7 @@ LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
-error: aborting due to 30 previous errors
+error: aborting due to 26 previous errors
 
 Some errors have detailed explanations: E0013, E0493, E0658, E0723.
 For more information about an error, try `rustc --explain E0013`.
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs b/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs
index b83fdf7c656..292e2dd167c 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs
+++ b/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs
@@ -3,7 +3,7 @@
             we're apparently really bad at it",
             issue = "none")]
 
-#![feature(const_fn, foo, foo2)]
+#![feature(const_fn, const_fn_floating_point_arithmetic, foo, foo2)]
 #![feature(staged_api)]
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -25,9 +25,9 @@ const fn bar2() -> u32 { foo2() } //~ ERROR not yet stable as a const fn
 
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_const_stable(feature = "rust1", since = "1.0.0")]
-// conformity is required, even with `const_fn` feature gate
+// Const-stable functions cannot rely on unstable const-eval features.
 const fn bar3() -> u32 { (5f32 + 6f32) as u32 }
-//~^ ERROR const-stable function cannot use `#[feature(const_fn)]`
+//~^ ERROR const-stable function cannot use `#[feature(const_fn_floating_point_arithmetic)]`
 
 // check whether this function cannot be called even with the feature gate active
 #[unstable(feature = "foo2", issue = "none")]
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr
index a1f1f6f52ab..fa2260b40d1 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr
@@ -14,7 +14,7 @@ LL | const fn bar2() -> u32 { foo2() }
    |
    = help: Const-stable functions can only call other const-stable functions
 
-error: const-stable function cannot use `#[feature(const_fn)]`
+error: const-stable function cannot use `#[feature(const_fn_floating_point_arithmetic)]`
   --> $DIR/min_const_fn_libstd_stability.rs:29:26
    |
 LL | const fn bar3() -> u32 { (5f32 + 6f32) as u32 }
diff --git a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs
index 902ed435e31..0f48341ddf3 100644
--- a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs
+++ b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs
@@ -3,7 +3,7 @@
             we're apparently really bad at it",
             issue = "none")]
 
-#![feature(const_fn, foo, foo2)]
+#![feature(const_fn, const_fn_floating_point_arithmetic, foo, foo2)]
 #![feature(staged_api)]
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -27,7 +27,7 @@ const unsafe fn bar2() -> u32 { unsafe { foo2() } } //~ ERROR not yet stable as
 #[rustc_const_stable(feature = "rust1", since = "1.0.0")]
 // conformity is required, even with `const_fn` feature gate
 const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 }
-//~^ ERROR const-stable function cannot use `#[feature(const_fn)]`
+//~^ ERROR const-stable function cannot use `#[feature(const_fn_floating_point_arithmetic)]`
 
 // check whether this function cannot be called even with the feature gate active
 #[unstable(feature = "foo2", issue = "none")]
diff --git a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr
index 2741a864404..1ca5964ce0f 100644
--- a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr
@@ -14,7 +14,7 @@ LL | const unsafe fn bar2() -> u32 { unsafe { foo2() } }
    |
    = help: Const-stable functions can only call other const-stable functions
 
-error: const-stable function cannot use `#[feature(const_fn)]`
+error: const-stable function cannot use `#[feature(const_fn_floating_point_arithmetic)]`
   --> $DIR/min_const_unsafe_fn_libstd_stability.rs:29:33
    |
 LL | const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 }
diff --git a/src/tools/miri b/src/tools/miri
-Subproject 02a33d411d8e385942776760a99535d69826349
+Subproject 2f84bfc57dd0ef22269bb84dae10f71e5e23e85
diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml
index f0a6ce2fa06..f5e5c0867b4 100644
--- a/src/tools/rustbook/Cargo.toml
+++ b/src/tools/rustbook/Cargo.toml
@@ -9,6 +9,6 @@ edition = "2018"
 clap = "2.25.0"
 
 [dependencies.mdbook]
-version = "0.4.0"
+version = "0.4.3"
 default-features = false
 features = ["search"]