Skip to content

Commit be00c5a

Browse files
committed
Auto merge of rust-lang#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 rust-lang#118965 . Any other occurrence can be canonicalized safely AFAICT. r? `@lcnr`
2 parents dc64103 + 707c4f9 commit be00c5a

File tree

8 files changed

+35
-75
lines changed

8 files changed

+35
-75
lines changed

compiler/rustc_infer/src/infer/canonical/canonicalizer.rs

+27-56
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,33 @@ impl<'tcx> InferCtxt<'tcx> {
4141
where
4242
V: TypeFoldable<TyCtxt<'tcx>>,
4343
{
44-
self.canonicalize_query_with_mode(value, query_state, &CanonicalizeAllFreeRegions)
44+
let (param_env, value) = value.into_parts();
45+
let param_env = self.tcx.canonical_param_env_cache.get_or_insert(
46+
self.tcx,
47+
param_env,
48+
query_state,
49+
|tcx, param_env, query_state| {
50+
// FIXME(#118965): We don't canonicalize the static lifetimes that appear in the
51+
// `param_env` beacause they are treated differently by trait selection.
52+
Canonicalizer::canonicalize(
53+
param_env,
54+
None,
55+
tcx,
56+
&CanonicalizeFreeRegionsOtherThanStatic,
57+
query_state,
58+
)
59+
},
60+
);
61+
62+
Canonicalizer::canonicalize_with_base(
63+
param_env,
64+
value,
65+
Some(self),
66+
self.tcx,
67+
&CanonicalizeAllFreeRegions,
68+
query_state,
69+
)
70+
.unchecked_map(|(param_env, value)| param_env.and(value))
4571
}
4672

4773
/// Canonicalizes a query *response* `V`. When we canonicalize a
@@ -96,61 +122,6 @@ impl<'tcx> InferCtxt<'tcx> {
96122
&mut query_state,
97123
)
98124
}
99-
100-
/// A variant of `canonicalize_query` that does not
101-
/// canonicalize `'static`. This is useful when
102-
/// the query implementation can perform more efficient
103-
/// handling of `'static` regions (e.g. trait evaluation).
104-
pub fn canonicalize_query_keep_static<V>(
105-
&self,
106-
value: ty::ParamEnvAnd<'tcx, V>,
107-
query_state: &mut OriginalQueryValues<'tcx>,
108-
) -> Canonical<'tcx, ty::ParamEnvAnd<'tcx, V>>
109-
where
110-
V: TypeFoldable<TyCtxt<'tcx>>,
111-
{
112-
self.canonicalize_query_with_mode(
113-
value,
114-
query_state,
115-
&CanonicalizeFreeRegionsOtherThanStatic,
116-
)
117-
}
118-
119-
fn canonicalize_query_with_mode<V>(
120-
&self,
121-
value: ty::ParamEnvAnd<'tcx, V>,
122-
query_state: &mut OriginalQueryValues<'tcx>,
123-
canonicalize_region_mode: &dyn CanonicalizeMode,
124-
) -> Canonical<'tcx, ty::ParamEnvAnd<'tcx, V>>
125-
where
126-
V: TypeFoldable<TyCtxt<'tcx>>,
127-
{
128-
let (param_env, value) = value.into_parts();
129-
let base = self.tcx.canonical_param_env_cache.get_or_insert(
130-
self.tcx,
131-
param_env,
132-
query_state,
133-
|tcx, param_env, query_state| {
134-
Canonicalizer::canonicalize(
135-
param_env,
136-
None,
137-
tcx,
138-
&CanonicalizeFreeRegionsOtherThanStatic,
139-
query_state,
140-
)
141-
},
142-
);
143-
144-
Canonicalizer::canonicalize_with_base(
145-
base,
146-
value,
147-
Some(self),
148-
self.tcx,
149-
canonicalize_region_mode,
150-
query_state,
151-
)
152-
.unchecked_map(|(param_env, value)| param_env.and(value))
153-
}
154125
}
155126

156127
/// Controls how we canonicalize "free regions" that are not inference

compiler/rustc_trait_selection/src/traits/outlives_bounds.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,7 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> {
6565
assert!(!ty.has_non_region_infer());
6666

6767
let mut canonical_var_values = OriginalQueryValues::default();
68-
let canonical_ty =
69-
self.canonicalize_query_keep_static(param_env.and(ty), &mut canonical_var_values);
68+
let canonical_ty = self.canonicalize_query(param_env.and(ty), &mut canonical_var_values);
7069
let Ok(canonical_result) = self.tcx.implied_outlives_bounds(canonical_ty) else {
7170
return vec![];
7271
};

compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,8 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
8787
})
8888
} else {
8989
assert!(!self.intercrate);
90-
let c_pred = self.canonicalize_query_keep_static(
91-
param_env.and(obligation.predicate),
92-
&mut _orig_values,
93-
);
90+
let c_pred =
91+
self.canonicalize_query(param_env.and(obligation.predicate), &mut _orig_values);
9492
self.tcx.at(obligation.cause.span()).evaluate_obligation(c_pred)
9593
}
9694
}

compiler/rustc_trait_selection/src/traits/query/normalize.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -272,10 +272,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx>
272272
let data = data.try_fold_with(self)?;
273273

274274
let mut orig_values = OriginalQueryValues::default();
275-
// HACK(matthewjasper) `'static` is special-cased in selection,
276-
// so we cannot canonicalize it.
277-
let c_data = infcx
278-
.canonicalize_query_keep_static(self.param_env.and(data), &mut orig_values);
275+
let c_data = infcx.canonicalize_query(self.param_env.and(data), &mut orig_values);
279276
debug!("QueryNormalizer: c_data = {:#?}", c_data);
280277
debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
281278
let result = match kind {

compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -111,14 +111,9 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable<TyCtxt<'tcx>> + 't
111111
return Ok((result, None, vec![], Certainty::Proven));
112112
}
113113

114-
// FIXME(#33684) -- We need to use
115-
// `canonicalize_query_keep_static` here because of things
116-
// like the subtype query, which go awry around
117-
// `'static` otherwise.
118114
let mut canonical_var_values = OriginalQueryValues::default();
119115
let old_param_env = query_key.param_env;
120-
let canonical_self =
121-
infcx.canonicalize_query_keep_static(query_key, &mut canonical_var_values);
116+
let canonical_self = infcx.canonicalize_query(query_key, &mut canonical_var_values);
122117
let canonical_result = Self::perform_query(infcx.tcx, canonical_self)?;
123118

124119
let InferOk { value, obligations } = infcx

tests/ui/higher-ranked/trait-bounds/hrtb-cache-issue-54302.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error: implementation of `Deserialize` is not general enough
44
LL | assert_deserialize_owned::<&'static str>();
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Deserialize` is not general enough
66
|
7-
= note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0`...
7+
= note: `&str` must implement `Deserialize<'0>`, for any lifetime `'0`...
88
= note: ...but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1`
99

1010
error: aborting due to 1 previous error

tests/ui/higher-ranked/trait-bounds/issue-59311.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ error: higher-ranked lifetime error
1212
LL | v.t(|| {});
1313
| ^^^^^
1414
|
15-
= note: could not prove `for<'a> &'a V: 'static`
15+
= note: could not prove `for<'a> &'a V: 'b`
1616

1717
error: aborting due to 2 previous errors
1818

tests/ui/nll/issue-54302.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error: implementation of `Deserialize` is not general enough
44
LL | assert_deserialize_owned::<&'static str>();
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Deserialize` is not general enough
66
|
7-
= note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0`...
7+
= note: `&str` must implement `Deserialize<'0>`, for any lifetime `'0`...
88
= note: ...but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1`
99

1010
error: aborting due to 1 previous error

0 commit comments

Comments
 (0)