Skip to content

Commit d712024

Browse files
Rollup merge of #142927 - compiler-errors:note-find-const, r=BoxyUwU
Add note to `find_const_ty_from_env` Add a note to `find_const_ty_from_env` to explain why it has an `unwrap` which "often" causes ICEs. Also, uplift it into the new trait solver. This avoids needing to go through the interner to call this method which is otherwise an inherent method in the compiler. I can remove this part if desired. r? `@boxyuwu`
2 parents 58cda76 + df426cf commit d712024

File tree

10 files changed

+64
-48
lines changed

10 files changed

+64
-48
lines changed

compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1495,7 +1495,9 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
14951495
ty::ConstKind::Unevaluated(uv) => {
14961496
infcx.tcx.type_of(uv.def).instantiate(infcx.tcx, uv.args)
14971497
}
1498-
ty::ConstKind::Param(param_ct) => param_ct.find_ty_from_env(wfcx.param_env),
1498+
ty::ConstKind::Param(param_ct) => {
1499+
param_ct.find_const_ty_from_env(wfcx.param_env)
1500+
}
14991501
};
15001502

15011503
let param_ty = tcx.type_of(param.def_id).instantiate_identity();

compiler/rustc_middle/src/ty/context.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -698,14 +698,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
698698
self.unsizing_params_for_adt(adt_def_id)
699699
}
700700

701-
fn find_const_ty_from_env(
702-
self,
703-
param_env: ty::ParamEnv<'tcx>,
704-
placeholder: Self::PlaceholderConst,
705-
) -> Ty<'tcx> {
706-
placeholder.find_const_ty_from_env(param_env)
707-
}
708-
709701
fn anonymize_bound_vars<T: TypeFoldable<TyCtxt<'tcx>>>(
710702
self,
711703
binder: ty::Binder<'tcx, T>,

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -907,30 +907,6 @@ pub struct Placeholder<T> {
907907
pub universe: UniverseIndex,
908908
pub bound: T,
909909
}
910-
impl Placeholder<BoundVar> {
911-
pub fn find_const_ty_from_env<'tcx>(self, env: ParamEnv<'tcx>) -> Ty<'tcx> {
912-
let mut candidates = env.caller_bounds().iter().filter_map(|clause| {
913-
// `ConstArgHasType` are never desugared to be higher ranked.
914-
match clause.kind().skip_binder() {
915-
ty::ClauseKind::ConstArgHasType(placeholder_ct, ty) => {
916-
assert!(!(placeholder_ct, ty).has_escaping_bound_vars());
917-
918-
match placeholder_ct.kind() {
919-
ty::ConstKind::Placeholder(placeholder_ct) if placeholder_ct == self => {
920-
Some(ty)
921-
}
922-
_ => None,
923-
}
924-
}
925-
_ => None,
926-
}
927-
});
928-
929-
let ty = candidates.next().unwrap();
930-
assert!(candidates.next().is_none());
931-
ty
932-
}
933-
}
934910

935911
pub type PlaceholderRegion = Placeholder<BoundRegion>;
936912

compiler/rustc_middle/src/ty/sty.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ impl ParamConst {
346346
}
347347

348348
#[instrument(level = "debug")]
349-
pub fn find_ty_from_env<'tcx>(self, env: ParamEnv<'tcx>) -> Ty<'tcx> {
349+
pub fn find_const_ty_from_env<'tcx>(self, env: ParamEnv<'tcx>) -> Ty<'tcx> {
350350
let mut candidates = env.caller_bounds().iter().filter_map(|clause| {
351351
// `ConstArgHasType` are never desugared to be higher ranked.
352352
match clause.kind().skip_binder() {
@@ -362,8 +362,19 @@ impl ParamConst {
362362
}
363363
});
364364

365-
let ty = candidates.next().unwrap();
366-
assert!(candidates.next().is_none());
365+
// N.B. it may be tempting to fix ICEs by making this function return
366+
// `Option<Ty<'tcx>>` instead of `Ty<'tcx>`; however, this is generally
367+
// considered to be a bandaid solution, since it hides more important
368+
// underlying issues with how we construct generics and predicates of
369+
// items. It's advised to fix the underlying issue rather than trying
370+
// to modify this function.
371+
let ty = candidates.next().unwrap_or_else(|| {
372+
bug!("cannot find `{self:?}` in param-env: {env:#?}");
373+
});
374+
assert!(
375+
candidates.next().is_none(),
376+
"did not expect duplicate `ConstParamHasTy` for `{self:?}` in param-env: {env:#?}"
377+
);
367378
ty
368379
}
369380
}

compiler/rustc_next_trait_solver/src/solve/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ where
211211
ty::ConstKind::Bound(_, _) => panic!("escaping bound vars in {:?}", ct),
212212
ty::ConstKind::Value(cv) => cv.ty(),
213213
ty::ConstKind::Placeholder(placeholder) => {
214-
self.cx().find_const_ty_from_env(goal.param_env, placeholder)
214+
placeholder.find_const_ty_from_env(goal.param_env)
215215
}
216216
};
217217

compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ pub(super) fn fulfillment_error_for_no_solution<'tcx>(
3737
ty::ConstKind::Unevaluated(uv) => {
3838
infcx.tcx.type_of(uv.def).instantiate(infcx.tcx, uv.args)
3939
}
40-
ty::ConstKind::Param(param_ct) => param_ct.find_ty_from_env(obligation.param_env),
40+
ty::ConstKind::Param(param_ct) => {
41+
param_ct.find_const_ty_from_env(obligation.param_env)
42+
}
4143
ty::ConstKind::Value(cv) => cv.ty,
4244
kind => span_bug!(
4345
obligation.cause.span,

compiler/rustc_trait_selection/src/traits/fulfill.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
509509
}
510510
ty::ConstKind::Bound(_, _) => bug!("escaping bound vars in {:?}", ct),
511511
ty::ConstKind::Param(param_ct) => {
512-
param_ct.find_ty_from_env(obligation.param_env)
512+
param_ct.find_const_ty_from_env(obligation.param_env)
513513
}
514514
};
515515

compiler/rustc_trait_selection/src/traits/select/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -981,7 +981,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
981981
}
982982
ty::ConstKind::Bound(_, _) => bug!("escaping bound vars in {:?}", ct),
983983
ty::ConstKind::Param(param_ct) => {
984-
param_ct.find_ty_from_env(obligation.param_env)
984+
param_ct.find_const_ty_from_env(obligation.param_env)
985985
}
986986
};
987987

compiler/rustc_type_ir/src/inherent.rs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::elaborate::Elaboratable;
1212
use crate::fold::{TypeFoldable, TypeSuperFoldable};
1313
use crate::relate::Relate;
1414
use crate::solve::{AdtDestructorKind, SizedTraitKind};
15-
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
15+
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable, TypeVisitableExt};
1616
use crate::{self as ty, CollectAndApply, Interner, UpcastFrom};
1717

1818
pub trait Ty<I: Interner<Ty = Self>>:
@@ -538,6 +538,45 @@ pub trait PlaceholderLike<I: Interner>: Copy + Debug + Hash + Eq {
538538
fn with_updated_universe(self, ui: ty::UniverseIndex) -> Self;
539539
}
540540

541+
pub trait PlaceholderConst<I: Interner>: PlaceholderLike<I, Bound = I::BoundConst> {
542+
fn find_const_ty_from_env(self, env: I::ParamEnv) -> I::Ty;
543+
}
544+
impl<I: Interner> PlaceholderConst<I> for I::PlaceholderConst {
545+
fn find_const_ty_from_env(self, env: I::ParamEnv) -> I::Ty {
546+
let mut candidates = env.caller_bounds().iter().filter_map(|clause| {
547+
// `ConstArgHasType` are never desugared to be higher ranked.
548+
match clause.kind().skip_binder() {
549+
ty::ClauseKind::ConstArgHasType(placeholder_ct, ty) => {
550+
assert!(!(placeholder_ct, ty).has_escaping_bound_vars());
551+
552+
match placeholder_ct.kind() {
553+
ty::ConstKind::Placeholder(placeholder_ct) if placeholder_ct == self => {
554+
Some(ty)
555+
}
556+
_ => None,
557+
}
558+
}
559+
_ => None,
560+
}
561+
});
562+
563+
// N.B. it may be tempting to fix ICEs by making this function return
564+
// `Option<Ty<'tcx>>` instead of `Ty<'tcx>`; however, this is generally
565+
// considered to be a bandaid solution, since it hides more important
566+
// underlying issues with how we construct generics and predicates of
567+
// items. It's advised to fix the underlying issue rather than trying
568+
// to modify this function.
569+
let ty = candidates.next().unwrap_or_else(|| {
570+
panic!("cannot find `{self:?}` in param-env: {env:#?}");
571+
});
572+
assert!(
573+
candidates.next().is_none(),
574+
"did not expect duplicate `ConstParamHasTy` for `{self:?}` in param-env: {env:#?}"
575+
);
576+
ty
577+
}
578+
}
579+
541580
pub trait IntoKind {
542581
type Kind;
543582

compiler/rustc_type_ir/src/interner.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ pub trait Interner:
133133
type Const: Const<Self>;
134134
type ParamConst: Copy + Debug + Hash + Eq + ParamLike;
135135
type BoundConst: BoundVarLike<Self>;
136-
type PlaceholderConst: PlaceholderLike<Self, Bound = Self::BoundConst>;
136+
type PlaceholderConst: PlaceholderConst<Self>;
137137
type ValueConst: ValueConst<Self>;
138138
type ExprConst: ExprConst<Self>;
139139
type ValTree: Copy + Debug + Hash + Eq;
@@ -348,12 +348,6 @@ pub trait Interner:
348348
type UnsizingParams: Deref<Target = DenseBitSet<u32>>;
349349
fn unsizing_params_for_adt(self, adt_def_id: Self::DefId) -> Self::UnsizingParams;
350350

351-
fn find_const_ty_from_env(
352-
self,
353-
param_env: Self::ParamEnv,
354-
placeholder: Self::PlaceholderConst,
355-
) -> Self::Ty;
356-
357351
fn anonymize_bound_vars<T: TypeFoldable<Self>>(
358352
self,
359353
binder: ty::Binder<Self, T>,

0 commit comments

Comments
 (0)