about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-01-06 09:31:27 +0000
committerbors <bors@rust-lang.org>2020-01-06 09:31:27 +0000
commita80e63f3fa77792e848e3b248acf4c0acda2e310 (patch)
tree6e9574bac0128d5184af68d208b2ee8d9e98e416 /src
parent33640f0e03af2fb31ce380d5389d5545f24ce29a (diff)
parent34716a31db9371501fe98100a7aa1566f37c1d23 (diff)
downloadrust-a80e63f3fa77792e848e3b248acf4c0acda2e310.tar.gz
rust-a80e63f3fa77792e848e3b248acf4c0acda2e310.zip
Auto merge of #67917 - Dylan-DPC:rollup-id05y91, r=Dylan-DPC
Rollup of 6 pull requests

Successful merges:

 - #67800 (Fix ICE involving calling `Instance.ty` during const evaluation)
 - #67873 (change remove to have a PartialEq bound)
 - #67897 (Use `as_deref()` to replace `as_ref().map(...)`)
 - #67906 (Silence `TooGeneric` error)
 - #67912 (macros: typo fix)
 - #67915 (Use Self instead of $type)

Failed merges:

r? @ghost
Diffstat (limited to 'src')
-rw-r--r--src/liballoc/tests/lib.rs1
-rw-r--r--src/liballoc/tests/vec.rs15
-rw-r--r--src/liballoc/vec.rs7
-rw-r--r--src/libcore/convert/num.rs28
-rw-r--r--src/libcore/fmt/num.rs4
-rw-r--r--src/libcore/iter/traits/accum.rs16
-rw-r--r--src/libcore/macros/mod.rs2
-rw-r--r--src/libcore/marker.rs8
-rw-r--r--src/libcore/num/bignum.rs4
-rw-r--r--src/librustc/traits/error_reporting.rs6
-rw-r--r--src/librustc/ty/instance.rs27
-rw-r--r--src/librustc/ty/layout.rs2
-rw-r--r--src/librustc_codegen_llvm/callee.rs2
-rw-r--r--src/librustc_codegen_llvm/consts.rs4
-rw-r--r--src/librustc_codegen_llvm/debuginfo/metadata.rs2
-rw-r--r--src/librustc_codegen_llvm/intrinsic.rs2
-rw-r--r--src/librustc_codegen_llvm/mono_item.rs2
-rw-r--r--src/librustc_mir/const_eval/eval_queries.rs2
-rw-r--r--src/librustc_mir/interpret/terminator.rs2
-rw-r--r--src/librustc_mir/interpret/traits.rs2
-rw-r--r--src/librustc_mir/monomorphize/collector.rs5
-rw-r--r--src/librustc_typeck/impl_wf_check.rs5
-rw-r--r--src/librustdoc/html/render.rs6
-rw-r--r--src/test/ui/const-generics/array-size-in-generic-struct-param.rs23
-rw-r--r--src/test/ui/const-generics/array-size-in-generic-struct-param.stderr8
-rw-r--r--src/test/ui/issues/issue-8460.rs4
-rw-r--r--src/test/ui/mir/issue-67639-normalization-ice.rs34
27 files changed, 172 insertions, 51 deletions
diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs
index 3fdee8bbfdf..c1ae67a1a33 100644
--- a/src/liballoc/tests/lib.rs
+++ b/src/liballoc/tests/lib.rs
@@ -11,6 +11,7 @@
 #![feature(associated_type_bounds)]
 #![feature(binary_heap_into_iter_sorted)]
 #![feature(binary_heap_drain_sorted)]
+#![feature(vec_remove_item)]
 
 use std::collections::hash_map::DefaultHasher;
 use std::hash::{Hash, Hasher};
diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs
index 19acc70c73c..2a9bfefc713 100644
--- a/src/liballoc/tests/vec.rs
+++ b/src/liballoc/tests/vec.rs
@@ -132,6 +132,21 @@ fn test_extend_ref() {
 }
 
 #[test]
+fn test_remove_item() {
+    let mut v = vec![1, 2, 3];
+    v.remove_item(&1);
+
+    assert_eq!(v.len(), 2);
+    assert_eq!(v, [2, 3]);
+
+    let mut w = vec![1, 2, 3];
+    w.remove_item(&4);
+
+    assert_eq!(w.len(), 3);
+    w.remove_item(&4);
+}
+
+#[test]
 fn test_slice_from_mut() {
     let mut values = vec![1, 2, 3, 4, 5];
     {
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index 93a51ccb207..a27a13847d6 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -1688,7 +1688,9 @@ impl<T: PartialEq> Vec<T> {
     pub fn dedup(&mut self) {
         self.dedup_by(|a, b| a == b)
     }
+}
 
+impl<T> Vec<T> {
     /// Removes the first instance of `item` from the vector if the item exists.
     ///
     /// # Examples
@@ -1702,7 +1704,10 @@ impl<T: PartialEq> Vec<T> {
     /// assert_eq!(vec, vec![2, 3, 1]);
     /// ```
     #[unstable(feature = "vec_remove_item", reason = "recently added", issue = "40062")]
-    pub fn remove_item(&mut self, item: &T) -> Option<T> {
+    pub fn remove_item<V>(&mut self, item: &V) -> Option<T>
+    where
+        T: PartialEq<V>,
+    {
         let pos = self.iter().position(|x| *x == *item)?;
         Some(self.remove(pos))
     }
diff --git a/src/libcore/convert/num.rs b/src/libcore/convert/num.rs
index 596da6f786b..752199c94b8 100644
--- a/src/libcore/convert/num.rs
+++ b/src/libcore/convert/num.rs
@@ -47,8 +47,8 @@ macro_rules! impl_from {
         #[doc = $doc]
         impl From<$Small> for $Large {
             #[inline]
-            fn from(small: $Small) -> $Large {
-                small as $Large
+            fn from(small: $Small) -> Self {
+                small as Self
             }
         }
     };
@@ -177,7 +177,7 @@ macro_rules! try_from_unbounded {
             /// is outside of the range of the target type.
             #[inline]
             fn try_from(value: $source) -> Result<Self, Self::Error> {
-                Ok(value as $target)
+                Ok(value as Self)
             }
         }
     )*}
@@ -194,9 +194,9 @@ macro_rules! try_from_lower_bounded {
             /// number type. This returns an error if the source value
             /// is outside of the range of the target type.
             #[inline]
-            fn try_from(u: $source) -> Result<$target, TryFromIntError> {
+            fn try_from(u: $source) -> Result<Self, Self::Error> {
                 if u >= 0 {
-                    Ok(u as $target)
+                    Ok(u as Self)
                 } else {
                     Err(TryFromIntError(()))
                 }
@@ -216,11 +216,11 @@ macro_rules! try_from_upper_bounded {
             /// number type. This returns an error if the source value
             /// is outside of the range of the target type.
             #[inline]
-            fn try_from(u: $source) -> Result<$target, TryFromIntError> {
-                if u > (<$target>::max_value() as $source) {
+            fn try_from(u: $source) -> Result<Self, Self::Error> {
+                if u > (Self::max_value() as $source) {
                     Err(TryFromIntError(()))
                 } else {
-                    Ok(u as $target)
+                    Ok(u as Self)
                 }
             }
         }
@@ -238,13 +238,13 @@ macro_rules! try_from_both_bounded {
             /// number type. This returns an error if the source value
             /// is outside of the range of the target type.
             #[inline]
-            fn try_from(u: $source) -> Result<$target, TryFromIntError> {
-                let min = <$target>::min_value() as $source;
-                let max = <$target>::max_value() as $source;
+            fn try_from(u: $source) -> Result<Self, Self::Error> {
+                let min = Self::min_value() as $source;
+                let max = Self::max_value() as $source;
                 if u < min || u > max {
                     Err(TryFromIntError(()))
                 } else {
-                    Ok(u as $target)
+                    Ok(u as Self)
                 }
             }
         }
@@ -385,10 +385,10 @@ macro_rules! nzint_impl_from {
         #[doc = $doc]
         impl From<$Small> for $Large {
             #[inline]
-            fn from(small: $Small) -> $Large {
+            fn from(small: $Small) -> Self {
                 // SAFETY: input type guarantees the value is non-zero
                 unsafe {
-                    <$Large>::new_unchecked(small.get().into())
+                    Self::new_unchecked(small.get().into())
                 }
             }
         }
diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs
index 7b20677ffb5..d562639a658 100644
--- a/src/libcore/fmt/num.rs
+++ b/src/libcore/fmt/num.rs
@@ -24,8 +24,8 @@ trait Int:
 
 macro_rules! doit {
     ($($t:ident)*) => ($(impl Int for $t {
-        fn zero() -> $t { 0 }
-        fn from_u8(u: u8) -> $t { u as $t }
+        fn zero() -> Self { 0 }
+        fn from_u8(u: u8) -> Self { u as Self }
         fn to_u8(&self) -> u8 { *self as u8 }
         fn to_u16(&self) -> u16 { *self as u16 }
         fn to_u32(&self) -> u32 { *self as u32 }
diff --git a/src/libcore/iter/traits/accum.rs b/src/libcore/iter/traits/accum.rs
index 65af671ddf2..55f30794af6 100644
--- a/src/libcore/iter/traits/accum.rs
+++ b/src/libcore/iter/traits/accum.rs
@@ -44,28 +44,28 @@ macro_rules! integer_sum_product {
     (@impls $zero:expr, $one:expr, #[$attr:meta], $($a:ty)*) => ($(
         #[$attr]
         impl Sum for $a {
-            fn sum<I: Iterator<Item=$a>>(iter: I) -> $a {
+            fn sum<I: Iterator<Item=Self>>(iter: I) -> Self {
                 iter.fold($zero, Add::add)
             }
         }
 
         #[$attr]
         impl Product for $a {
-            fn product<I: Iterator<Item=$a>>(iter: I) -> $a {
+            fn product<I: Iterator<Item=Self>>(iter: I) -> Self {
                 iter.fold($one, Mul::mul)
             }
         }
 
         #[$attr]
         impl<'a> Sum<&'a $a> for $a {
-            fn sum<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
+            fn sum<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
                 iter.fold($zero, Add::add)
             }
         }
 
         #[$attr]
         impl<'a> Product<&'a $a> for $a {
-            fn product<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
+            fn product<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
                 iter.fold($one, Mul::mul)
             }
         }
@@ -84,28 +84,28 @@ macro_rules! float_sum_product {
     ($($a:ident)*) => ($(
         #[stable(feature = "iter_arith_traits", since = "1.12.0")]
         impl Sum for $a {
-            fn sum<I: Iterator<Item=$a>>(iter: I) -> $a {
+            fn sum<I: Iterator<Item=Self>>(iter: I) -> Self {
                 iter.fold(0.0, Add::add)
             }
         }
 
         #[stable(feature = "iter_arith_traits", since = "1.12.0")]
         impl Product for $a {
-            fn product<I: Iterator<Item=$a>>(iter: I) -> $a {
+            fn product<I: Iterator<Item=Self>>(iter: I) -> Self {
                 iter.fold(1.0, Mul::mul)
             }
         }
 
         #[stable(feature = "iter_arith_traits", since = "1.12.0")]
         impl<'a> Sum<&'a $a> for $a {
-            fn sum<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
+            fn sum<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
                 iter.fold(0.0, Add::add)
             }
         }
 
         #[stable(feature = "iter_arith_traits", since = "1.12.0")]
         impl<'a> Product<&'a $a> for $a {
-            fn product<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
+            fn product<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
                 iter.fold(1.0, Mul::mul)
             }
         }
diff --git a/src/libcore/macros/mod.rs b/src/libcore/macros/mod.rs
index 0eb9e194236..76e58f0cc62 100644
--- a/src/libcore/macros/mod.rs
+++ b/src/libcore/macros/mod.rs
@@ -551,7 +551,7 @@ macro_rules! unreachable {
 
 /// Indicates unimplemented code by panicking with a message of "not implemented".
 ///
-/// This allows the your code to type-check, which is useful if you are prototyping or
+/// This allows your code to type-check, which is useful if you are prototyping or
 /// implementing a trait that requires multiple methods which you don't plan of using all of.
 ///
 /// The difference between `unimplemented!` and [`todo!`](macro.todo.html) is that while `todo!`
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 3b98bc1c272..b4b595f330e 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -505,15 +505,15 @@ macro_rules! impls {
 
         #[stable(feature = "rust1", since = "1.0.0")]
         impl<T: ?Sized> Clone for $t<T> {
-            fn clone(&self) -> $t<T> {
-                $t
+            fn clone(&self) -> Self {
+                Self
             }
         }
 
         #[stable(feature = "rust1", since = "1.0.0")]
         impl<T: ?Sized> Default for $t<T> {
-            fn default() -> $t<T> {
-                $t
+            fn default() -> Self {
+                Self
             }
         }
 
diff --git a/src/libcore/num/bignum.rs b/src/libcore/num/bignum.rs
index 39cc381b64c..6f16b93d048 100644
--- a/src/libcore/num/bignum.rs
+++ b/src/libcore/num/bignum.rs
@@ -455,8 +455,8 @@ macro_rules! define_bignum {
         }
 
         impl crate::clone::Clone for $name {
-            fn clone(&self) -> $name {
-                $name { size: self.size, base: self.base }
+            fn clone(&self) -> Self {
+                Self { size: self.size, base: self.base }
             }
         }
 
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 3fef1dd064e..009e52e479a 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -12,6 +12,7 @@ use crate::hir::Node;
 use crate::infer::error_reporting::TypeAnnotationNeeded as ErrorCode;
 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use crate::infer::{self, InferCtxt};
+use crate::mir::interpret::ErrorHandled;
 use crate::session::DiagnosticMessageId;
 use crate::ty::error::ExpectedFound;
 use crate::ty::fast_reject;
@@ -1086,6 +1087,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
 
             // already reported in the query
             ConstEvalFailure(err) => {
+                if let ErrorHandled::TooGeneric = err {
+                    // Silence this error, as it can be produced during intermediate steps
+                    // when a constant is not yet able to be evaluated (but will be later).
+                    return;
+                }
                 self.tcx.sess.delay_span_bug(
                     span,
                     &format!("constant in type had an ignored error: {:?}", err),
diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs
index a7e716ad7b7..e315de11568 100644
--- a/src/librustc/ty/instance.rs
+++ b/src/librustc/ty/instance.rs
@@ -62,10 +62,35 @@ pub enum InstanceDef<'tcx> {
 }
 
 impl<'tcx> Instance<'tcx> {
-    pub fn ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
+    /// Returns the `Ty` corresponding to this `Instance`,
+    /// with generic substitutions applied and lifetimes erased.
+    ///
+    /// This method can only be called when the 'substs' for this Instance
+    /// are fully monomorphic (no `ty::Param`'s are present).
+    /// This is usually the case (e.g. during codegen).
+    /// However, during constant evaluation, we may want
+    /// to try to resolve a `Instance` using generic parameters
+    /// (e.g. when we are attempting to to do const-propagation).
+    /// In this case, `Instance.ty_env` should be used to provide
+    /// the `ParamEnv` for our generic context.
+    pub fn monomorphic_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         let ty = tcx.type_of(self.def.def_id());
+        // There shouldn't be any params - if there are, then
+        // Instance.ty_env should have been used to provide the proper
+        // ParamEnv
+        if self.substs.has_param_types() {
+            bug!("Instance.ty called for type {:?} with params in substs: {:?}", ty, self.substs);
+        }
         tcx.subst_and_normalize_erasing_regions(self.substs, ty::ParamEnv::reveal_all(), &ty)
     }
+
+    /// Like `Instance.ty`, but allows a `ParamEnv` to be specified for use during
+    /// normalization. This method is only really useful during constant evaluation,
+    /// where we are dealing with potentially generic types.
+    pub fn ty_env(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Ty<'tcx> {
+        let ty = tcx.type_of(self.def.def_id());
+        tcx.subst_and_normalize_erasing_regions(self.substs, param_env, &ty)
+    }
 }
 
 impl<'tcx> InstanceDef<'tcx> {
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index 63345f828e0..5f599034e7d 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -2301,7 +2301,7 @@ impl<'tcx> ty::Instance<'tcx> {
     // or should go through `FnAbi` instead, to avoid losing any
     // adjustments `FnAbi::of_instance` might be performing.
     fn fn_sig_for_fn_abi(&self, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> {
-        let ty = self.ty(tcx);
+        let ty = self.monomorphic_ty(tcx);
         match ty.kind {
             ty::FnDef(..) |
             // Shims currently have type FnPtr. Not sure this should remain.
diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs
index 7be179a2098..78dd6fc8ffe 100644
--- a/src/librustc_codegen_llvm/callee.rs
+++ b/src/librustc_codegen_llvm/callee.rs
@@ -36,7 +36,7 @@ pub fn get_fn(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value
     }
 
     let sym = tcx.symbol_name(instance).name.as_str();
-    debug!("get_fn({:?}: {:?}) => {}", instance, instance.ty(cx.tcx()), sym);
+    debug!("get_fn({:?}: {:?}) => {}", instance, instance.monomorphic_ty(cx.tcx()), sym);
 
     let fn_abi = FnAbi::of_instance(cx, instance, &[]);
 
diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs
index 4b4fbd0e1ad..bccf3f5735c 100644
--- a/src/librustc_codegen_llvm/consts.rs
+++ b/src/librustc_codegen_llvm/consts.rs
@@ -204,7 +204,7 @@ impl CodegenCx<'ll, 'tcx> {
             def_id
         );
 
-        let ty = instance.ty(self.tcx);
+        let ty = instance.monomorphic_ty(self.tcx);
         let sym = self.tcx.symbol_name(instance).name;
 
         debug!("get_static: sym={} instance={:?}", sym, instance);
@@ -361,7 +361,7 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> {
             };
 
             let instance = Instance::mono(self.tcx, def_id);
-            let ty = instance.ty(self.tcx);
+            let ty = instance.monomorphic_ty(self.tcx);
             let llty = self.layout_of(ty).llvm_type(self);
             let g = if val_llty == llty {
                 g
diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs
index 88e692cb117..a1e81c10b41 100644
--- a/src/librustc_codegen_llvm/debuginfo/metadata.rs
+++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs
@@ -2287,7 +2287,7 @@ pub fn create_global_var_metadata(cx: &CodegenCx<'ll, '_>, def_id: DefId, global
     };
 
     let is_local_to_unit = is_node_local_to_unit(cx, def_id);
-    let variable_type = Instance::mono(cx.tcx, def_id).ty(cx.tcx);
+    let variable_type = Instance::mono(cx.tcx, def_id).monomorphic_ty(cx.tcx);
     let type_metadata = type_metadata(cx, variable_type, span);
     let var_name = SmallCStr::new(&tcx.item_name(def_id).as_str());
     let linkage_name = if no_mangle {
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs
index 0e121df1d25..1c714630838 100644
--- a/src/librustc_codegen_llvm/intrinsic.rs
+++ b/src/librustc_codegen_llvm/intrinsic.rs
@@ -89,7 +89,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
         span: Span,
     ) {
         let tcx = self.tcx;
-        let callee_ty = instance.ty(tcx);
+        let callee_ty = instance.monomorphic_ty(tcx);
 
         let (def_id, substs) = match callee_ty.kind {
             ty::FnDef(def_id, substs) => (def_id, substs),
diff --git a/src/librustc_codegen_llvm/mono_item.rs b/src/librustc_codegen_llvm/mono_item.rs
index e0a946a38e4..681bc1f2dcb 100644
--- a/src/librustc_codegen_llvm/mono_item.rs
+++ b/src/librustc_codegen_llvm/mono_item.rs
@@ -22,7 +22,7 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         symbol_name: &str,
     ) {
         let instance = Instance::mono(self.tcx, def_id);
-        let ty = instance.ty(self.tcx);
+        let ty = instance.monomorphic_ty(self.tcx);
         let llty = self.layout_of(ty).llvm_type(self);
 
         let g = self.define_global(symbol_name, llty).unwrap_or_else(|| {
diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs
index d55620f657b..46e76512d35 100644
--- a/src/librustc_mir/const_eval/eval_queries.rs
+++ b/src/librustc_mir/const_eval/eval_queries.rs
@@ -221,7 +221,7 @@ pub fn const_eval_validated_provider<'tcx>(
     // We call `const_eval` for zero arg intrinsics, too, in order to cache their value.
     // Catch such calls and evaluate them instead of trying to load a constant's MIR.
     if let ty::InstanceDef::Intrinsic(def_id) = key.value.instance.def {
-        let ty = key.value.instance.ty(tcx);
+        let ty = key.value.instance.ty_env(tcx, key.param_env);
         let substs = match ty.kind {
             ty::FnDef(_, substs) => substs,
             _ => bug!("intrinsic with type {:?}", ty),
diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs
index 032062d6360..a28bb539fd0 100644
--- a/src/librustc_mir/interpret/terminator.rs
+++ b/src/librustc_mir/interpret/terminator.rs
@@ -204,7 +204,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         // ABI check
         {
             let callee_abi = {
-                let instance_ty = instance.ty(*self.tcx);
+                let instance_ty = instance.ty_env(*self.tcx, self.param_env);
                 match instance_ty.kind {
                     ty::FnDef(..) => instance_ty.fn_sig(*self.tcx).abi(),
                     ty::Closure(..) => Abi::RustCall,
diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs
index d6fd48cc89f..efbbca53485 100644
--- a/src/librustc_mir/interpret/traits.rs
+++ b/src/librustc_mir/interpret/traits.rs
@@ -140,7 +140,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         // to determine the type.
         let drop_instance = self.memory.get_fn(drop_fn)?.as_instance()?;
         trace!("Found drop fn: {:?}", drop_instance);
-        let fn_sig = drop_instance.ty(*self.tcx).fn_sig(*self.tcx);
+        let fn_sig = drop_instance.ty_env(*self.tcx, self.param_env).fn_sig(*self.tcx);
         let fn_sig = self.tcx.normalize_erasing_late_bound_regions(self.param_env, &fn_sig);
         // The drop function takes `*mut T` where `T` is the type being dropped, so get that.
         let args = fn_sig.inputs();
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index 231ee792918..dca850462ce 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -358,7 +358,7 @@ fn collect_items_rec<'tcx>(
             // Sanity check whether this ended up being collected accidentally
             debug_assert!(should_monomorphize_locally(tcx, &instance));
 
-            let ty = instance.ty(tcx);
+            let ty = instance.monomorphic_ty(tcx);
             visit_drop_use(tcx, ty, true, &mut neighbors);
 
             recursion_depth_reset = None;
@@ -1002,7 +1002,8 @@ impl ItemLikeVisitor<'v> for RootCollector<'_, 'v> {
                             def_id_to_string(self.tcx, def_id)
                         );
 
-                        let ty = Instance::new(def_id, InternalSubsts::empty()).ty(self.tcx);
+                        let ty =
+                            Instance::new(def_id, InternalSubsts::empty()).monomorphic_ty(self.tcx);
                         visit_drop_use(self.tcx, ty, true, self.output);
                     }
                 }
diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs
index 770aeb6869a..f8c1af038e9 100644
--- a/src/librustc_typeck/impl_wf_check.rs
+++ b/src/librustc_typeck/impl_wf_check.rs
@@ -98,7 +98,10 @@ fn enforce_impl_params_are_constrained(
         // (#36836)
         tcx.sess.delay_span_bug(
             tcx.def_span(impl_def_id),
-            "potentially unconstrained type parameters weren't evaluated",
+            &format!(
+                "potentially unconstrained type parameters weren't evaluated: {:?}",
+                impl_self_ty,
+            ),
         );
         return;
     }
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index c315cefc1b8..85661621fba 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -2152,7 +2152,7 @@ fn stability_tags(item: &clean::Item) -> String {
     }
 
     if let Some(stab) = item.stability.as_ref().filter(|s| s.level == stability::Unstable) {
-        if stab.feature.as_ref().map(|s| &**s) == Some("rustc_private") {
+        if stab.feature.as_deref() == Some("rustc_private") {
             tags += &tag_html("internal", "Internal");
         } else {
             tags += &tag_html("unstable", "Experimental");
@@ -2205,7 +2205,7 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec<String> {
     }
 
     if let Some(stab) = item.stability.as_ref().filter(|stab| stab.level == stability::Unstable) {
-        let is_rustc_private = stab.feature.as_ref().map(|s| &**s) == Some("rustc_private");
+        let is_rustc_private = stab.feature.as_deref() == Some("rustc_private");
 
         let mut message = if is_rustc_private {
             "<span class='emoji'>⚙️</span> This is an internal compiler API."
@@ -2214,7 +2214,7 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec<String> {
         }
         .to_owned();
 
-        if let Some(feature) = stab.feature.as_ref() {
+        if let Some(feature) = stab.feature.as_deref() {
             let mut feature = format!("<code>{}</code>", Escape(&feature));
             if let (Some(url), Some(issue)) = (&cx.shared.issue_tracker_base_url, stab.issue) {
                 feature.push_str(&format!(
diff --git a/src/test/ui/const-generics/array-size-in-generic-struct-param.rs b/src/test/ui/const-generics/array-size-in-generic-struct-param.rs
new file mode 100644
index 00000000000..f3be7b56db5
--- /dev/null
+++ b/src/test/ui/const-generics/array-size-in-generic-struct-param.rs
@@ -0,0 +1,23 @@
+// run-pass
+
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+#[allow(dead_code)]
+struct ArithArrayLen<const N: usize>([u32; 0 + N]); // ok
+
+#[derive(PartialEq, Eq)]
+struct Config {
+    arr_size: usize,
+}
+
+struct B<const CFG: Config> {
+    arr: [u8; CFG.arr_size], // ok
+}
+
+const C: Config = Config { arr_size: 5 };
+
+fn main() {
+    let b = B::<C> { arr: [1, 2, 3, 4, 5] };
+    assert_eq!(b.arr.len(), 5);
+}
diff --git a/src/test/ui/const-generics/array-size-in-generic-struct-param.stderr b/src/test/ui/const-generics/array-size-in-generic-struct-param.stderr
new file mode 100644
index 00000000000..274f9769702
--- /dev/null
+++ b/src/test/ui/const-generics/array-size-in-generic-struct-param.stderr
@@ -0,0 +1,8 @@
+warning: the feature `const_generics` is incomplete and may cause the compiler to crash
+  --> $DIR/array-size-in-generic-struct-param.rs:3:12
+   |
+LL | #![feature(const_generics)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+
diff --git a/src/test/ui/issues/issue-8460.rs b/src/test/ui/issues/issue-8460.rs
index b7fc564a9b5..3fd576a8d35 100644
--- a/src/test/ui/issues/issue-8460.rs
+++ b/src/test/ui/issues/issue-8460.rs
@@ -11,8 +11,8 @@ trait Int {
 }
 macro_rules! doit {
     ($($t:ident)*) => ($(impl Int for $t {
-        fn zero() -> $t { 0 }
-        fn one() -> $t { 1 }
+        fn zero() -> Self { 0 }
+        fn one() -> Self { 1 }
     })*)
 }
 doit! { i8 i16 i32 i64 isize }
diff --git a/src/test/ui/mir/issue-67639-normalization-ice.rs b/src/test/ui/mir/issue-67639-normalization-ice.rs
new file mode 100644
index 00000000000..21851a72525
--- /dev/null
+++ b/src/test/ui/mir/issue-67639-normalization-ice.rs
@@ -0,0 +1,34 @@
+// compile-flags: -Z mir-opt-level=3
+// build-pass
+
+// This used to ICE in const-prop due
+// to an empty ParamEnv being used during normalization
+// of a generic type
+
+
+fn main() {
+    join_all::<u32>();
+}
+
+trait Foo {
+    type Item;
+}
+
+impl Foo for u32 {
+    type Item = u8;
+}
+
+trait Bar {
+    type Item2;
+}
+
+impl Bar for u8 {
+    type Item2 = u64;
+}
+
+fn join_all<I>()
+where I: Foo,
+    I::Item: Bar
+{
+    Vec::<<I::Item as Bar>::Item2>::new(); // ICE occurs processing this line
+}