mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Auto merge of #118968 - aliemjay:canon-static, r=lcnr
unify query canonicalization mode Exclude from canonicalization only the static lifetimes that appear in the param env because of #118965 . Any other occurrence can be canonicalized safely AFAICT. r? `@lcnr`
This commit is contained in:
commit
be00c5a9b8
@ -41,7 +41,33 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||||||
where
|
where
|
||||||
V: TypeFoldable<TyCtxt<'tcx>>,
|
V: TypeFoldable<TyCtxt<'tcx>>,
|
||||||
{
|
{
|
||||||
self.canonicalize_query_with_mode(value, query_state, &CanonicalizeAllFreeRegions)
|
let (param_env, value) = value.into_parts();
|
||||||
|
let param_env = self.tcx.canonical_param_env_cache.get_or_insert(
|
||||||
|
self.tcx,
|
||||||
|
param_env,
|
||||||
|
query_state,
|
||||||
|
|tcx, param_env, query_state| {
|
||||||
|
// FIXME(#118965): We don't canonicalize the static lifetimes that appear in the
|
||||||
|
// `param_env` beacause they are treated differently by trait selection.
|
||||||
|
Canonicalizer::canonicalize(
|
||||||
|
param_env,
|
||||||
|
None,
|
||||||
|
tcx,
|
||||||
|
&CanonicalizeFreeRegionsOtherThanStatic,
|
||||||
|
query_state,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
Canonicalizer::canonicalize_with_base(
|
||||||
|
param_env,
|
||||||
|
value,
|
||||||
|
Some(self),
|
||||||
|
self.tcx,
|
||||||
|
&CanonicalizeAllFreeRegions,
|
||||||
|
query_state,
|
||||||
|
)
|
||||||
|
.unchecked_map(|(param_env, value)| param_env.and(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Canonicalizes a query *response* `V`. When we canonicalize a
|
/// Canonicalizes a query *response* `V`. When we canonicalize a
|
||||||
@ -96,61 +122,6 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||||||
&mut query_state,
|
&mut query_state,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A variant of `canonicalize_query` that does not
|
|
||||||
/// canonicalize `'static`. This is useful when
|
|
||||||
/// the query implementation can perform more efficient
|
|
||||||
/// handling of `'static` regions (e.g. trait evaluation).
|
|
||||||
pub fn canonicalize_query_keep_static<V>(
|
|
||||||
&self,
|
|
||||||
value: ty::ParamEnvAnd<'tcx, V>,
|
|
||||||
query_state: &mut OriginalQueryValues<'tcx>,
|
|
||||||
) -> Canonical<'tcx, ty::ParamEnvAnd<'tcx, V>>
|
|
||||||
where
|
|
||||||
V: TypeFoldable<TyCtxt<'tcx>>,
|
|
||||||
{
|
|
||||||
self.canonicalize_query_with_mode(
|
|
||||||
value,
|
|
||||||
query_state,
|
|
||||||
&CanonicalizeFreeRegionsOtherThanStatic,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn canonicalize_query_with_mode<V>(
|
|
||||||
&self,
|
|
||||||
value: ty::ParamEnvAnd<'tcx, V>,
|
|
||||||
query_state: &mut OriginalQueryValues<'tcx>,
|
|
||||||
canonicalize_region_mode: &dyn CanonicalizeMode,
|
|
||||||
) -> Canonical<'tcx, ty::ParamEnvAnd<'tcx, V>>
|
|
||||||
where
|
|
||||||
V: TypeFoldable<TyCtxt<'tcx>>,
|
|
||||||
{
|
|
||||||
let (param_env, value) = value.into_parts();
|
|
||||||
let base = self.tcx.canonical_param_env_cache.get_or_insert(
|
|
||||||
self.tcx,
|
|
||||||
param_env,
|
|
||||||
query_state,
|
|
||||||
|tcx, param_env, query_state| {
|
|
||||||
Canonicalizer::canonicalize(
|
|
||||||
param_env,
|
|
||||||
None,
|
|
||||||
tcx,
|
|
||||||
&CanonicalizeFreeRegionsOtherThanStatic,
|
|
||||||
query_state,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
Canonicalizer::canonicalize_with_base(
|
|
||||||
base,
|
|
||||||
value,
|
|
||||||
Some(self),
|
|
||||||
self.tcx,
|
|
||||||
canonicalize_region_mode,
|
|
||||||
query_state,
|
|
||||||
)
|
|
||||||
.unchecked_map(|(param_env, value)| param_env.and(value))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Controls how we canonicalize "free regions" that are not inference
|
/// Controls how we canonicalize "free regions" that are not inference
|
||||||
|
@ -65,8 +65,7 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> {
|
|||||||
assert!(!ty.has_non_region_infer());
|
assert!(!ty.has_non_region_infer());
|
||||||
|
|
||||||
let mut canonical_var_values = OriginalQueryValues::default();
|
let mut canonical_var_values = OriginalQueryValues::default();
|
||||||
let canonical_ty =
|
let canonical_ty = self.canonicalize_query(param_env.and(ty), &mut canonical_var_values);
|
||||||
self.canonicalize_query_keep_static(param_env.and(ty), &mut canonical_var_values);
|
|
||||||
let Ok(canonical_result) = self.tcx.implied_outlives_bounds(canonical_ty) else {
|
let Ok(canonical_result) = self.tcx.implied_outlives_bounds(canonical_ty) else {
|
||||||
return vec![];
|
return vec![];
|
||||||
};
|
};
|
||||||
|
@ -87,10 +87,8 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
|||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
assert!(!self.intercrate);
|
assert!(!self.intercrate);
|
||||||
let c_pred = self.canonicalize_query_keep_static(
|
let c_pred =
|
||||||
param_env.and(obligation.predicate),
|
self.canonicalize_query(param_env.and(obligation.predicate), &mut _orig_values);
|
||||||
&mut _orig_values,
|
|
||||||
);
|
|
||||||
self.tcx.at(obligation.cause.span()).evaluate_obligation(c_pred)
|
self.tcx.at(obligation.cause.span()).evaluate_obligation(c_pred)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -272,10 +272,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx>
|
|||||||
let data = data.try_fold_with(self)?;
|
let data = data.try_fold_with(self)?;
|
||||||
|
|
||||||
let mut orig_values = OriginalQueryValues::default();
|
let mut orig_values = OriginalQueryValues::default();
|
||||||
// HACK(matthewjasper) `'static` is special-cased in selection,
|
let c_data = infcx.canonicalize_query(self.param_env.and(data), &mut orig_values);
|
||||||
// so we cannot canonicalize it.
|
|
||||||
let c_data = infcx
|
|
||||||
.canonicalize_query_keep_static(self.param_env.and(data), &mut orig_values);
|
|
||||||
debug!("QueryNormalizer: c_data = {:#?}", c_data);
|
debug!("QueryNormalizer: c_data = {:#?}", c_data);
|
||||||
debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
|
debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
|
||||||
let result = match kind {
|
let result = match kind {
|
||||||
|
@ -111,14 +111,9 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable<TyCtxt<'tcx>> + 't
|
|||||||
return Ok((result, None, vec![], Certainty::Proven));
|
return Ok((result, None, vec![], Certainty::Proven));
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(#33684) -- We need to use
|
|
||||||
// `canonicalize_query_keep_static` here because of things
|
|
||||||
// like the subtype query, which go awry around
|
|
||||||
// `'static` otherwise.
|
|
||||||
let mut canonical_var_values = OriginalQueryValues::default();
|
let mut canonical_var_values = OriginalQueryValues::default();
|
||||||
let old_param_env = query_key.param_env;
|
let old_param_env = query_key.param_env;
|
||||||
let canonical_self =
|
let canonical_self = infcx.canonicalize_query(query_key, &mut canonical_var_values);
|
||||||
infcx.canonicalize_query_keep_static(query_key, &mut canonical_var_values);
|
|
||||||
let canonical_result = Self::perform_query(infcx.tcx, canonical_self)?;
|
let canonical_result = Self::perform_query(infcx.tcx, canonical_self)?;
|
||||||
|
|
||||||
let InferOk { value, obligations } = infcx
|
let InferOk { value, obligations } = infcx
|
||||||
|
@ -4,7 +4,7 @@ error: implementation of `Deserialize` is not general enough
|
|||||||
LL | assert_deserialize_owned::<&'static str>();
|
LL | assert_deserialize_owned::<&'static str>();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Deserialize` is not general enough
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Deserialize` is not general enough
|
||||||
|
|
|
|
||||||
= note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0`...
|
= note: `&str` must implement `Deserialize<'0>`, for any lifetime `'0`...
|
||||||
= note: ...but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1`
|
= note: ...but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1`
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
@ -12,7 +12,7 @@ error: higher-ranked lifetime error
|
|||||||
LL | v.t(|| {});
|
LL | v.t(|| {});
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
|
|
||||||
= note: could not prove `for<'a> &'a V: 'static`
|
= note: could not prove `for<'a> &'a V: 'b`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ error: implementation of `Deserialize` is not general enough
|
|||||||
LL | assert_deserialize_owned::<&'static str>();
|
LL | assert_deserialize_owned::<&'static str>();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Deserialize` is not general enough
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Deserialize` is not general enough
|
||||||
|
|
|
|
||||||
= note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0`...
|
= note: `&str` must implement `Deserialize<'0>`, for any lifetime `'0`...
|
||||||
= note: ...but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1`
|
= note: ...but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1`
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
Loading…
Reference in New Issue
Block a user