From 4b57d2228b4f00e647efb10b0f874dd1fa9baefd Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 6 Nov 2019 21:26:40 -0500 Subject: [PATCH 1/7] Fix opaque types resulting from projections in function signature When we normalize the types in a function signature, we may end up resolving a projection to an opaque type (e.g. `Self::MyType` when we have `type MyType = impl SomeTrait`). When the projection is resolved, we will instantiate the generic parameters into fresh inference variables. While we do want to normalize projections to opaque types, we don't want to replace the explicit generic parameters (e.g. `T` in `impl MyTrait`) with inference variables. We want the opaque type in the function signature to be eligible to be a defining use of that opaque type - adding inference variables prevents this, since the opaque type substs now appears to refer to some specific type, rather than a generic type. To resolve this issue, we inspect the opaque types in the function signature after normalization. Any inference variables in the substs are replaced with the corresponding generic parameter in the identity substs (e.g. `T` in `impl MyTrait`). Note that normalization is the only way that we can end up with inference variables in opaque substs in a function signature - users have no way of getting inference variables into a function signature. Note that all of this refers to the opaque type (ty::Opaque) and its subst - *not* to the underlying type. Fixes #59342 --- src/librustc_typeck/check/mod.rs | 56 ++++++++++++++++++- src/librustc_typeck/collect.rs | 3 + .../ui/impl-trait/type-alias-generic-param.rs | 22 ++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/impl-trait/type-alias-generic-param.rs diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 512a49d13e7cf..c0b49bb591838 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -114,7 +114,7 @@ use rustc::ty::{ use rustc::ty::adjustment::{ Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast }; -use rustc::ty::fold::TypeFoldable; +use rustc::ty::fold::{TypeFoldable, TypeFolder}; use rustc::ty::query::Providers; use rustc::ty::subst::{ GenericArgKind, Subst, InternalSubsts, SubstsRef, UserSelfTy, UserSubsts, @@ -872,6 +872,58 @@ fn used_trait_imports(tcx: TyCtxt<'_>, def_id: DefId) -> &DefIdSet { &*tcx.typeck_tables_of(def_id).used_trait_imports } +/// Inspects the substs of opaque types, replacing any inference variables +/// with proper generic parameter from the identity substs. +/// +/// This is run after we normalize the function signature, to fix any inference +/// variables introduced by the projection of associated types. This ensures that +/// any opaque types used in the signature continue to refer to generic parameters, +/// allowing them to be considered for defining uses in the function body +fn fixup_opaque_types<'tcx, T>(tcx: TyCtxt<'tcx>, val: &T) -> T where T: TypeFoldable<'tcx> { + struct FixupFolder<'tcx> { + tcx: TyCtxt<'tcx> + } + + impl<'tcx> TypeFolder<'tcx> for FixupFolder<'tcx> { + fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { + self.tcx + } + + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + match ty.kind { + ty::Opaque(def_id, substs) => { + debug!("fixup_opaque_types: found type {:?}", ty); + if ty.has_infer_types() { + let new_substs = InternalSubsts::for_item(self.tcx, def_id, |param, _| { + let old_param = substs[param.index as usize]; + match old_param.unpack() { + GenericArgKind::Type(old_ty) => { + if let ty::Infer(_) = old_ty.kind { + // Replace inference type with a generic parameter + self.tcx.mk_param_from_def(param) + } else { + old_param.fold_with(self) + } + }, + _ => old_param + } + }); + let new_ty = self.tcx.mk_opaque(def_id, new_substs); + debug!("fixup_opaque_types: new type: {:?}", new_ty); + new_ty + } else { + ty + } + }, + _ => ty.super_fold_with(self) + } + } + } + + debug!("fixup_opaque_types({:?})", val); + val.fold_with(&mut FixupFolder { tcx }) +} + fn typeck_tables_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TypeckTables<'_> { // Closures' tables come from their outermost function, // as they are part of the same "inference environment". @@ -911,6 +963,8 @@ fn typeck_tables_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TypeckTables<'_> { param_env, &fn_sig); + let fn_sig = fixup_opaque_types(tcx, &fn_sig); + let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, None).0; fcx } else { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 8dced83b987ea..7732ac4a1c85e 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -2059,6 +2059,9 @@ fn explicit_predicates_of( ty::print::with_no_queries(|| { let substs = InternalSubsts::identity_for_item(tcx, def_id); let opaque_ty = tcx.mk_opaque(def_id, substs); + debug!("explicit_predicates_of({:?}): created opaque type {:?}", + def_id, opaque_ty); + // Collect the bounds, i.e., the `A + B + 'c` in `impl A + B + 'c`. let bounds = AstConv::compute_bounds( diff --git a/src/test/ui/impl-trait/type-alias-generic-param.rs b/src/test/ui/impl-trait/type-alias-generic-param.rs new file mode 100644 index 0000000000000..d834d9bb112f5 --- /dev/null +++ b/src/test/ui/impl-trait/type-alias-generic-param.rs @@ -0,0 +1,22 @@ +// Regression test for issue #59342 +// Checks that we properly detect defining uses of opaque +// types in 'item' position when generic parameters are involved +// +// run-pass +#![feature(type_alias_impl_trait)] + +trait Meow { + type MeowType; + fn meow(self) -> Self::MeowType; +} + +impl Meow for I + where I: Iterator +{ + type MeowType = impl Iterator; + fn meow(self) -> Self::MeowType { + self + } +} + +fn main() {} From 6b47cbaee6ae009937bf796da9fb5ae662d5c9f1 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 7 Nov 2019 22:40:19 -0500 Subject: [PATCH 2/7] Improve error message when opaque type is not fully constrained --- src/librustc_typeck/collect.rs | 17 +++++++---- .../bound_reduction2.stderr | 2 +- .../generic_nondefining_use.stderr | 2 +- .../ui/type-alias-impl-trait/issue-58887.rs | 5 ++-- .../type-alias-impl-trait/issue-58887.stderr | 30 ------------------- .../ui/type-alias-impl-trait/issue-60564.rs | 2 +- .../type-alias-impl-trait/issue-60564.stderr | 7 ++--- .../not_a_defining_use.stderr | 2 +- 8 files changed, 21 insertions(+), 46 deletions(-) delete mode 100644 src/test/ui/type-alias-impl-trait/issue-58887.stderr diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 7732ac4a1c85e..652f081e1761c 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1617,11 +1617,18 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { ty::Param(_) => true, _ => false, }; - if !substs.types().all(is_param) { - self.tcx.sess.span_err( - span, - "defining opaque type use does not fully define opaque type", - ); + let bad_substs: Vec<_> = substs.types().enumerate() + .filter(|(_, ty)| !is_param(ty)).collect(); + if !bad_substs.is_empty() { + let identity_substs = InternalSubsts::identity_for_item(self.tcx, self.def_id); + for (i, bad_subst) in bad_substs { + self.tcx.sess.span_err( + span, + &format!("defining opaque type use does not fully define opaque type: \ + generic parameter `{}` is specified as concrete type `{}`", + identity_substs.type_at(i), bad_subst) + ); + } } else if let Some((prev_span, prev_ty, ref prev_indices)) = self.found { let mut ty = concrete_type.walk().fuse(); let mut p_ty = prev_ty.walk().fuse(); diff --git a/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr b/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr index 886d17aca36ed..bb22d582f2167 100644 --- a/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr +++ b/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr @@ -1,4 +1,4 @@ -error: defining opaque type use does not fully define opaque type +error: defining opaque type use does not fully define opaque type: generic parameter `V` is specified as concrete type `::Assoc` --> $DIR/bound_reduction2.rs:17:1 | LL | / fn foo_desugared(_: T) -> Foo { diff --git a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr index c31d3912d9731..b952aaa79ccee 100644 --- a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr @@ -4,7 +4,7 @@ error: at least one trait must be specified LL | type Cmp = impl 'static; | ^^^^^^^^^^^^ -error: defining opaque type use does not fully define opaque type +error: defining opaque type use does not fully define opaque type: generic parameter `T` is specified as concrete type `u32` --> $DIR/generic_nondefining_use.rs:11:1 | LL | / fn cmp() -> Cmp { diff --git a/src/test/ui/type-alias-impl-trait/issue-58887.rs b/src/test/ui/type-alias-impl-trait/issue-58887.rs index 92ba50ae6cf1f..96ac7860283ac 100644 --- a/src/test/ui/type-alias-impl-trait/issue-58887.rs +++ b/src/test/ui/type-alias-impl-trait/issue-58887.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(type_alias_impl_trait)] trait UnwrapItemsExt { @@ -11,11 +13,8 @@ where E: std::fmt::Debug, { type Iter = impl Iterator; - //~^ ERROR: could not find defining uses fn unwrap_items(self) -> Self::Iter { - //~^ ERROR: type parameter `T` is part of concrete type - //~| ERROR: type parameter `E` is part of concrete type self.map(|x| x.unwrap()) } } diff --git a/src/test/ui/type-alias-impl-trait/issue-58887.stderr b/src/test/ui/type-alias-impl-trait/issue-58887.stderr deleted file mode 100644 index 7e2895711d345..0000000000000 --- a/src/test/ui/type-alias-impl-trait/issue-58887.stderr +++ /dev/null @@ -1,30 +0,0 @@ -error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-58887.rs:16:41 - | -LL | fn unwrap_items(self) -> Self::Iter { - | _________________________________________^ -LL | | -LL | | -LL | | self.map(|x| x.unwrap()) -LL | | } - | |_____^ - -error: type parameter `E` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-58887.rs:16:41 - | -LL | fn unwrap_items(self) -> Self::Iter { - | _________________________________________^ -LL | | -LL | | -LL | | self.map(|x| x.unwrap()) -LL | | } - | |_____^ - -error: could not find defining uses - --> $DIR/issue-58887.rs:13:5 - | -LL | type Iter = impl Iterator; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors - diff --git a/src/test/ui/type-alias-impl-trait/issue-60564.rs b/src/test/ui/type-alias-impl-trait/issue-60564.rs index 9e96b1cf7b05f..8fea29ac14b9a 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60564.rs +++ b/src/test/ui/type-alias-impl-trait/issue-60564.rs @@ -18,7 +18,7 @@ where { type BitsIter = IterBitsIter; fn iter_bits(self, n: u8) -> Self::BitsIter { - //~^ ERROR type parameter `E` is part of concrete type but not used + //~^ ERROR defining opaque type use does not fully define opaque typ (0u8..n) .rev() .map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap()) diff --git a/src/test/ui/type-alias-impl-trait/issue-60564.stderr b/src/test/ui/type-alias-impl-trait/issue-60564.stderr index b838c06cadee3..9de3e759e1521 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60564.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-60564.stderr @@ -1,8 +1,7 @@ -error: type parameter `E` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-60564.rs:20:49 +error: defining opaque type use does not fully define opaque type: generic parameter `I` is specified as concrete type `u8` + --> $DIR/issue-60564.rs:20:5 | -LL | fn iter_bits(self, n: u8) -> Self::BitsIter { - | _________________________________________________^ +LL | / fn iter_bits(self, n: u8) -> Self::BitsIter { LL | | LL | | (0u8..n) LL | | .rev() diff --git a/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr b/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr index 7bb8939ccf5a2..d68f1bd30a0da 100644 --- a/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr +++ b/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr @@ -1,4 +1,4 @@ -error: defining opaque type use does not fully define opaque type +error: defining opaque type use does not fully define opaque type: generic parameter `U` is specified as concrete type `u32` --> $DIR/not_a_defining_use.rs:9:1 | LL | / fn two(t: T) -> Two { From a59b7eabe691695c66a9d3b95735121af1ba0166 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 11 Nov 2019 13:31:46 -0500 Subject: [PATCH 3/7] Also fix lifetimes and consts in opaque types --- src/librustc_typeck/check/mod.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index c0b49bb591838..a6dc4fc851fe4 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -893,7 +893,7 @@ fn fixup_opaque_types<'tcx, T>(tcx: TyCtxt<'tcx>, val: &T) -> T where T: TypeFol match ty.kind { ty::Opaque(def_id, substs) => { debug!("fixup_opaque_types: found type {:?}", ty); - if ty.has_infer_types() { + if ty.needs_infer() { let new_substs = InternalSubsts::for_item(self.tcx, def_id, |param, _| { let old_param = substs[param.index as usize]; match old_param.unpack() { @@ -905,7 +905,20 @@ fn fixup_opaque_types<'tcx, T>(tcx: TyCtxt<'tcx>, val: &T) -> T where T: TypeFol old_param.fold_with(self) } }, - _ => old_param + GenericArgKind::Const(old_const) => { + if let ConstValue::Infer(_) = old_const.val { + self.tcx.mk_param_from_def(param) + } else { + old_param.fold_with(self) + } + } + GenericArgKind::Lifetime(old_region) => { + if let RegionKind::ReVar(_) = old_region { + self.tcx.mk_param_from_def(param) + } else { + old_param.fold_with(self) + } + } } }); let new_ty = self.tcx.mk_opaque(def_id, new_substs); From 850e3e6d4db1544b538fcd3d0287cffed06d2b79 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 11 Nov 2019 15:01:53 -0500 Subject: [PATCH 4/7] bug!() on const inference variable in opaque type Add some tests to verify that this case is never hit --- src/librustc_typeck/check/mod.rs | 10 +++++- .../type-alias-impl-trait/assoc-type-const.rs | 36 +++++++++++++++++++ .../assoc-type-const.stderr | 8 +++++ .../assoc-type-lifetime.rs | 28 +++++++++++++++ 4 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/type-alias-impl-trait/assoc-type-const.rs create mode 100644 src/test/ui/type-alias-impl-trait/assoc-type-const.stderr create mode 100644 src/test/ui/type-alias-impl-trait/assoc-type-lifetime.rs diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index a6dc4fc851fe4..a1f1ac3f2d38a 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -907,7 +907,15 @@ fn fixup_opaque_types<'tcx, T>(tcx: TyCtxt<'tcx>, val: &T) -> T where T: TypeFol }, GenericArgKind::Const(old_const) => { if let ConstValue::Infer(_) = old_const.val { - self.tcx.mk_param_from_def(param) + // This should never happen - we currently do not support + // 'const projections', e.g.: + // `impl MyTrait for T where ::MyConst == 25` + // which should be the only way for us to end up with a const inference + // variable after projection. If Rust ever gains support for this kind + // of projection, this should *probably* be changed to + // `self.tcx.mk_param_from_def(param)` + bug!("Found infer const: `{:?}` in opaque type: {:?}", + old_const, ty); } else { old_param.fold_with(self) } diff --git a/src/test/ui/type-alias-impl-trait/assoc-type-const.rs b/src/test/ui/type-alias-impl-trait/assoc-type-const.rs new file mode 100644 index 0000000000000..5db677d82e266 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/assoc-type-const.rs @@ -0,0 +1,36 @@ +// Tests that we properly detect defining usages when using +// const generics in an associated opaque type +// check-pass + +#![feature(type_alias_impl_trait)] +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +trait UnwrapItemsExt { + type Iter; + fn unwrap_items(self) -> Self::Iter; +} + +struct MyStruct {} + +trait MyTrait<'a, const C: usize> { + type MyItem; + const MY_CONST: usize; +} + +impl<'a, const C: usize> MyTrait<'a, {C}> for MyStruct<{C}> { + type MyItem = u8; + const MY_CONST: usize = C; +} + +impl<'a, I, const C: usize> UnwrapItemsExt<{C}> for I +where +{ + type Iter = impl MyTrait<'a, {C}>; + + fn unwrap_items(self) -> Self::Iter { + MyStruct::<{C}> {} + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/assoc-type-const.stderr b/src/test/ui/type-alias-impl-trait/assoc-type-const.stderr new file mode 100644 index 0000000000000..0adbee2f24439 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/assoc-type-const.stderr @@ -0,0 +1,8 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/assoc-type-const.rs:6:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + diff --git a/src/test/ui/type-alias-impl-trait/assoc-type-lifetime.rs b/src/test/ui/type-alias-impl-trait/assoc-type-lifetime.rs new file mode 100644 index 0000000000000..cff1d24494e83 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/assoc-type-lifetime.rs @@ -0,0 +1,28 @@ +// Tests that we still detect defining usages when +// lifetimes are used in an associated opaque type +// check-pass + +#![feature(type_alias_impl_trait)] + +trait UnwrapItemsExt { + type Iter; + fn unwrap_items(self) -> Self::Iter; +} + +struct MyStruct {} + +trait MyTrait<'a> {} + +impl<'a> MyTrait<'a> for MyStruct {} + +impl<'a, I> UnwrapItemsExt for I +where +{ + type Iter = impl MyTrait<'a>; + + fn unwrap_items(self) -> Self::Iter { + MyStruct {} + } +} + +fn main() {} From 542383f65b5419820e90f4374f93d2d1207f3f08 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 18 Nov 2019 14:37:56 -0500 Subject: [PATCH 5/7] Fix missing character Co-Authored-By: varkor --- src/test/ui/type-alias-impl-trait/issue-60564.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/type-alias-impl-trait/issue-60564.rs b/src/test/ui/type-alias-impl-trait/issue-60564.rs index 8fea29ac14b9a..8686100205ffb 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60564.rs +++ b/src/test/ui/type-alias-impl-trait/issue-60564.rs @@ -18,7 +18,7 @@ where { type BitsIter = IterBitsIter; fn iter_bits(self, n: u8) -> Self::BitsIter { - //~^ ERROR defining opaque type use does not fully define opaque typ + //~^ ERROR defining opaque type use does not fully define opaque type (0u8..n) .rev() .map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap()) From cec7d944baa4a1d5ae0c09d68537ce20fe6b47f4 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 18 Nov 2019 14:46:16 -0500 Subject: [PATCH 6/7] Add example and extra documentation --- src/librustc_typeck/check/mod.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index a1f1ac3f2d38a..9182eb10545ca 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -879,6 +879,30 @@ fn used_trait_imports(tcx: TyCtxt<'_>, def_id: DefId) -> &DefIdSet { /// variables introduced by the projection of associated types. This ensures that /// any opaque types used in the signature continue to refer to generic parameters, /// allowing them to be considered for defining uses in the function body +/// +/// For example, consider this code. +/// +/// ```rust +/// trait MyTrait { +/// type MyItem; +/// fn use_it(self) -> Self::MyItem +/// } +/// impl MyTrait for T where T: Iterator { +/// type MyItem = impl Iterator; +/// fn use_it(self) -> Self::MyItem { +/// self +/// } +/// } +/// ``` +/// +/// When we normalize the signature of `use_it` from the impl block, +/// we will normalize `Self::MyItem` to the opaque type `impl Iterator` +/// However, this projection result may contain inference variables, due +/// to the way that projection works. We didn't have any inference variables +/// in the signature to begin with - leaving them in will cause us to incorrectly +/// conclude that we don't have a defining use of `MyItem`. By mapping inference +/// variables back to the actual generic parameters, we will correctly see that +/// we have a defining use of `MyItem` fn fixup_opaque_types<'tcx, T>(tcx: TyCtxt<'tcx>, val: &T) -> T where T: TypeFoldable<'tcx> { struct FixupFolder<'tcx> { tcx: TyCtxt<'tcx> @@ -893,6 +917,14 @@ fn fixup_opaque_types<'tcx, T>(tcx: TyCtxt<'tcx>, val: &T) -> T where T: TypeFol match ty.kind { ty::Opaque(def_id, substs) => { debug!("fixup_opaque_types: found type {:?}", ty); + // Here, we replace any inference variables that occur within + // the substs of an opaque type. By definition, any type occuring + // in the substs has a corresponding generic parameter, which is what + // we replace it with. + // This replacement is only run on the function signature, so any + // inference variables that we come across must be the rust of projection + // (there's no other way for a user to get inference variables into + // a function signature). if ty.needs_infer() { let new_substs = InternalSubsts::for_item(self.tcx, def_id, |param, _| { let old_param = substs[param.index as usize]; From df3f33870ad48b29a82cce524c1fa092280e76c8 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 18 Nov 2019 14:58:29 -0500 Subject: [PATCH 7/7] Update for ConstKind refactor --- src/librustc_typeck/check/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 9182eb10545ca..688523dc05b0b 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -938,7 +938,7 @@ fn fixup_opaque_types<'tcx, T>(tcx: TyCtxt<'tcx>, val: &T) -> T where T: TypeFol } }, GenericArgKind::Const(old_const) => { - if let ConstValue::Infer(_) = old_const.val { + if let ty::ConstKind::Infer(_) = old_const.val { // This should never happen - we currently do not support // 'const projections', e.g.: // `impl MyTrait for T where ::MyConst == 25`