Skip to content

Commit a84d1b2

Browse files
committed
Auto merge of rust-lang#86987 - lcnr:const-default-eval-bound, r=oli-obk
only check cg defaults wf once instantiated the previous fixmes here didn't make too much sense as I didn't yet fully understand the code further below. That code only runs if the predicates using our generic param default are fully concrete after substituting our default, which never happens if our default is generic. r? `@oli-obk` `@BoxyUwU`
2 parents 8eae2eb + 4a53b11 commit a84d1b2

File tree

6 files changed

+31
-38
lines changed

6 files changed

+31
-38
lines changed

compiler/rustc_typeck/src/check/wfcheck.rs

+11-15
Original file line numberDiff line numberDiff line change
@@ -738,15 +738,19 @@ fn check_where_clauses<'tcx, 'fcx>(
738738
}
739739
}
740740
GenericParamDefKind::Const { .. } => {
741-
// FIXME(const_generics_defaults): Figure out if this
742-
// is the behavior we want, see the comment further below.
743741
if is_our_default(&param) {
742+
// FIXME(const_generics_defaults): This
743+
// is incorrect when dealing with unused substs, for example
744+
// for `struct Foo<const N: usize, const M: usize = { 1 - 2 }>`
745+
// we should eagerly error.
744746
let default_ct = tcx.const_param_default(param.def_id);
745-
fcx.register_wf_obligation(
746-
default_ct.into(),
747-
tcx.def_span(param.def_id),
748-
ObligationCauseCode::MiscObligation,
749-
);
747+
if !default_ct.needs_subst() {
748+
fcx.register_wf_obligation(
749+
default_ct.into(),
750+
tcx.def_span(param.def_id),
751+
ObligationCauseCode::MiscObligation,
752+
);
753+
}
750754
}
751755
}
752756
// Doesn't have defaults.
@@ -783,14 +787,6 @@ fn check_where_clauses<'tcx, 'fcx>(
783787
tcx.mk_param_from_def(param)
784788
}
785789
GenericParamDefKind::Const { .. } => {
786-
// FIXME(const_generics_defaults): I(@lcnr) feel like always
787-
// using the const parameter is the right choice here, even
788-
// if it needs substs.
789-
//
790-
// Before stabilizing this we probably want to get some tests
791-
// where this makes a difference and figure out what's the exact
792-
// behavior we want here.
793-
794790
// If the param has a default, ...
795791
if is_our_default(param) {
796792
let default_ct = tcx.const_param_default(param.def_id);

compiler/rustc_typeck/src/collect.rs

+10
Original file line numberDiff line numberDiff line change
@@ -2308,6 +2308,16 @@ fn const_evaluatable_predicates_of<'tcx>(
23082308
));
23092309
}
23102310
}
2311+
2312+
fn visit_const_param_default(&mut self, _param: HirId, _ct: &'tcx hir::AnonConst) {
2313+
// Do not look into const param defaults,
2314+
// these get checked when they are actually instantiated.
2315+
//
2316+
// We do not want the following to error:
2317+
//
2318+
// struct Foo<const N: usize, const M: usize = { N + 1 }>;
2319+
// struct Bar<const N: usize>(Foo<N, 3>);
2320+
}
23112321
}
23122322

23132323
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// check-pass
2+
#![feature(const_generics, const_evaluatable_checked, const_generics_defaults)]
3+
#![allow(incomplete_features)]
4+
struct Foo<const N: usize, const M: usize = { N + 1 }>;
5+
struct Bar<const N: usize>(Foo<N, 3>);
6+
fn main() {}

src/test/ui/const-generics/defaults/complex-generic-default-expr.full.stderr

-18
This file was deleted.

src/test/ui/const-generics/defaults/complex-generic-default-expr.min.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: generic parameters may not be used in const operations
2-
--> $DIR/complex-generic-default-expr.rs:6:47
2+
--> $DIR/complex-generic-default-expr.rs:7:47
33
|
44
LL | struct Foo<const N: usize, const M: usize = { N + 1 }>;
55
| ^ cannot perform const operation using `N`
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
// revisions: full min
2+
//[full] check-pass
23
#![cfg_attr(full, feature(const_generics))]
34
#![feature(const_generics_defaults)]
45
#![allow(incomplete_features)]
56

67
struct Foo<const N: usize, const M: usize = { N + 1 }>;
7-
//[full]~^ ERROR constant expression depends on a generic parameter
8-
//[min]~^^ ERROR generic parameters may not be used in const operations
8+
//[min]~^ ERROR generic parameters may not be used in const operations
99

1010
struct Bar<T, const TYPE_SIZE: usize = { std::mem::size_of::<T>() }>(T);
11-
//[full]~^ ERROR constant expression depends on a generic parameter
12-
//[min]~^^ ERROR generic parameters may not be used in const operations
11+
//[min]~^ ERROR generic parameters may not be used in const operations
1312

1413
fn main() {}

0 commit comments

Comments
 (0)