From 4a53b115181a16d681dc05b312bbc913b7f836ac Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 8 Jul 2021 22:57:10 +0200 Subject: [PATCH] only check cg defaults wf once instantiated --- compiler/rustc_typeck/src/check/wfcheck.rs | 26 ++++++++----------- compiler/rustc_typeck/src/collect.rs | 10 +++++++ .../unused-complex-default-expr.rs | 6 +++++ .../complex-generic-default-expr.full.stderr | 18 ------------- .../complex-generic-default-expr.min.stderr | 2 +- .../defaults/complex-generic-default-expr.rs | 7 +++-- 6 files changed, 31 insertions(+), 38 deletions(-) create mode 100644 src/test/ui/const-generics/const_evaluatable_checked/unused-complex-default-expr.rs delete mode 100644 src/test/ui/const-generics/defaults/complex-generic-default-expr.full.stderr diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 0e063c86f2f4e..4838d70a83186 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -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(¶m) { + // FIXME(const_generics_defaults): This + // is incorrect when dealing with unused substs, for example + // for `struct Foo` + // 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. @@ -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); diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index b0e5453b7db92..583ba9392f062 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -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; + // struct Bar(Foo); + } } let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); diff --git a/src/test/ui/const-generics/const_evaluatable_checked/unused-complex-default-expr.rs b/src/test/ui/const-generics/const_evaluatable_checked/unused-complex-default-expr.rs new file mode 100644 index 0000000000000..21f14f58ab5af --- /dev/null +++ b/src/test/ui/const-generics/const_evaluatable_checked/unused-complex-default-expr.rs @@ -0,0 +1,6 @@ +// check-pass +#![feature(const_generics, const_evaluatable_checked, const_generics_defaults)] +#![allow(incomplete_features)] +struct Foo; +struct Bar(Foo); +fn main() {} diff --git a/src/test/ui/const-generics/defaults/complex-generic-default-expr.full.stderr b/src/test/ui/const-generics/defaults/complex-generic-default-expr.full.stderr deleted file mode 100644 index e0e2b6c69f280..0000000000000 --- a/src/test/ui/const-generics/defaults/complex-generic-default-expr.full.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error: constant expression depends on a generic parameter - --> $DIR/complex-generic-default-expr.rs:6:34 - | -LL | struct Foo; - | ^ - | - = note: this may fail depending on what value the parameter takes - -error: constant expression depends on a generic parameter - --> $DIR/complex-generic-default-expr.rs:10:21 - | -LL | struct Bar() }>(T); - | ^^^^^^^^^ - | - = note: this may fail depending on what value the parameter takes - -error: aborting due to 2 previous errors - diff --git a/src/test/ui/const-generics/defaults/complex-generic-default-expr.min.stderr b/src/test/ui/const-generics/defaults/complex-generic-default-expr.min.stderr index 58abd8db9f09f..44df2ac9f40fa 100644 --- a/src/test/ui/const-generics/defaults/complex-generic-default-expr.min.stderr +++ b/src/test/ui/const-generics/defaults/complex-generic-default-expr.min.stderr @@ -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; | ^ cannot perform const operation using `N` diff --git a/src/test/ui/const-generics/defaults/complex-generic-default-expr.rs b/src/test/ui/const-generics/defaults/complex-generic-default-expr.rs index a7b712f7b4b86..d3558007977e4 100644 --- a/src/test/ui/const-generics/defaults/complex-generic-default-expr.rs +++ b/src/test/ui/const-generics/defaults/complex-generic-default-expr.rs @@ -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; -//[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); -//[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() {}