Skip to content

Commit b243753

Browse files
committed
more wip on fixing ICEs
1 parent 17596bb commit b243753

File tree

6 files changed

+75
-50
lines changed

6 files changed

+75
-50
lines changed

compiler/rustc_middle/src/arena.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ macro_rules! arena_types {
4646
rustc_middle::traits::query::DropckOutlivesResult<'tcx>
4747
>
4848
>,
49-
[] normalize_canonicalized_projection_ty:
49+
[] normalize_canonicalized_projection:
5050
rustc_middle::infer::canonical::Canonical<'tcx,
5151
rustc_middle::infer::canonical::QueryResponse<'tcx,
5252
rustc_middle::traits::query::NormalizationResult<'tcx>

compiler/rustc_middle/src/query/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2305,7 +2305,7 @@ rustc_queries! {
23052305
/// Do not call this query directly: Invoke `normalize` instead.
23062306
///
23072307
/// </div>
2308-
query normalize_canonicalized_projection_ty(
2308+
query normalize_canonicalized_projection(
23092309
goal: CanonicalAliasGoal<'tcx>
23102310
) -> Result<
23112311
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, NormalizationResult<'tcx>>>,
@@ -2333,7 +2333,7 @@ rustc_queries! {
23332333
/// Do not call this query directly: Invoke `normalize` instead.
23342334
///
23352335
/// </div>
2336-
query normalize_canonicalized_inherent_projection_ty(
2336+
query normalize_canonicalized_inherent_projection(
23372337
goal: CanonicalAliasGoal<'tcx>
23382338
) -> Result<
23392339
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, NormalizationResult<'tcx>>>,

compiler/rustc_middle/src/traits/query.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ pub mod type_op {
6565
}
6666

6767
pub type CanonicalAliasGoal<'tcx> =
68-
CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, ty::AliasTy<'tcx>>>;
68+
CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, ty::AliasTerm<'tcx>>>;
6969

7070
pub type CanonicalTyGoal<'tcx> = CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, Ty<'tcx>>>;
7171

@@ -181,11 +181,11 @@ pub struct MethodAutoderefBadTy<'tcx> {
181181
pub ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
182182
}
183183

184-
/// Result of the `normalize_canonicalized_{{,inherent_}projection,free}_ty` queries.
184+
/// Result of the `normalize_canonicalized_{{,inherent_}projection,free}` queries.
185185
#[derive(Clone, Debug, HashStable, TypeFoldable, TypeVisitable)]
186186
pub struct NormalizationResult<'tcx> {
187187
/// Result of the normalization.
188-
pub normalized_ty: Ty<'tcx>,
188+
pub normalized_term: ty::Term<'tcx>,
189189
}
190190

191191
/// Outlives bounds are relationships between generic parameters,

compiler/rustc_trait_selection/src/traits/project.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,6 @@ fn normalize_to_error<'a, 'tcx>(
484484
}
485485

486486
/// Confirm and normalize the given inherent projection.
487-
// FIXME(mgca): While this supports constants, it is only used for types by default right now
488487
#[instrument(level = "debug", skip(selcx, param_env, cause, obligations))]
489488
pub fn normalize_inherent_projection<'a, 'b, 'tcx>(
490489
selcx: &'a mut SelectionContext<'b, 'tcx>,

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

Lines changed: 52 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
//! Code for the 'normalization' query. This consists of a wrapper
22
//! which folds deeply, invoking the underlying
3-
//! `normalize_canonicalized_projection_ty` query when it encounters projections.
3+
//! `normalize_canonicalized_projection` query when it encounters projections.
44
55
use rustc_data_structures::sso::SsoHashMap;
66
use rustc_data_structures::stack::ensure_sufficient_stack;
7+
use rustc_hir::def::DefKind;
78
use rustc_infer::traits::PredicateObligations;
89
use rustc_macros::extension;
910
pub use rustc_middle::traits::query::NormalizationResult;
@@ -253,7 +254,9 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
253254
}
254255
}
255256

256-
ty::Projection | ty::Inherent | ty::Free => self.try_fold_free_or_assoc(ty, kind, data)?,
257+
ty::Projection | ty::Inherent | ty::Free => self
258+
.try_fold_free_or_assoc(ty::AliasTerm::new(self.cx(), data.def_id, data.args))?
259+
.expect_type(),
257260
};
258261

259262
self.cache.insert(ty, res);
@@ -268,12 +271,22 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
268271
return Ok(constant);
269272
}
270273

271-
let constant = crate::traits::with_replaced_escaping_bound_vars(
272-
self.infcx,
273-
&mut self.universes,
274-
constant,
275-
|constant| crate::traits::evaluate_const(&self.infcx, constant, self.param_env),
276-
);
274+
let uv = match constant.kind() {
275+
ty::ConstKind::Unevaluated(uv) => uv,
276+
_ => return constant.try_super_fold_with(self),
277+
};
278+
279+
let constant = match self.cx().def_kind(uv.def) {
280+
DefKind::AnonConst => crate::traits::with_replaced_escaping_bound_vars(
281+
self.infcx,
282+
&mut self.universes,
283+
constant,
284+
|constant| crate::traits::evaluate_const(&self.infcx, constant, self.param_env),
285+
),
286+
_ => self
287+
.try_fold_free_or_assoc(ty::AliasTerm::new(self.cx(), uv.def, uv.args))?
288+
.expect_const(),
289+
};
277290
debug!(?constant, ?self.param_env);
278291
constant.try_super_fold_with(self)
279292
}
@@ -294,39 +307,45 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
294307
impl<'a, 'tcx> QueryNormalizer<'a, 'tcx> {
295308
fn try_fold_free_or_assoc(
296309
&mut self,
297-
ty: Ty<'tcx>,
298-
kind: ty::AliasTyKind,
299-
data: ty::AliasTy<'tcx>,
300-
) -> Result<Ty<'tcx>, NoSolution> {
310+
term: ty::AliasTerm<'tcx>,
311+
) -> Result<ty::Term<'tcx>, NoSolution> {
301312
let infcx = self.infcx;
302313
let tcx = infcx.tcx;
303314
// Just an optimization: When we don't have escaping bound vars,
304315
// we don't need to replace them with placeholders.
305-
let (data, maps) = if data.has_escaping_bound_vars() {
306-
let (data, mapped_regions, mapped_types, mapped_consts) =
307-
BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data);
308-
(data, Some((mapped_regions, mapped_types, mapped_consts)))
316+
let (term, maps) = if term.has_escaping_bound_vars() {
317+
let (term, mapped_regions, mapped_types, mapped_consts) =
318+
BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, term);
319+
(term, Some((mapped_regions, mapped_types, mapped_consts)))
309320
} else {
310-
(data, None)
321+
(term, None)
311322
};
312-
let data = data.try_fold_with(self)?;
323+
let term = term.try_fold_with(self)?;
313324

314325
let mut orig_values = OriginalQueryValues::default();
315-
let c_data = infcx.canonicalize_query(self.param_env.and(data), &mut orig_values);
316-
debug!("QueryNormalizer: c_data = {:#?}", c_data);
326+
let c_term = infcx.canonicalize_query(self.param_env.and(term), &mut orig_values);
327+
debug!("QueryNormalizer: c_term = {:#?}", c_term);
317328
debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
318-
let result = match kind {
319-
ty::Projection => tcx.normalize_canonicalized_projection_ty(c_data),
320-
ty::Free => tcx.normalize_canonicalized_free_alias(c_data),
321-
ty::Inherent => tcx.normalize_canonicalized_inherent_projection_ty(c_data),
322-
kind => unreachable!("did not expect {kind:?} due to match arm above"),
329+
let result = match term.kind(tcx) {
330+
ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => {
331+
tcx.normalize_canonicalized_projection(c_term)
332+
}
333+
ty::AliasTermKind::FreeTy | ty::AliasTermKind::FreeConst => {
334+
tcx.normalize_canonicalized_free_alias(c_term)
335+
}
336+
ty::AliasTermKind::InherentTy | ty::AliasTermKind::InherentConst => {
337+
tcx.normalize_canonicalized_inherent_projection(c_term)
338+
}
339+
kind @ (ty::AliasTermKind::OpaqueTy | ty::AliasTermKind::UnevaluatedConst) => {
340+
unreachable!("did not expect {kind:?} due to match arm above")
341+
}
323342
}?;
324343
// We don't expect ambiguity.
325344
if !result.value.is_proven() {
326345
// Rustdoc normalizes possibly not well-formed types, so only
327346
// treat this as a bug if we're not in rustdoc.
328347
if !tcx.sess.opts.actually_rustdoc {
329-
tcx.dcx().delayed_bug(format!("unexpected ambiguity: {c_data:?} {result:?}"));
348+
tcx.dcx().delayed_bug(format!("unexpected ambiguity: {c_term:?} {result:?}"));
330349
}
331350
return Err(NoSolution);
332351
}
@@ -347,16 +366,19 @@ impl<'a, 'tcx> QueryNormalizer<'a, 'tcx> {
347366
mapped_types,
348367
mapped_consts,
349368
&self.universes,
350-
result.normalized_ty,
369+
result.normalized_term,
351370
)
352371
} else {
353-
result.normalized_ty
372+
result.normalized_term
354373
};
355-
// `tcx.normalize_canonicalized_projection_ty` may normalize to a type that
374+
// `tcx.normalize_canonicalized_projection` may normalize to a type that
356375
// still has unevaluated consts, so keep normalizing here if that's the case.
357376
// Similarly, `tcx.normalize_canonicalized_free_alias` will only unwrap one layer
358377
// of type and we need to continue folding it to reveal the TAIT behind it.
359-
if res != ty && (res.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) || kind == ty::Free) {
378+
if res != term.to_term(tcx)
379+
&& (res.as_type().map_or(false, |t| t.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION))
380+
|| term.kind(tcx) == ty::AliasTermKind::FreeTy)
381+
{
360382
res.try_fold_with(self)
361383
} else {
362384
Ok(res)

compiler/rustc_traits/src/normalize_projection_ty.rs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,18 @@ use tracing::debug;
1212

1313
pub(crate) fn provide(p: &mut Providers) {
1414
*p = Providers {
15-
normalize_canonicalized_projection_ty,
15+
normalize_canonicalized_projection,
1616
normalize_canonicalized_free_alias,
17-
normalize_canonicalized_inherent_projection_ty,
17+
normalize_canonicalized_inherent_projection,
1818
..*p
1919
};
2020
}
2121

22-
fn normalize_canonicalized_projection_ty<'tcx>(
22+
fn normalize_canonicalized_projection<'tcx>(
2323
tcx: TyCtxt<'tcx>,
2424
goal: CanonicalAliasGoal<'tcx>,
2525
) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, NormalizationResult<'tcx>>>, NoSolution> {
26-
debug!("normalize_canonicalized_projection_ty(goal={:#?})", goal);
26+
debug!("normalize_canonicalized_projection(goal={:#?})", goal);
2727

2828
tcx.infer_ctxt().enter_canonical_trait_query(
2929
&goal,
@@ -32,7 +32,7 @@ fn normalize_canonicalized_projection_ty<'tcx>(
3232
let selcx = &mut SelectionContext::new(ocx.infcx);
3333
let cause = ObligationCause::dummy();
3434
let mut obligations = PredicateObligations::new();
35-
let answer = traits::normalize_projection_term(
35+
let normalized_term = traits::normalize_projection_term(
3636
selcx,
3737
param_env,
3838
goal.into(),
@@ -61,10 +61,10 @@ fn normalize_canonicalized_projection_ty<'tcx>(
6161
return Err(NoSolution);
6262
}
6363

64-
// FIXME(associated_const_equality): All users of normalize_canonicalized_projection_ty
64+
// FIXME(associated_const_equality): All users of normalize_canonicalized_projection
6565
// expected a type, but there is the possibility it could've been a const now.
6666
// Maybe change it to a Term later?
67-
Ok(NormalizationResult { normalized_ty: answer.expect_type() })
67+
Ok(NormalizationResult { normalized_term })
6868
},
6969
)
7070
}
@@ -89,25 +89,29 @@ fn normalize_canonicalized_free_alias<'tcx>(
8989
},
9090
);
9191
ocx.register_obligations(obligations);
92-
let normalized_ty = tcx.type_of(goal.def_id).instantiate(tcx, goal.args);
93-
Ok(NormalizationResult { normalized_ty })
92+
let normalized_term = if goal.kind(tcx).is_type() {
93+
tcx.type_of(goal.def_id).instantiate(tcx, goal.args).into()
94+
} else {
95+
tcx.const_of_item(goal.def_id).instantiate(tcx, goal.args).into()
96+
};
97+
Ok(NormalizationResult { normalized_term })
9498
},
9599
)
96100
}
97101

98-
fn normalize_canonicalized_inherent_projection_ty<'tcx>(
102+
fn normalize_canonicalized_inherent_projection<'tcx>(
99103
tcx: TyCtxt<'tcx>,
100104
goal: CanonicalAliasGoal<'tcx>,
101105
) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, NormalizationResult<'tcx>>>, NoSolution> {
102-
debug!("normalize_canonicalized_inherent_projection_ty(goal={:#?})", goal);
106+
debug!("normalize_canonicalized_inherent_projection(goal={:#?})", goal);
103107

104108
tcx.infer_ctxt().enter_canonical_trait_query(
105109
&goal,
106110
|ocx, ParamEnvAnd { param_env, value: goal }| {
107111
let selcx = &mut SelectionContext::new(ocx.infcx);
108112
let cause = ObligationCause::dummy();
109113
let mut obligations = PredicateObligations::new();
110-
let answer = traits::normalize_inherent_projection(
114+
let normalized_term = traits::normalize_inherent_projection(
111115
selcx,
112116
param_env,
113117
goal.into(),
@@ -117,7 +121,7 @@ fn normalize_canonicalized_inherent_projection_ty<'tcx>(
117121
);
118122
ocx.register_obligations(obligations);
119123

120-
Ok(NormalizationResult { normalized_ty: answer.expect_type() })
124+
Ok(NormalizationResult { normalized_term })
121125
},
122126
)
123127
}

0 commit comments

Comments
 (0)