diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index 3fdee8bbfdf10..c1ae67a1a339f 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 19acc70c73c8e..2a9bfefc713e7 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -131,6 +131,21 @@ fn test_extend_ref() { assert_eq!(v, [1, 2, 3, 4, 5, 6, 7]); } +#[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 93a51ccb20737..a27a13847d6a2 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -1688,7 +1688,9 @@ impl Vec { pub fn dedup(&mut self) { self.dedup_by(|a, b| a == b) } +} +impl Vec { /// Removes the first instance of `item` from the vector if the item exists. /// /// # Examples @@ -1702,7 +1704,10 @@ impl Vec { /// 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 { + pub fn remove_item(&mut self, item: &V) -> Option + where + T: PartialEq, + { 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 596da6f786bbd..752199c94b8ae 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 { - 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 { 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 { + 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 { + 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 7b20677ffb54c..d562639a6588d 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 65af671ddf204..55f30794af652 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>(iter: I) -> $a { + fn sum>(iter: I) -> Self { iter.fold($zero, Add::add) } } #[$attr] impl Product for $a { - fn product>(iter: I) -> $a { + fn product>(iter: I) -> Self { iter.fold($one, Mul::mul) } } #[$attr] impl<'a> Sum<&'a $a> for $a { - fn sum>(iter: I) -> $a { + fn sum>(iter: I) -> Self { iter.fold($zero, Add::add) } } #[$attr] impl<'a> Product<&'a $a> for $a { - fn product>(iter: I) -> $a { + fn product>(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>(iter: I) -> $a { + fn sum>(iter: I) -> Self { iter.fold(0.0, Add::add) } } #[stable(feature = "iter_arith_traits", since = "1.12.0")] impl Product for $a { - fn product>(iter: I) -> $a { + fn product>(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>(iter: I) -> $a { + fn sum>(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>(iter: I) -> $a { + fn product>(iter: I) -> Self { iter.fold(1.0, Mul::mul) } } diff --git a/src/libcore/macros/mod.rs b/src/libcore/macros/mod.rs index 0eb9e19423617..76e58f0cc62bc 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 3b98bc1c272f0..b4b595f330e22 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 Clone for $t { - fn clone(&self) -> $t { - $t + fn clone(&self) -> Self { + Self } } #[stable(feature = "rust1", since = "1.0.0")] impl Default for $t { - fn default() -> $t { - $t + fn default() -> Self { + Self } } diff --git a/src/libcore/num/bignum.rs b/src/libcore/num/bignum.rs index 39cc381b64c74..6f16b93d0488a 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 3fef1dd064edb..009e52e479a61 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 a7e716ad7b730..e315de115688b 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 63345f828e09c..5f599034e7d4d 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 7be179a2098c1..78dd6fc8ffe75 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 4b4fbd0e1ad53..bccf3f5735cc8 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 88e692cb11747..a1e81c10b415e 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 0e121df1d257e..1c7146308389a 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 e0a946a38e4d0..681bc1f2dcb77 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 d55620f657ba9..46e76512d35fc 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 032062d636040..a28bb539fd070 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 d6fd48cc89fa0..efbbca534856a 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 231ee792918b3..dca850462ce2e 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 770aeb6869a8a..f8c1af038e967 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 c315cefc1b88b..85661621fbaf6 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 { } 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 { "⚙️ This is an internal compiler API." @@ -2214,7 +2214,7 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec { } .to_owned(); - if let Some(feature) = stab.feature.as_ref() { + if let Some(feature) = stab.feature.as_deref() { let mut feature = format!("{}", 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 0000000000000..f3be7b56db589 --- /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([u32; 0 + N]); // ok + +#[derive(PartialEq, Eq)] +struct Config { + arr_size: usize, +} + +struct B { + arr: [u8; CFG.arr_size], // ok +} + +const C: Config = Config { arr_size: 5 }; + +fn main() { + let b = B:: { 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 0000000000000..274f97697029e --- /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 b7fc564a9b59a..3fd576a8d3580 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 0000000000000..21851a725254f --- /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::(); +} + +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() +where I: Foo, + I::Item: Bar +{ + Vec::<::Item2>::new(); // ICE occurs processing this line +}