Skip to content

Commit 3a11e35

Browse files
authored
Unrolled build for #142126
Rollup merge of #142126 - compiler-errors:normalize-uv-via-relate, r=BoxyUwU Treat normalizing consts like normalizing types in deeply normalize ...so that we don't end up putting a top-level normalizes-to goal in the fulfillment context, which ICEs. This basically just models the normalize-const code off of the normalize-ty code above it, which uses an alias-relate goal instead. Fixes #140571 r? lcnr
2 parents cdd545b + aa1b296 commit 3a11e35

File tree

6 files changed

+64
-76
lines changed

6 files changed

+64
-76
lines changed

compiler/rustc_infer/src/infer/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,13 @@ impl<'tcx> InferCtxt<'tcx> {
823823
ty::Region::new_var(self.tcx, region_var)
824824
}
825825

826+
pub fn next_term_var_of_kind(&self, term: ty::Term<'tcx>, span: Span) -> ty::Term<'tcx> {
827+
match term.kind() {
828+
ty::TermKind::Ty(_) => self.next_ty_var(span).into(),
829+
ty::TermKind::Const(_) => self.next_const_var(span).into(),
830+
}
831+
}
832+
826833
/// Return the universe that the region `r` was created in. For
827834
/// most regions (e.g., `'static`, named regions from the user,
828835
/// etc) this is the root universe U0. For inference variables or

compiler/rustc_trait_selection/src/solve/inspect/analyse.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -231,10 +231,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
231231
let infcx = self.goal.infcx;
232232
match goal.predicate.kind().no_bound_vars() {
233233
Some(ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term })) => {
234-
let unconstrained_term = match term.kind() {
235-
ty::TermKind::Ty(_) => infcx.next_ty_var(span).into(),
236-
ty::TermKind::Const(_) => infcx.next_const_var(span).into(),
237-
};
234+
let unconstrained_term = infcx.next_term_var_of_kind(term, span);
238235
let goal =
239236
goal.with(infcx.tcx, ty::NormalizesTo { alias, term: unconstrained_term });
240237
// We have to use a `probe` here as evaluating a `NormalizesTo` can constrain the

compiler/rustc_trait_selection/src/solve/normalize.rs

Lines changed: 25 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use std::assert_matches::assert_matches;
21
use std::fmt::Debug;
32

43
use rustc_data_structures::stack::ensure_sufficient_stack;
@@ -16,7 +15,6 @@ use tracing::instrument;
1615
use super::{FulfillmentCtxt, NextSolverError};
1716
use crate::error_reporting::InferCtxtErrorExt;
1817
use crate::error_reporting::traits::OverflowCause;
19-
use crate::traits::query::evaluate_obligation::InferCtxtExt;
2018
use crate::traits::{BoundVarReplacer, PlaceholderReplacer, ScrubbedTraitError};
2119

2220
/// Deeply normalize all aliases in `value`. This does not handle inference and expects
@@ -97,19 +95,18 @@ impl<'tcx, E> NormalizationFolder<'_, 'tcx, E>
9795
where
9896
E: FromSolverError<'tcx, NextSolverError<'tcx>>,
9997
{
100-
fn normalize_alias_ty(&mut self, alias_ty: Ty<'tcx>) -> Result<Ty<'tcx>, Vec<E>> {
101-
assert_matches!(alias_ty.kind(), ty::Alias(..));
102-
98+
fn normalize_alias_term(
99+
&mut self,
100+
alias_term: ty::Term<'tcx>,
101+
) -> Result<ty::Term<'tcx>, Vec<E>> {
103102
let infcx = self.at.infcx;
104103
let tcx = infcx.tcx;
105104
let recursion_limit = tcx.recursion_limit();
106105
if !recursion_limit.value_within_limit(self.depth) {
107-
let ty::Alias(_, data) = *alias_ty.kind() else {
108-
unreachable!();
109-
};
106+
let term = alias_term.to_alias_term().unwrap();
110107

111108
self.at.infcx.err_ctxt().report_overflow_error(
112-
OverflowCause::DeeplyNormalize(data.into()),
109+
OverflowCause::DeeplyNormalize(term),
113110
self.at.cause.span,
114111
true,
115112
|_| {},
@@ -118,14 +115,14 @@ where
118115

119116
self.depth += 1;
120117

121-
let new_infer_ty = infcx.next_ty_var(self.at.cause.span);
118+
let infer_term = infcx.next_term_var_of_kind(alias_term, self.at.cause.span);
122119
let obligation = Obligation::new(
123120
tcx,
124121
self.at.cause.clone(),
125122
self.at.param_env,
126123
ty::PredicateKind::AliasRelate(
127-
alias_ty.into(),
128-
new_infer_ty.into(),
124+
alias_term.into(),
125+
infer_term.into(),
129126
ty::AliasRelationDirection::Equate,
130127
),
131128
);
@@ -135,50 +132,13 @@ where
135132

136133
// Alias is guaranteed to be fully structurally resolved,
137134
// so we can super fold here.
138-
let ty = infcx.resolve_vars_if_possible(new_infer_ty);
139-
let result = ty.try_super_fold_with(self)?;
140-
self.depth -= 1;
141-
Ok(result)
142-
}
143-
144-
fn normalize_unevaluated_const(
145-
&mut self,
146-
uv: ty::UnevaluatedConst<'tcx>,
147-
) -> Result<ty::Const<'tcx>, Vec<E>> {
148-
let infcx = self.at.infcx;
149-
let tcx = infcx.tcx;
150-
let recursion_limit = tcx.recursion_limit();
151-
if !recursion_limit.value_within_limit(self.depth) {
152-
self.at.infcx.err_ctxt().report_overflow_error(
153-
OverflowCause::DeeplyNormalize(uv.into()),
154-
self.at.cause.span,
155-
true,
156-
|_| {},
157-
);
158-
}
159-
160-
self.depth += 1;
161-
162-
let new_infer_ct = infcx.next_const_var(self.at.cause.span);
163-
let obligation = Obligation::new(
164-
tcx,
165-
self.at.cause.clone(),
166-
self.at.param_env,
167-
ty::NormalizesTo { alias: uv.into(), term: new_infer_ct.into() },
168-
);
169-
170-
let result = if infcx.predicate_may_hold(&obligation) {
171-
self.fulfill_cx.register_predicate_obligation(infcx, obligation);
172-
let errors = self.fulfill_cx.select_where_possible(infcx);
173-
if !errors.is_empty() {
174-
return Err(errors);
175-
}
176-
let ct = infcx.resolve_vars_if_possible(new_infer_ct);
177-
ct.try_fold_with(self)?
178-
} else {
179-
ty::Const::new_unevaluated(tcx, uv).try_super_fold_with(self)?
135+
let term = infcx.resolve_vars_if_possible(infer_term);
136+
// super-folding the `term` will directly fold the `Ty` or `Const` so
137+
// we have to match on the term and super-fold them manually.
138+
let result = match term.kind() {
139+
ty::TermKind::Ty(ty) => ty.try_super_fold_with(self)?.into(),
140+
ty::TermKind::Const(ct) => ct.try_super_fold_with(self)?.into(),
180141
};
181-
182142
self.depth -= 1;
183143
Ok(result)
184144
}
@@ -238,7 +198,8 @@ where
238198
if ty.has_escaping_bound_vars() {
239199
let (ty, mapped_regions, mapped_types, mapped_consts) =
240200
BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, ty);
241-
let result = ensure_sufficient_stack(|| self.normalize_alias_ty(ty))?;
201+
let result =
202+
ensure_sufficient_stack(|| self.normalize_alias_term(ty.into()))?.expect_type();
242203
Ok(PlaceholderReplacer::replace_placeholders(
243204
infcx,
244205
mapped_regions,
@@ -248,7 +209,7 @@ where
248209
result,
249210
))
250211
} else {
251-
ensure_sufficient_stack(|| self.normalize_alias_ty(ty))
212+
Ok(ensure_sufficient_stack(|| self.normalize_alias_term(ty.into()))?.expect_type())
252213
}
253214
}
254215

@@ -260,15 +221,13 @@ where
260221
return Ok(ct);
261222
}
262223

263-
let uv = match ct.kind() {
264-
ty::ConstKind::Unevaluated(ct) => ct,
265-
_ => return ct.try_super_fold_with(self),
266-
};
224+
let ty::ConstKind::Unevaluated(..) = ct.kind() else { return ct.try_super_fold_with(self) };
267225

268-
if uv.has_escaping_bound_vars() {
269-
let (uv, mapped_regions, mapped_types, mapped_consts) =
270-
BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, uv);
271-
let result = ensure_sufficient_stack(|| self.normalize_unevaluated_const(uv))?;
226+
if ct.has_escaping_bound_vars() {
227+
let (ct, mapped_regions, mapped_types, mapped_consts) =
228+
BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, ct);
229+
let result =
230+
ensure_sufficient_stack(|| self.normalize_alias_term(ct.into()))?.expect_const();
272231
Ok(PlaceholderReplacer::replace_placeholders(
273232
infcx,
274233
mapped_regions,
@@ -278,7 +237,7 @@ where
278237
result,
279238
))
280239
} else {
281-
ensure_sufficient_stack(|| self.normalize_unevaluated_const(uv))
240+
Ok(ensure_sufficient_stack(|| self.normalize_alias_term(ct.into()))?.expect_const())
282241
}
283242
}
284243
}

compiler/rustc_trait_selection/src/traits/structural_normalize.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,7 @@ impl<'tcx> At<'_, 'tcx> {
3939
return Ok(term);
4040
}
4141

42-
let new_infer = match term.kind() {
43-
ty::TermKind::Ty(_) => self.infcx.next_ty_var(self.cause.span).into(),
44-
ty::TermKind::Const(_) => self.infcx.next_const_var(self.cause.span).into(),
45-
};
42+
let new_infer = self.infcx.next_term_var_of_kind(term, self.cause.span);
4643

4744
// We simply emit an `alias-eq` goal here, since that will take care of
4845
// normalizing the LHS of the projection until it is a rigid projection
Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
1-
//@ known-bug: #140571
1+
// Regression test for #140571. The compiler used to ICE
2+
3+
#![feature(associated_const_equality, specialization)]
4+
//~^ WARN the feature `specialization` is incomplete
5+
26
pub trait IsVoid {
37
const IS_VOID: bool;
48
}
59
impl<T> IsVoid for T {
610
default const IS_VOID: bool = false;
711
}
8-
impl<T> Maybe<T> for () where T: NotVoid + ?Sized {}
912

1013
pub trait NotVoid {}
1114
impl<T> NotVoid for T where T: IsVoid<IS_VOID = false> + ?Sized {}
1215

1316
pub trait Maybe<T> {}
1417
impl<T> Maybe<T> for T {}
18+
impl<T> Maybe<T> for () where T: NotVoid + ?Sized {}
19+
//~^ ERROR conflicting implementations of trait `Maybe<()>` for type `()`
20+
21+
fn main() {}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/overlap-due-to-unsatisfied-const-bound.rs:3:39
3+
|
4+
LL | #![feature(associated_const_equality, specialization)]
5+
| ^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
8+
= help: consider using `min_specialization` instead, which is more stable and complete
9+
= note: `#[warn(incomplete_features)]` on by default
10+
11+
error[E0119]: conflicting implementations of trait `Maybe<()>` for type `()`
12+
--> $DIR/overlap-due-to-unsatisfied-const-bound.rs:18:1
13+
|
14+
LL | impl<T> Maybe<T> for T {}
15+
| ---------------------- first implementation here
16+
LL | impl<T> Maybe<T> for () where T: NotVoid + ?Sized {}
17+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`
18+
19+
error: aborting due to 1 previous error; 1 warning emitted
20+
21+
For more information about this error, try `rustc --explain E0119`.

0 commit comments

Comments
 (0)