Replace associated item bound vars with placeholders when projecting.
This commit is contained in:
parent
aa65b08b1d
commit
c63f1fe92b
18 changed files with 609 additions and 31 deletions
|
@ -204,6 +204,69 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
}
|
||||
ty::Projection(data) if !data.trait_ref(self.infcx.tcx).has_escaping_bound_vars() => {
|
||||
// See note in `rustc_trait_selection::traits::project`
|
||||
|
||||
// One other point mentioning: In `traits::project`, if a
|
||||
// projection can't be normalized, we return an inference variable
|
||||
// and register an obligation to later resolve that. Here, the query
|
||||
// will just return ambiguity. In both cases, the effect is the same: we only want
|
||||
// to return `ty` because there are bound vars that we aren't yet handling in a more
|
||||
// complete way.
|
||||
|
||||
let tcx = self.infcx.tcx;
|
||||
let infcx = self.infcx;
|
||||
let (data, mapped_regions, mapped_types, mapped_consts, universe_map) =
|
||||
crate::traits::project::BoundVarReplacer::replace_bound_vars(infcx, data);
|
||||
let data = data.super_fold_with(self);
|
||||
|
||||
let mut orig_values = OriginalQueryValues::default();
|
||||
// HACK(matthewjasper) `'static` is special-cased in selection,
|
||||
// so we cannot canonicalize it.
|
||||
let c_data = self
|
||||
.infcx
|
||||
.canonicalize_hr_query_hack(self.param_env.and(data), &mut orig_values);
|
||||
debug!("QueryNormalizer: c_data = {:#?}", c_data);
|
||||
debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
|
||||
let normalized_ty = match tcx.normalize_projection_ty(c_data) {
|
||||
Ok(result) => {
|
||||
// We don't expect ambiguity.
|
||||
if result.is_ambiguous() {
|
||||
self.error = true;
|
||||
return ty;
|
||||
}
|
||||
match self.infcx.instantiate_query_response_and_region_obligations(
|
||||
self.cause,
|
||||
self.param_env,
|
||||
&orig_values,
|
||||
result,
|
||||
) {
|
||||
Ok(InferOk { value: result, obligations }) => {
|
||||
debug!("QueryNormalizer: result = {:#?}", result);
|
||||
debug!("QueryNormalizer: obligations = {:#?}", obligations);
|
||||
self.obligations.extend(obligations);
|
||||
result.normalized_ty
|
||||
}
|
||||
Err(_) => {
|
||||
self.error = true;
|
||||
ty
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(NoSolution) => {
|
||||
self.error = true;
|
||||
ty
|
||||
}
|
||||
};
|
||||
crate::traits::project::PlaceholderReplacer::replace_placeholders(
|
||||
infcx,
|
||||
mapped_regions,
|
||||
mapped_types,
|
||||
mapped_consts,
|
||||
universe_map,
|
||||
normalized_ty,
|
||||
)
|
||||
}
|
||||
|
||||
_ => ty,
|
||||
})();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue