diff options
| author | matthewjasper <mjjasper1@gmail.com> | 2020-06-16 18:27:40 +0100 |
|---|---|---|
| committer | Matthew Jasper <mjjasper1@gmail.com> | 2020-06-17 19:46:15 +0100 |
| commit | ba2ef58ae6c126ec0b87b307d45fef2da127be22 (patch) | |
| tree | 1af52c4955daf2ea82f05795619c56fe60c7ef3c /src/librustc_trait_selection | |
| parent | 435f97cec1f0d7de95a0b80e95f295ab444b2fce (diff) | |
Unify region variables when projecting associated types
This is required to avoid cycles when evaluating auto trait predicates.
Diffstat (limited to 'src/librustc_trait_selection')
| -rw-r--r-- | src/librustc_trait_selection/traits/project.rs | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/src/librustc_trait_selection/traits/project.rs b/src/librustc_trait_selection/traits/project.rs index 9492c3c3409..bccd903f57e 100644 --- a/src/librustc_trait_selection/traits/project.rs +++ b/src/librustc_trait_selection/traits/project.rs @@ -24,6 +24,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::ErrorReported; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::{FnOnceTraitLangItem, GeneratorTraitLangItem}; +use rustc_infer::infer::resolve::OpportunisticRegionResolver; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder}; use rustc_middle::ty::subst::Subst; use rustc_middle::ty::util::IntTypeExt; @@ -1146,7 +1147,7 @@ fn confirm_candidate<'cx, 'tcx>( ) -> Progress<'tcx> { debug!("confirm_candidate(candidate={:?}, obligation={:?})", candidate, obligation); - match candidate { + let mut progress = match candidate { ProjectionTyCandidate::ParamEnv(poly_projection) | ProjectionTyCandidate::TraitDef(poly_projection) => { confirm_param_env_candidate(selcx, obligation, poly_projection) @@ -1155,7 +1156,16 @@ fn confirm_candidate<'cx, 'tcx>( ProjectionTyCandidate::Select(impl_source) => { confirm_select_candidate(selcx, obligation, obligation_trait_ref, impl_source) } + }; + // When checking for cycle during evaluation, we compare predicates with + // "syntactic" equality. Since normalization generally introduces a type + // with new region variables, we need to resolve them to existing variables + // when possible for this to work. See `auto-trait-projection-recursion.rs` + // for a case where this matters. + if progress.ty.has_infer_regions() { + progress.ty = OpportunisticRegionResolver::new(selcx.infcx()).fold_ty(progress.ty); } + progress } fn confirm_select_candidate<'cx, 'tcx>( |
