diff options
| author | bors <bors@rust-lang.org> | 2022-08-11 10:47:48 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-08-11 10:47:48 +0000 |
| commit | aeb5067967ef58e4a324b19dd0dba2f385d5959f (patch) | |
| tree | 3169c9fba086a5386eee71fe238953d770da70cf /compiler/rustc_trait_selection/src | |
| parent | 187654481fd828e495919295369d33827f10e1c4 (diff) | |
| parent | d2667e4b718e3ded742a095e79eec92beb9bbbd6 (diff) | |
| download | rust-aeb5067967ef58e4a324b19dd0dba2f385d5959f.tar.gz rust-aeb5067967ef58e4a324b19dd0dba2f385d5959f.zip | |
Auto merge of #100315 - compiler-errors:norm-ct-in-proj, r=lcnr
Keep going if normalized projection has unevaluated consts in `QueryNormalizer` #100312 was the wrong approach, I think this is the right one. When normalizing a type, if we see that it's a projection, we currently defer to `tcx.normalize_projection_ty`, which normalizes the projections away but doesn't touch the unevaluated constants. So now we just continue to fold the type if it has unevaluated constants so we make sure to evaluate those too, if we can. Fixes #100217 Fixes #83972 Fixes #84669 Fixes #86710 Fixes #82268 Fixes #73298
Diffstat (limited to 'compiler/rustc_trait_selection/src')
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/query/normalize.rs | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 38b3a4b7253..61c556b726d 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -266,7 +266,15 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { debug!("QueryNormalizer: result = {:#?}", result); debug!("QueryNormalizer: obligations = {:#?}", obligations); self.obligations.extend(obligations); - Ok(result.normalized_ty) + + let res = result.normalized_ty; + // `tcx.normalize_projection_ty` may normalize to a type that still has + // unevaluated consts, so keep normalizing here if that's the case. + if res != ty && res.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) { + Ok(res.try_super_fold_with(self)?) + } else { + Ok(res) + } } ty::Projection(data) => { @@ -305,18 +313,27 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { debug!("QueryNormalizer: result = {:#?}", result); debug!("QueryNormalizer: obligations = {:#?}", obligations); self.obligations.extend(obligations); - Ok(crate::traits::project::PlaceholderReplacer::replace_placeholders( + + let res = crate::traits::project::PlaceholderReplacer::replace_placeholders( infcx, mapped_regions, mapped_types, mapped_consts, &self.universes, result.normalized_ty, - )) + ); + // `tcx.normalize_projection_ty` may normalize to a type that still has + // unevaluated consts, so keep normalizing here if that's the case. + if res != ty && res.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) { + Ok(res.try_super_fold_with(self)?) + } else { + Ok(res) + } } _ => ty.try_super_fold_with(self), })()?; + self.cache.insert(ty, res); Ok(res) } |
