Skip to content

Commit a315a05

Browse files
committed
compare after fully resolving and disable lint if generic_const_exprs enabled
1 parent 4408f14 commit a315a05

File tree

5 files changed

+121
-69
lines changed

5 files changed

+121
-69
lines changed

compiler/rustc_trait_selection/src/solve/normalize.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,7 @@ where
217217
fn try_fold_const(&mut self, ct: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, Self::Error> {
218218
let infcx = self.at.infcx;
219219
debug_assert_eq!(ct, infcx.shallow_resolve_const(ct));
220-
// FIXME: `generic_const_exprs` causes query cycle problem. Same as the old solver.
221-
if !ct.has_aliases() || infcx.tcx.features().generic_const_exprs() {
220+
if !ct.has_aliases() {
222221
return Ok(ct);
223222
}
224223

compiler/rustc_trait_selection/src/traits/mod.rs

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -284,38 +284,6 @@ fn do_normalize_predicates<'tcx>(
284284

285285
debug!("do_normalize_predicates: normalized predicates = {:?}", predicates);
286286

287-
// The next solver returns nothing for values that contains type error.
288-
// And type error should cause failure later. So we skip the consistency check.
289-
if !tcx.next_trait_solver_globally() && !predicates.references_error() {
290-
let infcx = tcx
291-
.infer_ctxt()
292-
.with_next_trait_solver(true)
293-
.ignoring_regions()
294-
.build(TypingMode::non_body_analysis());
295-
for (orig_pred, pred_by_old) in original_predicates.into_iter().zip(&predicates) {
296-
let inconsistent_pred_by_next =
297-
match crate::solve::deeply_normalize::<_, ScrubbedTraitError<'tcx>>(
298-
infcx.at(&cause, elaborated_env),
299-
orig_pred,
300-
) {
301-
Ok(pred_by_next) => {
302-
if pred_by_next == *pred_by_old {
303-
continue;
304-
}
305-
Some(pred_by_next)
306-
}
307-
Err(_) => None,
308-
};
309-
tcx.dcx().span_err(
310-
span,
311-
format!(
312-
"inconsistency during normalizing env `{:#?}`, old={:#?}, next={:#?}",
313-
orig_pred, pred_by_old, inconsistent_pred_by_next
314-
),
315-
);
316-
}
317-
}
318-
319287
// We can use the `elaborated_env` here; the region code only
320288
// cares about declarations like `'a: 'b`.
321289
// FIXME: It's very weird that we ignore region obligations but apparently
@@ -329,8 +297,8 @@ fn do_normalize_predicates<'tcx>(
329297
);
330298
}
331299

332-
match infcx.fully_resolve(predicates) {
333-
Ok(predicates) => Ok(predicates),
300+
let predicates = match infcx.fully_resolve(predicates) {
301+
Ok(predicates) => predicates,
334302
Err(fixup_err) => {
335303
// If we encounter a fixup error, it means that some type
336304
// variable wound up unconstrained. I actually don't know
@@ -347,7 +315,43 @@ fn do_normalize_predicates<'tcx>(
347315
fixup_err
348316
);
349317
}
318+
};
319+
// The next solver returns nothing for values that contains type error.
320+
// And type error should cause failure later. So we skip the consistency check.
321+
// `generic_const_exprs` is incompatible with next solver now.
322+
if !tcx.next_trait_solver_globally()
323+
&& !predicates.references_error()
324+
&& !tcx.features().generic_const_exprs()
325+
{
326+
let infcx = tcx
327+
.infer_ctxt()
328+
.with_next_trait_solver(true)
329+
.ignoring_regions()
330+
.build(TypingMode::non_body_analysis());
331+
for (orig_pred, pred_by_old) in original_predicates.into_iter().zip(&predicates) {
332+
let inconsistent_pred_by_next =
333+
match crate::solve::deeply_normalize::<_, ScrubbedTraitError<'tcx>>(
334+
infcx.at(&cause, elaborated_env),
335+
orig_pred,
336+
) {
337+
Ok(pred_by_next) => {
338+
if pred_by_next == *pred_by_old {
339+
continue;
340+
}
341+
Some(pred_by_next)
342+
}
343+
Err(_) => None,
344+
};
345+
tcx.dcx().span_err(
346+
span,
347+
format!(
348+
"inconsistency during normalizing env `{:#?}`, old={:#?}, next={:#?}",
349+
orig_pred, pred_by_old, inconsistent_pred_by_next
350+
),
351+
);
352+
}
350353
}
354+
Ok(predicates)
351355
}
352356

353357
// FIXME: this is gonna need to be removed ...

tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,5 @@ trait Trait {}
1010
impl<const N: u32> Trait for A<N> {}
1111

1212
impl<const N: u32> Trait for A<N> {}
13-
//~^ ERROR: conflicting implementations of trait
1413

1514
pub fn main() {}

tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.stderr

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,6 @@ error[E0423]: expected value, found builtin type `u8`
44
LL | struct A<const N: u32 = 1, const M: u32 = u8>;
55
| ^^ not a value
66

7-
error[E0119]: conflicting implementations of trait `Trait` for type `A<_>`
8-
--> $DIR/unknown-alias-defkind-anonconst-ice-116710.rs:12:1
9-
|
10-
LL | impl<const N: u32> Trait for A<N> {}
11-
| --------------------------------- first implementation here
12-
LL |
13-
LL | impl<const N: u32> Trait for A<N> {}
14-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `A<_>`
15-
16-
error: aborting due to 2 previous errors
7+
error: aborting due to 1 previous error
178

18-
Some errors have detailed explanations: E0119, E0423.
19-
For more information about an error, try `rustc --explain E0119`.
9+
For more information about this error, try `rustc --explain E0423`.

tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr

Lines changed: 80 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,34 +6,94 @@ LL | #![feature(const_trait_impl, generic_const_exprs)]
66
|
77
= help: remove one of these features
88

9-
error[E0277]: the trait bound `T: const Trait` is not satisfied
10-
--> $DIR/unsatisfied-const-trait-bound.rs:28:37
9+
error[E0391]: cycle detected when evaluating type-level constant
10+
--> $DIR/unsatisfied-const-trait-bound.rs:28:35
1111
|
1212
LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
13-
| ^
13+
| ^^^^^^^^^^^^^
14+
|
15+
note: ...which requires const-evaluating + checking `accept0::{constant#0}`...
16+
--> $DIR/unsatisfied-const-trait-bound.rs:28:35
17+
|
18+
LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
19+
| ^^^^^^^^^^^^^
20+
note: ...which requires checking if `accept0::{constant#0}` is a trivial const...
21+
--> $DIR/unsatisfied-const-trait-bound.rs:28:35
22+
|
23+
LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
24+
| ^^^^^^^^^^^^^
25+
note: ...which requires building MIR for `accept0::{constant#0}`...
26+
--> $DIR/unsatisfied-const-trait-bound.rs:28:35
27+
|
28+
LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
29+
| ^^^^^^^^^^^^^
30+
note: ...which requires building an abstract representation for `accept0::{constant#0}`...
31+
--> $DIR/unsatisfied-const-trait-bound.rs:28:35
32+
|
33+
LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
34+
| ^^^^^^^^^^^^^
35+
note: ...which requires building THIR for `accept0::{constant#0}`...
36+
--> $DIR/unsatisfied-const-trait-bound.rs:28:35
37+
|
38+
LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
39+
| ^^^^^^^^^^^^^
40+
note: ...which requires type-checking `accept0::{constant#0}`...
41+
--> $DIR/unsatisfied-const-trait-bound.rs:28:35
42+
|
43+
LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
44+
| ^^^^^^^^^^^^^
45+
= note: ...which again requires evaluating type-level constant, completing the cycle
46+
note: cycle used when checking that `accept0` is well-formed
47+
--> $DIR/unsatisfied-const-trait-bound.rs:28:35
48+
|
49+
LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
50+
| ^^^^^^^^^^^^^
51+
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
1452

15-
error[E0277]: the trait bound `T: const Trait` is not satisfied
16-
--> $DIR/unsatisfied-const-trait-bound.rs:32:51
53+
error[E0391]: cycle detected when checking if `accept1::{constant#0}` is a trivial const
54+
--> $DIR/unsatisfied-const-trait-bound.rs:32:49
1755
|
1856
LL | const fn accept1<T: [const] Trait>(_: Container<{ T::make() }>) {}
19-
| ^
20-
21-
error[E0277]: the trait bound `Ty: const Trait` is not satisfied
22-
--> $DIR/unsatisfied-const-trait-bound.rs:21:15
57+
| ^^^^^^^^^^^^^
2358
|
24-
LL | require::<Ty>();
25-
| ^^
59+
note: ...which requires building MIR for `accept1::{constant#0}`...
60+
--> $DIR/unsatisfied-const-trait-bound.rs:32:49
2661
|
27-
note: required by a bound in `require`
28-
--> $DIR/unsatisfied-const-trait-bound.rs:8:15
62+
LL | const fn accept1<T: [const] Trait>(_: Container<{ T::make() }>) {}
63+
| ^^^^^^^^^^^^^
64+
note: ...which requires building an abstract representation for `accept1::{constant#0}`...
65+
--> $DIR/unsatisfied-const-trait-bound.rs:32:49
2966
|
30-
LL | fn require<T: const Trait>() {}
31-
| ^^^^^^^^^^^ required by this bound in `require`
32-
help: make the `impl` of trait `Trait` `const`
67+
LL | const fn accept1<T: [const] Trait>(_: Container<{ T::make() }>) {}
68+
| ^^^^^^^^^^^^^
69+
note: ...which requires building THIR for `accept1::{constant#0}`...
70+
--> $DIR/unsatisfied-const-trait-bound.rs:32:49
3371
|
34-
LL | impl const Trait for Ty {
35-
| +++++
72+
LL | const fn accept1<T: [const] Trait>(_: Container<{ T::make() }>) {}
73+
| ^^^^^^^^^^^^^
74+
note: ...which requires type-checking `accept1::{constant#0}`...
75+
--> $DIR/unsatisfied-const-trait-bound.rs:32:49
76+
|
77+
LL | const fn accept1<T: [const] Trait>(_: Container<{ T::make() }>) {}
78+
| ^^^^^^^^^^^^^
79+
note: ...which requires evaluating type-level constant...
80+
--> $DIR/unsatisfied-const-trait-bound.rs:32:49
81+
|
82+
LL | const fn accept1<T: [const] Trait>(_: Container<{ T::make() }>) {}
83+
| ^^^^^^^^^^^^^
84+
note: ...which requires const-evaluating + checking `accept1::{constant#0}`...
85+
--> $DIR/unsatisfied-const-trait-bound.rs:32:49
86+
|
87+
LL | const fn accept1<T: [const] Trait>(_: Container<{ T::make() }>) {}
88+
| ^^^^^^^^^^^^^
89+
= note: ...which again requires checking if `accept1::{constant#0}` is a trivial const, completing the cycle
90+
note: cycle used when const-evaluating + checking `accept1::{constant#0}`
91+
--> $DIR/unsatisfied-const-trait-bound.rs:32:49
92+
|
93+
LL | const fn accept1<T: [const] Trait>(_: Container<{ T::make() }>) {}
94+
| ^^^^^^^^^^^^^
95+
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
3696

37-
error: aborting due to 4 previous errors
97+
error: aborting due to 3 previous errors
3898

39-
For more information about this error, try `rustc --explain E0277`.
99+
For more information about this error, try `rustc --explain E0391`.

0 commit comments

Comments
 (0)