about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-01-20 23:35:50 +0000
committerbors <bors@rust-lang.org>2020-01-20 23:35:50 +0000
commit06b945049b6e6795bcfb9fb8007a46c44a93c0aa (patch)
treee5ac89eda26500d49ee52698ed3d9b033cd2e05a
parentb5a3341f1b8b475990e9d1b071b88d3c280936b4 (diff)
parentf6406f7f680d4f77144d22e1f74064e878213f5c (diff)
downloadrust-06b945049b6e6795bcfb9fb8007a46c44a93c0aa.tar.gz
rust-06b945049b6e6795bcfb9fb8007a46c44a93c0aa.zip
Auto merge of #68405 - JohnTitor:rollup-kj0x4za, r=JohnTitor
Rollup of 8 pull requests

Successful merges:

 - #67734 (Remove appendix from Apache license)
 - #67795 (Cleanup formatting code)
 - #68290 (Fix some tests failing in `--pass check` mode)
 - #68297 ( Filter and test predicates using `normalize_and_test_predicates` for const-prop)
 - #68302 (Fix #[track_caller] and function pointers)
 - #68339 (Add `riscv64gc-unknown-linux-gnu` into target list in build-manifest)
 - #68381 (Added minor clarification to specification of GlobalAlloc::realloc.)
 - #68397 (rustdoc: Correct order of `async` and `unsafe` in `async unsafe fn`s)

Failed merges:

r? @ghost
-rw-r--r--LICENSE-APACHE25
-rw-r--r--src/libcore/alloc.rs3
-rw-r--r--src/libcore/fmt/mod.rs75
-rw-r--r--src/libcore/fmt/rt/v1.rs6
-rw-r--r--src/librustc/mir/mono.rs5
-rw-r--r--src/librustc/query/mod.rs6
-rw-r--r--src/librustc/traits/fulfill.rs24
-rw-r--r--src/librustc/traits/mod.rs20
-rw-r--r--src/librustc/ty/instance.rs7
-rw-r--r--src/librustc/ty/query/keys.rs9
-rw-r--r--src/librustc_builtin_macros/format.rs13
-rw-r--r--src/librustc_mir/shim.rs80
-rw-r--r--src/librustc_mir/transform/const_prop.rs44
-rw-r--r--src/librustdoc/html/render.rs10
-rw-r--r--src/test/rustdoc/async-fn.rs7
-rw-r--r--src/test/ui/async-await/async-fn-nonsend.rs15
-rw-r--r--src/test/ui/async-await/async-fn-nonsend.stderr24
-rw-r--r--src/test/ui/consts/array-literal-index-oob.rs1
-rw-r--r--src/test/ui/consts/array-literal-index-oob.stderr8
-rw-r--r--src/test/ui/consts/const-eval/promoted_errors.rs1
-rw-r--r--src/test/ui/consts/const-eval/promoted_errors.stderr20
-rw-r--r--src/test/ui/consts/const-eval/promoted_errors2.rs1
-rw-r--r--src/test/ui/consts/const-eval/promoted_errors2.stderr22
-rw-r--r--src/test/ui/consts/issue-68264-overflow.rs43
-rw-r--r--src/test/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs19
-rw-r--r--src/test/ui/rfc-2091-track-caller/tracked-fn-ptr.rs19
-rw-r--r--src/tools/build-manifest/src/main.rs1
27 files changed, 266 insertions, 242 deletions
diff --git a/LICENSE-APACHE b/LICENSE-APACHE
index 16fe87b06e8..1b5ec8b78e2 100644
--- a/LICENSE-APACHE
+++ b/LICENSE-APACHE
@@ -174,28 +174,3 @@ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
    of your accepting any such warranty or additional liability.
 
 END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
-   To apply the Apache License to your work, attach the following
-   boilerplate notice, with the fields enclosed by brackets "[]"
-   replaced with your own identifying information. (Don't include
-   the brackets!)  The text should be enclosed in the appropriate
-   comment syntax for the file format. We also recommend that a
-   file or class name and description of purpose be included on the
-   same "printed page" as the copyright notice for easier
-   identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-	http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs
index 4354e1c7b5f..09f743fb81e 100644
--- a/src/libcore/alloc.rs
+++ b/src/libcore/alloc.rs
@@ -525,7 +525,8 @@ pub unsafe trait GlobalAlloc {
     /// The memory may or may not have been deallocated,
     /// and should be considered unusable (unless of course it was
     /// transferred back to the caller again via the return value of
-    /// this method).
+    /// this method). The new memory block is allocated with `layout`, but
+    /// with the `size` updated to `new_size`.
     ///
     /// If this method returns null, then ownership of the memory
     /// block has not been transferred to this allocator, and the
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index e68f3c58a3e..900ef63f1df 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -10,7 +10,6 @@ use crate::mem;
 use crate::num::flt2dec;
 use crate::ops::Deref;
 use crate::result;
-use crate::slice;
 use crate::str;
 
 mod builders;
@@ -234,8 +233,6 @@ pub struct Formatter<'a> {
     precision: Option<usize>,
 
     buf: &'a mut (dyn Write + 'a),
-    curarg: slice::Iter<'a, ArgumentV1<'a>>,
-    args: &'a [ArgumentV1<'a>],
 }
 
 // NB. Argument is essentially an optimized partially applied formatting function,
@@ -1043,8 +1040,6 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result {
         buf: output,
         align: rt::v1::Alignment::Unknown,
         fill: ' ',
-        args: args.args,
-        curarg: args.args.iter(),
     };
 
     let mut idx = 0;
@@ -1063,7 +1058,7 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result {
             // a string piece.
             for (arg, piece) in fmt.iter().zip(args.pieces.iter()) {
                 formatter.buf.write_str(*piece)?;
-                formatter.run(arg)?;
+                run(&mut formatter, arg, &args.args)?;
                 idx += 1;
             }
         }
@@ -1077,6 +1072,39 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result {
     Ok(())
 }
 
+fn run(fmt: &mut Formatter<'_>, arg: &rt::v1::Argument, args: &[ArgumentV1<'_>]) -> Result {
+    fmt.fill = arg.format.fill;
+    fmt.align = arg.format.align;
+    fmt.flags = arg.format.flags;
+    fmt.width = getcount(args, &arg.format.width);
+    fmt.precision = getcount(args, &arg.format.precision);
+
+    // Extract the correct argument
+    let value = {
+        #[cfg(bootstrap)]
+        {
+            match arg.position {
+                rt::v1::Position::At(i) => args[i],
+            }
+        }
+        #[cfg(not(bootstrap))]
+        {
+            args[arg.position]
+        }
+    };
+
+    // Then actually do some printing
+    (value.formatter)(value.value, fmt)
+}
+
+fn getcount(args: &[ArgumentV1<'_>], cnt: &rt::v1::Count) -> Option<usize> {
+    match *cnt {
+        rt::v1::Count::Is(n) => Some(n),
+        rt::v1::Count::Implied => None,
+        rt::v1::Count::Param(i) => args[i].as_usize(),
+    }
+}
+
 /// Padding after the end of something. Returned by `Formatter::padding`.
 #[must_use = "don't forget to write the post padding"]
 struct PostPadding {
@@ -1114,41 +1142,6 @@ impl<'a> Formatter<'a> {
             align: self.align,
             width: self.width,
             precision: self.precision,
-
-            // These only exist in the struct for the `run` method,
-            // which won’t be used together with this method.
-            curarg: self.curarg.clone(),
-            args: self.args,
-        }
-    }
-
-    // First up is the collection of functions used to execute a format string
-    // at runtime. This consumes all of the compile-time statics generated by
-    // the format! syntax extension.
-    fn run(&mut self, arg: &rt::v1::Argument) -> Result {
-        // Fill in the format parameters into the formatter
-        self.fill = arg.format.fill;
-        self.align = arg.format.align;
-        self.flags = arg.format.flags;
-        self.width = self.getcount(&arg.format.width);
-        self.precision = self.getcount(&arg.format.precision);
-
-        // Extract the correct argument
-        let value = match arg.position {
-            rt::v1::Position::Next => *self.curarg.next().unwrap(),
-            rt::v1::Position::At(i) => self.args[i],
-        };
-
-        // Then actually do some printing
-        (value.formatter)(value.value, self)
-    }
-
-    fn getcount(&mut self, cnt: &rt::v1::Count) -> Option<usize> {
-        match *cnt {
-            rt::v1::Count::Is(n) => Some(n),
-            rt::v1::Count::Implied => None,
-            rt::v1::Count::Param(i) => self.args[i].as_usize(),
-            rt::v1::Count::NextParam => self.curarg.next()?.as_usize(),
         }
     }
 
diff --git a/src/libcore/fmt/rt/v1.rs b/src/libcore/fmt/rt/v1.rs
index 826ae36d2d1..fd81f93242b 100644
--- a/src/libcore/fmt/rt/v1.rs
+++ b/src/libcore/fmt/rt/v1.rs
@@ -7,7 +7,10 @@
 
 #[derive(Copy, Clone)]
 pub struct Argument {
+    #[cfg(bootstrap)]
     pub position: Position,
+    #[cfg(not(bootstrap))]
+    pub position: usize,
     pub format: FormatSpec,
 }
 
@@ -37,12 +40,11 @@ pub enum Alignment {
 pub enum Count {
     Is(usize),
     Param(usize),
-    NextParam,
     Implied,
 }
 
+#[cfg(bootstrap)]
 #[derive(Copy, Clone)]
 pub enum Position {
-    Next,
     At(usize),
 }
diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs
index e7a4c5b5921..51ce575e51f 100644
--- a/src/librustc/mir/mono.rs
+++ b/src/librustc/mir/mono.rs
@@ -1,7 +1,6 @@
 use crate::dep_graph::{DepConstructor, DepNode, WorkProduct, WorkProductId};
 use crate::ich::{Fingerprint, NodeIdHashingMode, StableHashingContext};
 use crate::session::config::OptLevel;
-use crate::traits::TraitQueryMode;
 use crate::ty::print::obsolete::DefPathBasedNames;
 use crate::ty::{subst::InternalSubsts, Instance, InstanceDef, SymbolName, TyCtxt};
 use rustc_data_structures::base_n;
@@ -168,9 +167,7 @@ impl<'tcx> MonoItem<'tcx> {
             MonoItem::GlobalAsm(..) => return true,
         };
 
-        // We shouldn't encounter any overflow here, so we use TraitQueryMode::Standard\
-        // to report an error if overflow somehow occurs.
-        tcx.substitute_normalize_and_test_predicates((def_id, &substs, TraitQueryMode::Standard))
+        tcx.substitute_normalize_and_test_predicates((def_id, &substs))
     }
 
     pub fn to_string(&self, tcx: TyCtxt<'tcx>, debug: bool) -> String {
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index b7aef0c44d9..deb2d6ac630 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -1156,11 +1156,11 @@ rustc_queries! {
             desc { "normalizing `{:?}`", goal }
         }
 
-        query substitute_normalize_and_test_predicates(key: (DefId, SubstsRef<'tcx>, traits::TraitQueryMode)) -> bool {
+        query substitute_normalize_and_test_predicates(key: (DefId, SubstsRef<'tcx>)) -> bool {
             no_force
             desc { |tcx|
-                "testing substituted normalized predicates in mode {:?}:`{}`",
-                key.2, tcx.def_path_str(key.0)
+                "testing substituted normalized predicates:`{}`",
+                tcx.def_path_str(key.0)
             }
         }
 
diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs
index 9e5abc80822..46ece6fc405 100644
--- a/src/librustc/traits/fulfill.rs
+++ b/src/librustc/traits/fulfill.rs
@@ -16,7 +16,6 @@ use super::CodeSelectionError;
 use super::{ConstEvalFailure, Unimplemented};
 use super::{FulfillmentError, FulfillmentErrorCode};
 use super::{ObligationCause, PredicateObligation};
-use crate::traits::TraitQueryMode;
 
 impl<'tcx> ForestObligation for PendingPredicateObligation<'tcx> {
     type Predicate = ty::Predicate<'tcx>;
@@ -63,9 +62,6 @@ pub struct FulfillmentContext<'tcx> {
     // a snapshot (they don't *straddle* a snapshot, so there
     // is no trouble there).
     usable_in_snapshot: bool,
-
-    // The `TraitQueryMode` used when constructing a `SelectionContext`
-    query_mode: TraitQueryMode,
 }
 
 #[derive(Clone, Debug)]
@@ -79,26 +75,12 @@ pub struct PendingPredicateObligation<'tcx> {
 static_assert_size!(PendingPredicateObligation<'_>, 136);
 
 impl<'a, 'tcx> FulfillmentContext<'tcx> {
-    /// Creates a new fulfillment context with `TraitQueryMode::Standard`
-    /// You almost always want to use this instead of `with_query_mode`
+    /// Creates a new fulfillment context.
     pub fn new() -> FulfillmentContext<'tcx> {
         FulfillmentContext {
             predicates: ObligationForest::new(),
             register_region_obligations: true,
             usable_in_snapshot: false,
-            query_mode: TraitQueryMode::Standard,
-        }
-    }
-
-    /// Creates a new fulfillment context with the specified query mode.
-    /// This should only be used when you want to ignore overflow,
-    /// rather than reporting it as an error.
-    pub fn with_query_mode(query_mode: TraitQueryMode) -> FulfillmentContext<'tcx> {
-        FulfillmentContext {
-            predicates: ObligationForest::new(),
-            register_region_obligations: true,
-            usable_in_snapshot: false,
-            query_mode,
         }
     }
 
@@ -107,7 +89,6 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> {
             predicates: ObligationForest::new(),
             register_region_obligations: true,
             usable_in_snapshot: true,
-            query_mode: TraitQueryMode::Standard,
         }
     }
 
@@ -116,7 +97,6 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> {
             predicates: ObligationForest::new(),
             register_region_obligations: false,
             usable_in_snapshot: false,
-            query_mode: TraitQueryMode::Standard,
         }
     }
 
@@ -237,7 +217,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
         &mut self,
         infcx: &InferCtxt<'_, 'tcx>,
     ) -> Result<(), Vec<FulfillmentError<'tcx>>> {
-        let mut selcx = SelectionContext::with_query_mode(infcx, self.query_mode);
+        let mut selcx = SelectionContext::new(infcx);
         self.select(&mut selcx)
     }
 
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index 2e5da2b0382..e93529186ac 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -95,7 +95,7 @@ pub enum IntercrateMode {
 }
 
 /// The mode that trait queries run in.
-#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, HashStable)]
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
 pub enum TraitQueryMode {
     // Standard/un-canonicalized queries get accurate
     // spans etc. passed in and hence can do reasonable
@@ -1014,17 +1014,16 @@ where
 /// environment. If this returns false, then either normalize
 /// encountered an error or one of the predicates did not hold. Used
 /// when creating vtables to check for unsatisfiable methods.
-fn normalize_and_test_predicates<'tcx>(
+pub fn normalize_and_test_predicates<'tcx>(
     tcx: TyCtxt<'tcx>,
     predicates: Vec<ty::Predicate<'tcx>>,
-    mode: TraitQueryMode,
 ) -> bool {
-    debug!("normalize_and_test_predicates(predicates={:?}, mode={:?})", predicates, mode);
+    debug!("normalize_and_test_predicates(predicates={:?})", predicates);
 
     let result = tcx.infer_ctxt().enter(|infcx| {
         let param_env = ty::ParamEnv::reveal_all();
-        let mut selcx = SelectionContext::with_query_mode(&infcx, mode);
-        let mut fulfill_cx = FulfillmentContext::with_query_mode(mode);
+        let mut selcx = SelectionContext::new(&infcx);
+        let mut fulfill_cx = FulfillmentContext::new();
         let cause = ObligationCause::dummy();
         let Normalized { value: predicates, obligations } =
             normalize(&mut selcx, param_env, cause.clone(), &predicates);
@@ -1044,12 +1043,12 @@ fn normalize_and_test_predicates<'tcx>(
 
 fn substitute_normalize_and_test_predicates<'tcx>(
     tcx: TyCtxt<'tcx>,
-    key: (DefId, SubstsRef<'tcx>, TraitQueryMode),
+    key: (DefId, SubstsRef<'tcx>),
 ) -> bool {
     debug!("substitute_normalize_and_test_predicates(key={:?})", key);
 
     let predicates = tcx.predicates_of(key.0).instantiate(tcx, key.1).predicates;
-    let result = normalize_and_test_predicates(tcx, predicates, key.2);
+    let result = normalize_and_test_predicates(tcx, predicates);
 
     debug!("substitute_normalize_and_test_predicates(key={:?}) = {:?}", key, result);
     result
@@ -1102,10 +1101,7 @@ fn vtable_methods<'tcx>(
             // Note that this method could then never be called, so we
             // do not want to try and codegen it, in that case (see #23435).
             let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs);
-            // We don't expect overflow here, so report an error if it somehow ends
-            // up happening.
-            if !normalize_and_test_predicates(tcx, predicates.predicates, TraitQueryMode::Standard)
-            {
+            if !normalize_and_test_predicates(tcx, predicates.predicates) {
                 debug!("vtable_methods: predicates do not hold");
                 return None;
             }
diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs
index 9be50d19a50..1ea695e40b2 100644
--- a/src/librustc/ty/instance.rs
+++ b/src/librustc/ty/instance.rs
@@ -141,7 +141,12 @@ impl<'tcx> InstanceDef<'tcx> {
     }
 
     pub fn requires_caller_location(&self, tcx: TyCtxt<'_>) -> bool {
-        tcx.codegen_fn_attrs(self.def_id()).flags.contains(CodegenFnAttrFlags::TRACK_CALLER)
+        match *self {
+            InstanceDef::Item(def_id) => {
+                tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::TRACK_CALLER)
+            }
+            _ => false,
+        }
     }
 }
 
diff --git a/src/librustc/ty/query/keys.rs b/src/librustc/ty/query/keys.rs
index 3fb3720a563..cbf335ad607 100644
--- a/src/librustc/ty/query/keys.rs
+++ b/src/librustc/ty/query/keys.rs
@@ -125,15 +125,6 @@ impl<'tcx> Key for (DefId, SubstsRef<'tcx>) {
     }
 }
 
-impl<'tcx> Key for (DefId, SubstsRef<'tcx>, traits::TraitQueryMode) {
-    fn query_crate(&self) -> CrateNum {
-        self.0.krate
-    }
-    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
-        self.0.default_span(tcx)
-    }
-}
-
 impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) {
     fn query_crate(&self) -> CrateNum {
         self.1.def_id().krate
diff --git a/src/librustc_builtin_macros/format.rs b/src/librustc_builtin_macros/format.rs
index 6fca74e2239..3f4e24ca993 100644
--- a/src/librustc_builtin_macros/format.rs
+++ b/src/librustc_builtin_macros/format.rs
@@ -590,17 +590,6 @@ impl<'a, 'b> Context<'a, 'b> {
             parse::NextArgument(ref arg) => {
                 // Build the position
                 let pos = {
-                    let pos = |c, arg| {
-                        let mut path = Context::rtpath(self.ecx, "Position");
-                        path.push(self.ecx.ident_of(c, sp));
-                        match arg {
-                            Some(i) => {
-                                let arg = self.ecx.expr_usize(sp, i);
-                                self.ecx.expr_call_global(sp, path, vec![arg])
-                            }
-                            None => self.ecx.expr_path(self.ecx.path_global(sp, path)),
-                        }
-                    };
                     match arg.position {
                         parse::ArgumentIs(i) | parse::ArgumentImplicitlyIs(i) => {
                             // Map to index in final generated argument array
@@ -615,7 +604,7 @@ impl<'a, 'b> Context<'a, 'b> {
                                     arg_idx
                                 }
                             };
-                            pos("At", Some(arg_idx))
+                            self.ecx.expr_usize(sp, arg_idx)
                         }
 
                         // should never be the case, because names are already
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index 01cecdd0679..b84616142cb 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -31,9 +31,13 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
 
     let mut result = match instance {
         ty::InstanceDef::Item(..) => bug!("item {:?} passed to make_shim", instance),
-        ty::InstanceDef::VtableShim(def_id) => {
-            build_call_shim(tcx, instance, Adjustment::DerefMove, CallKind::Direct(def_id), None)
-        }
+        ty::InstanceDef::VtableShim(def_id) => build_call_shim(
+            tcx,
+            instance,
+            Some(Adjustment::DerefMove),
+            CallKind::Direct(def_id),
+            None,
+        ),
         ty::InstanceDef::FnPtrShim(def_id, ty) => {
             let trait_ = tcx.trait_of_item(def_id).unwrap();
             let adjustment = match tcx.lang_items().fn_trait_kind(trait_) {
@@ -50,7 +54,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
             let sig = tcx.erase_late_bound_regions(&ty.fn_sig(tcx));
             let arg_tys = sig.inputs();
 
-            build_call_shim(tcx, instance, adjustment, CallKind::Indirect, Some(arg_tys))
+            build_call_shim(tcx, instance, Some(adjustment), CallKind::Indirect, Some(arg_tys))
         }
         // We are generating a call back to our def-id, which the
         // codegen backend knows to turn to an actual call, be it
@@ -58,7 +62,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
         // indirect calls must be codegen'd differently than direct ones
         // (such as `#[track_caller]`).
         ty::InstanceDef::ReifyShim(def_id) => {
-            build_call_shim(tcx, instance, Adjustment::Identity, CallKind::Direct(def_id), None)
+            build_call_shim(tcx, instance, None, CallKind::Direct(def_id), None)
         }
         ty::InstanceDef::ClosureOnceShim { call_once: _ } => {
             let fn_mut = tcx.lang_items().fn_mut_trait().unwrap();
@@ -68,7 +72,13 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
                 .unwrap()
                 .def_id;
 
-            build_call_shim(tcx, instance, Adjustment::RefMut, CallKind::Direct(call_mut), None)
+            build_call_shim(
+                tcx,
+                instance,
+                Some(Adjustment::RefMut),
+                CallKind::Direct(call_mut),
+                None,
+            )
         }
         ty::InstanceDef::DropGlue(def_id, ty) => build_drop_shim(tcx, def_id, ty),
         ty::InstanceDef::CloneShim(def_id, ty) => {
@@ -648,7 +658,7 @@ impl CloneShimBuilder<'tcx> {
 fn build_call_shim<'tcx>(
     tcx: TyCtxt<'tcx>,
     instance: ty::InstanceDef<'tcx>,
-    rcvr_adjustment: Adjustment,
+    rcvr_adjustment: Option<Adjustment>,
     call_kind: CallKind,
     untuple_args: Option<&[Ty<'tcx>]>,
 ) -> BodyAndCache<'tcx> {
@@ -680,14 +690,16 @@ fn build_call_shim<'tcx>(
     let mut local_decls = local_decls_for_sig(&sig, span);
     let source_info = SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE };
 
-    let rcvr_arg = Local::new(1 + 0);
-    let rcvr_l = Place::from(rcvr_arg);
+    let rcvr_place = || {
+        assert!(rcvr_adjustment.is_some());
+        Place::from(Local::new(1 + 0))
+    };
     let mut statements = vec![];
 
-    let rcvr = match rcvr_adjustment {
-        Adjustment::Identity => Operand::Move(rcvr_l),
-        Adjustment::Deref => Operand::Copy(tcx.mk_place_deref(rcvr_l)),
-        Adjustment::DerefMove => Operand::Move(tcx.mk_place_deref(rcvr_l)),
+    let rcvr = rcvr_adjustment.map(|rcvr_adjustment| match rcvr_adjustment {
+        Adjustment::Identity => Operand::Move(rcvr_place()),
+        Adjustment::Deref => Operand::Copy(tcx.mk_place_deref(rcvr_place())),
+        Adjustment::DerefMove => Operand::Move(tcx.mk_place_deref(rcvr_place())),
         Adjustment::RefMut => {
             // let rcvr = &mut rcvr;
             let ref_rcvr = local_decls.push(temp_decl(
@@ -703,15 +715,15 @@ fn build_call_shim<'tcx>(
                 source_info,
                 kind: StatementKind::Assign(box (
                     Place::from(ref_rcvr),
-                    Rvalue::Ref(tcx.lifetimes.re_erased, borrow_kind, rcvr_l),
+                    Rvalue::Ref(tcx.lifetimes.re_erased, borrow_kind, rcvr_place()),
                 )),
             });
             Operand::Move(Place::from(ref_rcvr))
         }
-    };
+    });
 
     let (callee, mut args) = match call_kind {
-        CallKind::Indirect => (rcvr, vec![]),
+        CallKind::Indirect => (rcvr.unwrap(), vec![]),
         CallKind::Direct(def_id) => {
             let ty = tcx.type_of(def_id);
             (
@@ -720,21 +732,35 @@ fn build_call_shim<'tcx>(
                     user_ty: None,
                     literal: ty::Const::zero_sized(tcx, ty),
                 }),
-                vec![rcvr],
+                rcvr.into_iter().collect::<Vec<_>>(),
             )
         }
     };
 
+    let mut arg_range = 0..sig.inputs().len();
+
+    // Take the `self` ("receiver") argument out of the range (it's adjusted above).
+    if rcvr_adjustment.is_some() {
+        arg_range.start += 1;
+    }
+
+    // Take the last argument, if we need to untuple it (handled below).
+    if untuple_args.is_some() {
+        arg_range.end -= 1;
+    }
+
+    // Pass all of the non-special arguments directly.
+    args.extend(arg_range.map(|i| Operand::Move(Place::from(Local::new(1 + i)))));
+
+    // Untuple the last argument, if we have to.
     if let Some(untuple_args) = untuple_args {
+        let tuple_arg = Local::new(1 + (sig.inputs().len() - 1));
         args.extend(untuple_args.iter().enumerate().map(|(i, ity)| {
-            let arg_place = Place::from(Local::new(1 + 1));
-            Operand::Move(tcx.mk_place_field(arg_place, Field::new(i), *ity))
+            Operand::Move(tcx.mk_place_field(Place::from(tuple_arg), Field::new(i), *ity))
         }));
-    } else {
-        args.extend((1..sig.inputs().len()).map(|i| Operand::Move(Place::from(Local::new(1 + i)))));
     }
 
-    let n_blocks = if let Adjustment::RefMut = rcvr_adjustment { 5 } else { 2 };
+    let n_blocks = if let Some(Adjustment::RefMut) = rcvr_adjustment { 5 } else { 2 };
     let mut blocks = IndexVec::with_capacity(n_blocks);
     let block = |blocks: &mut IndexVec<_, _>, statements, kind, is_cleanup| {
         blocks.push(BasicBlockData {
@@ -752,7 +778,7 @@ fn build_call_shim<'tcx>(
             func: callee,
             args,
             destination: Some((Place::return_place(), BasicBlock::new(1))),
-            cleanup: if let Adjustment::RefMut = rcvr_adjustment {
+            cleanup: if let Some(Adjustment::RefMut) = rcvr_adjustment {
                 Some(BasicBlock::new(3))
             } else {
                 None
@@ -762,13 +788,13 @@ fn build_call_shim<'tcx>(
         false,
     );
 
-    if let Adjustment::RefMut = rcvr_adjustment {
+    if let Some(Adjustment::RefMut) = rcvr_adjustment {
         // BB #1 - drop for Self
         block(
             &mut blocks,
             vec![],
             TerminatorKind::Drop {
-                location: Place::from(rcvr_arg),
+                location: rcvr_place(),
                 target: BasicBlock::new(2),
                 unwind: None,
             },
@@ -777,13 +803,13 @@ fn build_call_shim<'tcx>(
     }
     // BB #1/#2 - return
     block(&mut blocks, vec![], TerminatorKind::Return, false);
-    if let Adjustment::RefMut = rcvr_adjustment {
+    if let Some(Adjustment::RefMut) = rcvr_adjustment {
         // BB #3 - drop if closure panics
         block(
             &mut blocks,
             vec![],
             TerminatorKind::Drop {
-                location: Place::from(rcvr_arg),
+                location: rcvr_place(),
                 target: BasicBlock::new(4),
                 unwind: None,
             },
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index bd398c6e5b4..d645f6cf183 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -14,7 +14,7 @@ use rustc::mir::{
     SourceInfo, SourceScope, SourceScopeData, Statement, StatementKind, Terminator, TerminatorKind,
     UnOp, RETURN_PLACE,
 };
-use rustc::traits::TraitQueryMode;
+use rustc::traits;
 use rustc::ty::layout::{
     HasDataLayout, HasTyCtxt, LayoutError, LayoutOf, Size, TargetDataLayout, TyLayout,
 };
@@ -90,28 +90,28 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
         // If there are unsatisfiable where clauses, then all bets are
         // off, and we just give up.
         //
-        // Note that we use TraitQueryMode::Canonical here, which causes
-        // us to treat overflow like any other error. This is because we
-        // are "speculatively" evaluating this item with the default substs.
-        // While this usually succeeds, it may fail with tricky impls
-        // (e.g. the typenum crate). Const-propagation is fundamentally
-        // "best-effort", and does not affect correctness in any way.
-        // Therefore, it's perfectly fine to just "give up" if we're
-        // unable to check the bounds with the default substs.
+        // We manually filter the predicates, skipping anything that's not
+        // "global". We are in a potentially generic context
+        // (e.g. we are evaluating a function without substituting generic
+        // parameters, so this filtering serves two purposes:
         //
-        // False negatives (failing to run const-prop on something when we actually
-        // could) are fine. However, false positives (running const-prop on
-        // an item with unsatisfiable bounds) can lead to us generating invalid
-        // MIR.
-        if !tcx.substitute_normalize_and_test_predicates((
-            source.def_id(),
-            InternalSubsts::identity_for_item(tcx, source.def_id()),
-            TraitQueryMode::Canonical,
-        )) {
-            trace!(
-                "ConstProp skipped for item with unsatisfiable predicates: {:?}",
-                source.def_id()
-            );
+        // 1. We skip evaluating any predicates that we would
+        // never be able prove are unsatisfiable (e.g. `<T as Foo>`
+        // 2. We avoid trying to normalize predicates involving generic
+        // parameters (e.g. `<T as Foo>::MyItem`). This can confuse
+        // the normalization code (leading to cycle errors), since
+        // it's usually never invoked in this way.
+        let predicates = tcx
+            .predicates_of(source.def_id())
+            .predicates
+            .iter()
+            .filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None })
+            .collect();
+        if !traits::normalize_and_test_predicates(
+            tcx,
+            traits::elaborate_predicates(tcx, predicates).collect(),
+        ) {
+            trace!("ConstProp skipped for {:?}: found unsatisfiable predicates", source.def_id());
             return;
         }
 
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 94068038253..ab38eec5f3e 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -2321,8 +2321,8 @@ fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Func
         "{}{}{}{}{:#}fn {}{:#}",
         it.visibility.print_with_space(),
         f.header.constness.print_with_space(),
-        f.header.unsafety.print_with_space(),
         f.header.asyncness.print_with_space(),
+        f.header.unsafety.print_with_space(),
         print_abi_with_space(f.header.abi),
         it.name.as_ref().unwrap(),
         f.generics.print()
@@ -2332,12 +2332,12 @@ fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Func
     render_attributes(w, it, false);
     write!(
         w,
-        "{vis}{constness}{unsafety}{asyncness}{abi}fn \
+        "{vis}{constness}{asyncness}{unsafety}{abi}fn \
            {name}{generics}{decl}{where_clause}</pre>",
         vis = it.visibility.print_with_space(),
         constness = f.header.constness.print_with_space(),
-        unsafety = f.header.unsafety.print_with_space(),
         asyncness = f.header.asyncness.print_with_space(),
+        unsafety = f.header.unsafety.print_with_space(),
         abi = print_abi_with_space(f.header.abi),
         name = it.name.as_ref().unwrap(),
         generics = f.generics.print(),
@@ -2832,8 +2832,8 @@ fn render_assoc_item(
             "{}{}{}{}{}{:#}fn {}{:#}",
             meth.visibility.print_with_space(),
             header.constness.print_with_space(),
-            header.unsafety.print_with_space(),
             header.asyncness.print_with_space(),
+            header.unsafety.print_with_space(),
             print_default_space(meth.is_default()),
             print_abi_with_space(header.abi),
             name,
@@ -2854,8 +2854,8 @@ fn render_assoc_item(
             if parent == ItemType::Trait { "    " } else { "" },
             meth.visibility.print_with_space(),
             header.constness.print_with_space(),
-            header.unsafety.print_with_space(),
             header.asyncness.print_with_space(),
+            header.unsafety.print_with_space(),
             print_default_space(meth.is_default()),
             print_abi_with_space(header.abi),
             href = href,
diff --git a/src/test/rustdoc/async-fn.rs b/src/test/rustdoc/async-fn.rs
index 5f9708a3972..5a03e821e8a 100644
--- a/src/test/rustdoc/async-fn.rs
+++ b/src/test/rustdoc/async-fn.rs
@@ -15,6 +15,11 @@ pub async fn baz<T>(a: T) -> T {
     a
 }
 
+// @has async_fn/fn.qux.html '//pre[@class="rust fn"]' 'pub async unsafe fn qux() -> char'
+pub async unsafe fn qux() -> char {
+    '⚠'
+}
+
 trait Bar {}
 
 impl Bar for () {}
@@ -26,8 +31,10 @@ pub async fn quux() -> impl Bar {
 
 // @has async_fn/struct.Foo.html
 // @matches - '//code' 'pub async fn f\(\)$'
+// @matches - '//code' 'pub async unsafe fn g\(\)$'
 pub struct Foo;
 
 impl Foo {
     pub async fn f() {}
+    pub async unsafe fn g() {}
 }
diff --git a/src/test/ui/async-await/async-fn-nonsend.rs b/src/test/ui/async-await/async-fn-nonsend.rs
index 645c903c6ba..ceeebbca519 100644
--- a/src/test/ui/async-await/async-fn-nonsend.rs
+++ b/src/test/ui/async-await/async-fn-nonsend.rs
@@ -2,15 +2,15 @@
 // edition:2018
 // compile-flags: --crate-type lib
 
-use std::{
-    cell::RefCell,
-    fmt::Debug,
-    rc::Rc,
-};
+use std::{cell::RefCell, fmt::Debug, rc::Rc};
 
-fn non_sync() -> impl Debug { RefCell::new(()) }
+fn non_sync() -> impl Debug {
+    RefCell::new(())
+}
 
-fn non_send() -> impl Debug { Rc::new(()) }
+fn non_send() -> impl Debug {
+    Rc::new(())
+}
 
 fn take_ref<T>(_: &T) {}
 
@@ -53,5 +53,4 @@ pub fn pass_assert() {
     //~^ ERROR future cannot be sent between threads safely
     assert_send(non_sync_with_method_call());
     //~^ ERROR future cannot be sent between threads safely
-    //~^^ ERROR future cannot be sent between threads safely
 }
diff --git a/src/test/ui/async-await/async-fn-nonsend.stderr b/src/test/ui/async-await/async-fn-nonsend.stderr
index 5c870ca2d02..105fd23ecfb 100644
--- a/src/test/ui/async-await/async-fn-nonsend.stderr
+++ b/src/test/ui/async-await/async-fn-nonsend.stderr
@@ -62,27 +62,5 @@ LL |     }
 LL | }
    | - `f` is later dropped here
 
-error: future cannot be sent between threads safely
-  --> $DIR/async-fn-nonsend.rs:54:5
-   |
-LL | fn assert_send(_: impl Send) {}
-   |    -----------         ---- required by this bound in `assert_send`
-...
-LL |     assert_send(non_sync_with_method_call());
-   |     ^^^^^^^^^^^ future returned by `non_sync_with_method_call` is not `Send`
-   |
-   = help: within `std::fmt::ArgumentV1<'_>`, the trait `std::marker::Sync` is not implemented for `*mut (dyn std::ops::Fn() + 'static)`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/async-fn-nonsend.rs:43:9
-   |
-LL |     let f: &mut std::fmt::Formatter = panic!();
-   |         - has type `&mut std::fmt::Formatter<'_>`
-LL |     if non_sync().fmt(f).unwrap() == () {
-LL |         fut().await;
-   |         ^^^^^^^^^^^ await occurs here, with `f` maybe used later
-LL |     }
-LL | }
-   | - `f` is later dropped here
-
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/consts/array-literal-index-oob.rs b/src/test/ui/consts/array-literal-index-oob.rs
index 64aeb46894d..af63d1f75a7 100644
--- a/src/test/ui/consts/array-literal-index-oob.rs
+++ b/src/test/ui/consts/array-literal-index-oob.rs
@@ -1,4 +1,5 @@
 // build-pass
+// ignore-pass (emit codegen-time warnings and verify that they are indeed warnings and not errors)
 
 #![warn(const_err)]
 
diff --git a/src/test/ui/consts/array-literal-index-oob.stderr b/src/test/ui/consts/array-literal-index-oob.stderr
index 50ad8e83e90..e93aa324784 100644
--- a/src/test/ui/consts/array-literal-index-oob.stderr
+++ b/src/test/ui/consts/array-literal-index-oob.stderr
@@ -1,17 +1,17 @@
 warning: index out of bounds: the len is 3 but the index is 4
-  --> $DIR/array-literal-index-oob.rs:6:8
+  --> $DIR/array-literal-index-oob.rs:7:8
    |
 LL |     &{ [1, 2, 3][4] };
    |        ^^^^^^^^^^^^
    |
 note: lint level defined here
-  --> $DIR/array-literal-index-oob.rs:3:9
+  --> $DIR/array-literal-index-oob.rs:4:9
    |
 LL | #![warn(const_err)]
    |         ^^^^^^^^^
 
 warning: reaching this expression at runtime will panic or abort
-  --> $DIR/array-literal-index-oob.rs:6:8
+  --> $DIR/array-literal-index-oob.rs:7:8
    |
 LL |     &{ [1, 2, 3][4] };
    |     ---^^^^^^^^^^^^--
@@ -19,7 +19,7 @@ LL |     &{ [1, 2, 3][4] };
    |        indexing out of bounds: the len is 3 but the index is 4
 
 warning: erroneous constant used
-  --> $DIR/array-literal-index-oob.rs:6:5
+  --> $DIR/array-literal-index-oob.rs:7:5
    |
 LL |     &{ [1, 2, 3][4] };
    |     ^^^^^^^^^^^^^^^^^ referenced constant has errors
diff --git a/src/test/ui/consts/const-eval/promoted_errors.rs b/src/test/ui/consts/const-eval/promoted_errors.rs
index fee232185d2..22f863fb15a 100644
--- a/src/test/ui/consts/const-eval/promoted_errors.rs
+++ b/src/test/ui/consts/const-eval/promoted_errors.rs
@@ -1,4 +1,5 @@
 // build-pass
+// ignore-pass (emit codegen-time warnings and verify that they are indeed warnings and not errors)
 // compile-flags: -O
 
 #![warn(const_err)]
diff --git a/src/test/ui/consts/const-eval/promoted_errors.stderr b/src/test/ui/consts/const-eval/promoted_errors.stderr
index 4de22fdf4ab..b4330deb3ef 100644
--- a/src/test/ui/consts/const-eval/promoted_errors.stderr
+++ b/src/test/ui/consts/const-eval/promoted_errors.stderr
@@ -1,59 +1,59 @@
 warning: this expression will panic at runtime
-  --> $DIR/promoted_errors.rs:8:14
+  --> $DIR/promoted_errors.rs:9:14
    |
 LL |     let _x = 0u32 - 1;
    |              ^^^^^^^^ attempt to subtract with overflow
    |
 note: lint level defined here
-  --> $DIR/promoted_errors.rs:4:9
+  --> $DIR/promoted_errors.rs:5:9
    |
 LL | #![warn(const_err)]
    |         ^^^^^^^^^
 
 warning: attempt to divide by zero
-  --> $DIR/promoted_errors.rs:10:20
+  --> $DIR/promoted_errors.rs:11:20
    |
 LL |     println!("{}", 1 / (1 - 1));
    |                    ^^^^^^^^^^^
 
 warning: reaching this expression at runtime will panic or abort
-  --> $DIR/promoted_errors.rs:10:20
+  --> $DIR/promoted_errors.rs:11:20
    |
 LL |     println!("{}", 1 / (1 - 1));
    |                    ^^^^^^^^^^^ dividing by zero
 
 warning: erroneous constant used
-  --> $DIR/promoted_errors.rs:10:20
+  --> $DIR/promoted_errors.rs:11:20
    |
 LL |     println!("{}", 1 / (1 - 1));
    |                    ^^^^^^^^^^^ referenced constant has errors
 
 warning: attempt to divide by zero
-  --> $DIR/promoted_errors.rs:14:14
+  --> $DIR/promoted_errors.rs:15:14
    |
 LL |     let _x = 1 / (1 - 1);
    |              ^^^^^^^^^^^
 
 warning: attempt to divide by zero
-  --> $DIR/promoted_errors.rs:16:20
+  --> $DIR/promoted_errors.rs:17:20
    |
 LL |     println!("{}", 1 / (false as u32));
    |                    ^^^^^^^^^^^^^^^^^^
 
 warning: reaching this expression at runtime will panic or abort
-  --> $DIR/promoted_errors.rs:16:20
+  --> $DIR/promoted_errors.rs:17:20
    |
 LL |     println!("{}", 1 / (false as u32));
    |                    ^^^^^^^^^^^^^^^^^^ dividing by zero
 
 warning: erroneous constant used
-  --> $DIR/promoted_errors.rs:16:20
+  --> $DIR/promoted_errors.rs:17:20
    |
 LL |     println!("{}", 1 / (false as u32));
    |                    ^^^^^^^^^^^^^^^^^^ referenced constant has errors
 
 warning: attempt to divide by zero
-  --> $DIR/promoted_errors.rs:20:14
+  --> $DIR/promoted_errors.rs:21:14
    |
 LL |     let _x = 1 / (false as u32);
    |              ^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/consts/const-eval/promoted_errors2.rs b/src/test/ui/consts/const-eval/promoted_errors2.rs
index 41a989d91c5..62c77f76d90 100644
--- a/src/test/ui/consts/const-eval/promoted_errors2.rs
+++ b/src/test/ui/consts/const-eval/promoted_errors2.rs
@@ -1,4 +1,5 @@
 // build-pass
+// ignore-pass (emit codegen-time warnings and verify that they are indeed warnings and not errors)
 // compile-flags: -C overflow-checks=on -O
 
 #![warn(const_err)]
diff --git a/src/test/ui/consts/const-eval/promoted_errors2.stderr b/src/test/ui/consts/const-eval/promoted_errors2.stderr
index 4f7ba8bf385..a4dad295edd 100644
--- a/src/test/ui/consts/const-eval/promoted_errors2.stderr
+++ b/src/test/ui/consts/const-eval/promoted_errors2.stderr
@@ -1,65 +1,65 @@
 warning: attempt to subtract with overflow
-  --> $DIR/promoted_errors2.rs:7:20
+  --> $DIR/promoted_errors2.rs:8:20
    |
 LL |     println!("{}", 0u32 - 1);
    |                    ^^^^^^^^
    |
 note: lint level defined here
-  --> $DIR/promoted_errors2.rs:4:9
+  --> $DIR/promoted_errors2.rs:5:9
    |
 LL | #![warn(const_err)]
    |         ^^^^^^^^^
 
 warning: attempt to subtract with overflow
-  --> $DIR/promoted_errors2.rs:9:14
+  --> $DIR/promoted_errors2.rs:10:14
    |
 LL |     let _x = 0u32 - 1;
    |              ^^^^^^^^
 
 warning: attempt to divide by zero
-  --> $DIR/promoted_errors2.rs:11:20
+  --> $DIR/promoted_errors2.rs:12:20
    |
 LL |     println!("{}", 1 / (1 - 1));
    |                    ^^^^^^^^^^^
 
 warning: reaching this expression at runtime will panic or abort
-  --> $DIR/promoted_errors2.rs:11:20
+  --> $DIR/promoted_errors2.rs:12:20
    |
 LL |     println!("{}", 1 / (1 - 1));
    |                    ^^^^^^^^^^^ dividing by zero
 
 warning: erroneous constant used
-  --> $DIR/promoted_errors2.rs:11:20
+  --> $DIR/promoted_errors2.rs:12:20
    |
 LL |     println!("{}", 1 / (1 - 1));
    |                    ^^^^^^^^^^^ referenced constant has errors
 
 warning: attempt to divide by zero
-  --> $DIR/promoted_errors2.rs:15:14
+  --> $DIR/promoted_errors2.rs:16:14
    |
 LL |     let _x = 1 / (1 - 1);
    |              ^^^^^^^^^^^
 
 warning: attempt to divide by zero
-  --> $DIR/promoted_errors2.rs:17:20
+  --> $DIR/promoted_errors2.rs:18:20
    |
 LL |     println!("{}", 1 / (false as u32));
    |                    ^^^^^^^^^^^^^^^^^^
 
 warning: reaching this expression at runtime will panic or abort
-  --> $DIR/promoted_errors2.rs:17:20
+  --> $DIR/promoted_errors2.rs:18:20
    |
 LL |     println!("{}", 1 / (false as u32));
    |                    ^^^^^^^^^^^^^^^^^^ dividing by zero
 
 warning: erroneous constant used
-  --> $DIR/promoted_errors2.rs:17:20
+  --> $DIR/promoted_errors2.rs:18:20
    |
 LL |     println!("{}", 1 / (false as u32));
    |                    ^^^^^^^^^^^^^^^^^^ referenced constant has errors
 
 warning: attempt to divide by zero
-  --> $DIR/promoted_errors2.rs:21:14
+  --> $DIR/promoted_errors2.rs:22:14
    |
 LL |     let _x = 1 / (false as u32);
    |              ^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/consts/issue-68264-overflow.rs b/src/test/ui/consts/issue-68264-overflow.rs
new file mode 100644
index 00000000000..8f21e0648d4
--- /dev/null
+++ b/src/test/ui/consts/issue-68264-overflow.rs
@@ -0,0 +1,43 @@
+// check-pass
+// compile-flags: --emit=mir,link
+// Regression test for issue #68264
+// Checks that we don't encounter overflow
+// when running const-prop on functions with
+// complicated bounds
+pub trait Query {}
+
+pub trait AsQuery {
+    type Query: Query;
+}
+pub trait Table: AsQuery + Sized {}
+
+pub trait LimitDsl {
+    type Output;
+}
+
+pub(crate) trait LoadQuery<Conn, U>: RunQueryDsl<Conn> {}
+
+impl<T: Query> AsQuery for T {
+    type Query = Self;
+}
+
+impl<T> LimitDsl for T
+where
+    T: Table,
+    T::Query: LimitDsl,
+{
+    type Output = <T::Query as LimitDsl>::Output;
+}
+
+pub(crate) trait RunQueryDsl<Conn>: Sized {
+    fn first<U>(self, _conn: &Conn) -> U
+    where
+        Self: LimitDsl,
+        Self::Output: LoadQuery<Conn, U>,
+    {
+        // Overflow is caused by this function body
+        unimplemented!()
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs b/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs
new file mode 100644
index 00000000000..0407eafbfd4
--- /dev/null
+++ b/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs
@@ -0,0 +1,19 @@
+// run-pass
+
+#![feature(track_caller)]
+
+fn pass_to_ptr_call<T>(f: fn(T), x: T) {
+    f(x);
+}
+
+#[track_caller]
+fn tracked_unit(_: ()) {
+    let expected_line = line!() - 1;
+    let location = std::panic::Location::caller();
+    assert_eq!(location.file(), file!());
+    assert_eq!(location.line(), expected_line, "call shims report location as fn definition");
+}
+
+fn main() {
+    pass_to_ptr_call(tracked_unit, ());
+}
diff --git a/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr.rs b/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr.rs
new file mode 100644
index 00000000000..a4baaa26ced
--- /dev/null
+++ b/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr.rs
@@ -0,0 +1,19 @@
+// run-pass
+
+#![feature(track_caller)]
+
+fn ptr_call(f: fn()) {
+    f();
+}
+
+#[track_caller]
+fn tracked() {
+    let expected_line = line!() - 1;
+    let location = std::panic::Location::caller();
+    assert_eq!(location.file(), file!());
+    assert_eq!(location.line(), expected_line, "call shims report location as fn definition");
+}
+
+fn main() {
+    ptr_call(tracked);
+}
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index 481163a1a9a..cff04e197e4 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -110,6 +110,7 @@ static TARGETS: &[&str] = &[
     "riscv32imac-unknown-none-elf",
     "riscv64imac-unknown-none-elf",
     "riscv64gc-unknown-none-elf",
+    "riscv64gc-unknown-linux-gnu",
     "s390x-unknown-linux-gnu",
     "sparc64-unknown-linux-gnu",
     "sparcv9-sun-solaris",