Skip to content

Commit 5a4f474

Browse files
authored
Rollup merge of #92780 - b-naber:postpone-const-eval-coherence, r=lcnr
Directly use ConstValue for single literals in blocks Addresses the minimal repro in #92186, but doesn't fix the underlying problem (which would be solved by solving the anon subst problem afaict). I do, however, think that it makes sense in general to treat single literals in anon blocks as const values directly, especially in light of the problem that the issue refers to (anon const evaluation being postponed until infer variables in substs can be resolved, which was introduced by #90023), i.e. while we do get warnings for those unnecessary braces, we should try to avoid errors caused by those braces if possible.
2 parents ff476b3 + 7dac626 commit 5a4f474

File tree

7 files changed

+55
-21
lines changed

7 files changed

+55
-21
lines changed

Diff for: compiler/rustc_middle/src/ty/consts.rs

+12-9
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ impl<'tcx> Const<'tcx> {
3636
Self::from_opt_const_arg_anon_const(tcx, ty::WithOptConstParam::unknown(def_id))
3737
}
3838

39+
#[instrument(skip(tcx), level = "debug")]
3940
pub fn from_opt_const_arg_anon_const(
4041
tcx: TyCtxt<'tcx>,
4142
def: ty::WithOptConstParam<LocalDefId>,
@@ -51,6 +52,7 @@ impl<'tcx> Const<'tcx> {
5152
};
5253

5354
let expr = &tcx.hir().body(body_id).value;
55+
debug!(?expr);
5456

5557
let ty = tcx.type_of(def.def_id_for_type_of());
5658

@@ -67,11 +69,21 @@ impl<'tcx> Const<'tcx> {
6769
}
6870
}
6971

72+
#[instrument(skip(tcx), level = "debug")]
7073
fn try_eval_lit_or_param(
7174
tcx: TyCtxt<'tcx>,
7275
ty: Ty<'tcx>,
7376
expr: &'tcx hir::Expr<'tcx>,
7477
) -> Option<&'tcx Self> {
78+
// Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
79+
// currently have to be wrapped in curly brackets, so it's necessary to special-case.
80+
let expr = match &expr.kind {
81+
hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => {
82+
block.expr.as_ref().unwrap()
83+
}
84+
_ => expr,
85+
};
86+
7587
let lit_input = match expr.kind {
7688
hir::ExprKind::Lit(ref lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
7789
hir::ExprKind::Unary(hir::UnOp::Neg, ref expr) => match expr.kind {
@@ -97,15 +109,6 @@ impl<'tcx> Const<'tcx> {
97109
}
98110
}
99111

100-
// Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
101-
// currently have to be wrapped in curly brackets, so it's necessary to special-case.
102-
let expr = match &expr.kind {
103-
hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => {
104-
block.expr.as_ref().unwrap()
105-
}
106-
_ => expr,
107-
};
108-
109112
use hir::{def::DefKind::ConstParam, def::Res, ExprKind, Path, QPath};
110113
match expr.kind {
111114
ExprKind::Path(QPath::Resolved(_, &Path { res: Res::Def(ConstParam, def_id), .. })) => {

Diff for: compiler/rustc_trait_selection/src/traits/coherence.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ pub fn add_placeholder_note(err: &mut rustc_errors::DiagnosticBuilder<'_>) {
5353
/// If there are types that satisfy both impls, invokes `on_overlap`
5454
/// with a suitably-freshened `ImplHeader` with those types
5555
/// substituted. Otherwise, invokes `no_overlap`.
56+
#[instrument(skip(tcx, skip_leak_check, on_overlap, no_overlap), level = "debug")]
5657
pub fn overlapping_impls<F1, F2, R>(
5758
tcx: TyCtxt<'_>,
5859
impl1_def_id: DefId,
@@ -65,12 +66,6 @@ where
6566
F1: FnOnce(OverlapResult<'_>) -> R,
6667
F2: FnOnce() -> R,
6768
{
68-
debug!(
69-
"overlapping_impls(\
70-
impl1_def_id={:?}, \
71-
impl2_def_id={:?})",
72-
impl1_def_id, impl2_def_id,
73-
);
7469
// Before doing expensive operations like entering an inference context, do
7570
// a quick check via fast_reject to tell if the impl headers could possibly
7671
// unify.
@@ -85,6 +80,7 @@ where
8580
.any(|(ty1, ty2)| {
8681
let t1 = fast_reject::simplify_type(tcx, ty1, SimplifyParams::No, StripReferences::No);
8782
let t2 = fast_reject::simplify_type(tcx, ty2, SimplifyParams::No, StripReferences::No);
83+
8884
if let (Some(t1), Some(t2)) = (t1, t2) {
8985
// Simplified successfully
9086
t1 != t2

Diff for: compiler/rustc_trait_selection/src/traits/specialize/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,8 @@ pub fn translate_substs<'a, 'tcx>(
117117
/// Specialization is determined by the sets of types to which the impls apply;
118118
/// `impl1` specializes `impl2` if it applies to a subset of the types `impl2` applies
119119
/// to.
120+
#[instrument(skip(tcx), level = "debug")]
120121
pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId, DefId)) -> bool {
121-
debug!("specializes({:?}, {:?})", impl1_def_id, impl2_def_id);
122-
123122
// The feature gate should prevent introducing new specializations, but not
124123
// taking advantage of upstream ones.
125124
let features = tcx.features();

Diff for: src/test/ui/const-generics/issues/issue-92186.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// check-pass
2+
3+
#![feature(generic_const_exprs)]
4+
#![allow(incomplete_features)]
5+
6+
pub struct Foo<const N: usize>;
7+
pub trait Bar<T> {}
8+
9+
impl<T> Bar<T> for Foo<{ 1 }> {}
10+
impl<T> Bar<T> for Foo<{ 2 }> {}
11+
12+
fn main() {}

Diff for: src/test/ui/const-generics/types-mismatch-const-args.full.stderr

+14-3
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,20 @@ LL | let _: A<'a, u16, {2u32}, {3u32}> = A::<'b, u32, {2u32}, {3u32}> { data
1515
| |
1616
| expected due to this
1717
|
18-
= note: expected struct `A<'a, u16, {2u32}, {3u32}>`
19-
found struct `A<'b, u32, {2u32}, {3u32}>`
18+
= note: expected struct `A<'a, u16, _, _>`
19+
found struct `A<'b, u32, _, _>`
2020

21-
error: aborting due to 2 previous errors
21+
error[E0308]: mismatched types
22+
--> $DIR/types-mismatch-const-args.rs:18:41
23+
|
24+
LL | let _: A<'a, u16, {4u32}, {3u32}> = A::<'b, u32, {2u32}, {3u32}> { data: PhantomData };
25+
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u16`, found `u32`
26+
| |
27+
| expected due to this
28+
|
29+
= note: expected struct `A<'a, u16, 4_u32, _>`
30+
found struct `A<'b, u32, 2_u32, _>`
31+
32+
error: aborting due to 3 previous errors
2233

2334
For more information about this error, try `rustc --explain E0308`.

Diff for: src/test/ui/const-generics/types-mismatch-const-args.min.stderr

+12-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,17 @@ LL | let _: A<'a, u16, {2u32}, {3u32}> = A::<'b, u32, {2u32}, {3u32}> { data
2020
= note: expected struct `A<'a, u16, _, _>`
2121
found struct `A<'b, u32, _, _>`
2222

23-
error: aborting due to 2 previous errors
23+
error[E0308]: mismatched types
24+
--> $DIR/types-mismatch-const-args.rs:18:41
25+
|
26+
LL | let _: A<'a, u16, {4u32}, {3u32}> = A::<'b, u32, {2u32}, {3u32}> { data: PhantomData };
27+
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u16`, found `u32`
28+
| |
29+
| expected due to this
30+
|
31+
= note: expected struct `A<'a, u16, 4_u32, _>`
32+
found struct `A<'b, u32, 2_u32, _>`
33+
34+
error: aborting due to 3 previous errors
2435

2536
For more information about this error, try `rustc --explain E0308`.

Diff for: src/test/ui/const-generics/types-mismatch-const-args.rs

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ fn a<'a, 'b>() {
1515
//~^ ERROR mismatched types
1616
let _: A<'a, u16, {2u32}, {3u32}> = A::<'b, u32, {2u32}, {3u32}> { data: PhantomData };
1717
//~^ ERROR mismatched types
18+
let _: A<'a, u16, {4u32}, {3u32}> = A::<'b, u32, {2u32}, {3u32}> { data: PhantomData };
19+
//~^ ERROR mismatched types
1820
}
1921

2022
pub fn main() {}

0 commit comments

Comments
 (0)