Skip to content

Commit

Permalink
Auto merge of rust-lang#86987 - lcnr:const-default-eval-bound, r=oli-obk
Browse files Browse the repository at this point in the history
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`
  • Loading branch information
bors committed Jul 10, 2021
2 parents 8eae2eb + 4a53b11 commit a84d1b2
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 38 deletions.
26 changes: 11 additions & 15 deletions compiler/rustc_typeck/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -738,15 +738,19 @@ fn check_where_clauses<'tcx, 'fcx>(
}
}
GenericParamDefKind::Const { .. } => {
// FIXME(const_generics_defaults): Figure out if this
// is the behavior we want, see the comment further below.
if is_our_default(&param) {
// FIXME(const_generics_defaults): This
// is incorrect when dealing with unused substs, for example
// for `struct Foo<const N: usize, const M: usize = { 1 - 2 }>`
// we should eagerly error.
let default_ct = tcx.const_param_default(param.def_id);
fcx.register_wf_obligation(
default_ct.into(),
tcx.def_span(param.def_id),
ObligationCauseCode::MiscObligation,
);
if !default_ct.needs_subst() {
fcx.register_wf_obligation(
default_ct.into(),
tcx.def_span(param.def_id),
ObligationCauseCode::MiscObligation,
);
}
}
}
// Doesn't have defaults.
Expand Down Expand Up @@ -783,14 +787,6 @@ fn check_where_clauses<'tcx, 'fcx>(
tcx.mk_param_from_def(param)
}
GenericParamDefKind::Const { .. } => {
// FIXME(const_generics_defaults): I(@lcnr) feel like always
// using the const parameter is the right choice here, even
// if it needs substs.
//
// Before stabilizing this we probably want to get some tests
// where this makes a difference and figure out what's the exact
// behavior we want here.

// If the param has a default, ...
if is_our_default(param) {
let default_ct = tcx.const_param_default(param.def_id);
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_typeck/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2308,6 +2308,16 @@ fn const_evaluatable_predicates_of<'tcx>(
));
}
}

fn visit_const_param_default(&mut self, _param: HirId, _ct: &'tcx hir::AnonConst) {
// Do not look into const param defaults,
// these get checked when they are actually instantiated.
//
// We do not want the following to error:
//
// struct Foo<const N: usize, const M: usize = { N + 1 }>;
// struct Bar<const N: usize>(Foo<N, 3>);
}
}

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

This file was deleted.

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

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

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

fn main() {}

0 comments on commit a84d1b2

Please sign in to comment.