From 3862095bd214a3ebdfb3fbaa4a13eac2ad8de331 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 20 Jul 2024 17:58:05 -0400 Subject: [PATCH] Just totally fully deny late-bound consts --- compiler/rustc_ast_passes/messages.ftl | 3 +++ compiler/rustc_ast_passes/src/errors.rs | 7 +++++++ compiler/rustc_ast_passes/src/feature_gate.rs | 16 ++++++++++++++++ .../src/collect/resolve_bound_vars.rs | 6 +----- compiler/rustc_resolve/src/late.rs | 6 +++++- tests/crashes/127009.rs | 11 ----------- tests/ui/closures/binder/const-bound.rs | 3 ++- tests/ui/closures/binder/const-bound.stderr | 8 +++++++- ...no-entry-found-for-key-ice-gce-nlb-113133.rs | 3 ++- ...ntry-found-for-key-ice-gce-nlb-113133.stderr | 8 +++++++- .../bad-suggestion-on-missing-assoc.rs | 3 ++- .../bad-suggestion-on-missing-assoc.stderr | 8 +++++++- .../binder-defaults-112547.rs | 5 +++-- .../binder-defaults-112547.stderr | 12 ++++++++++-- .../binder-defaults-119489.rs | 5 +++-- .../binder-defaults-119489.stderr | 8 +++++++- .../non_lifetime_binders/late-const-param-wf.rs | 11 +++++++++++ .../late-const-param-wf.stderr | 17 +++++++++++++++++ 18 files changed, 110 insertions(+), 30 deletions(-) delete mode 100644 tests/crashes/127009.rs create mode 100644 tests/ui/traits/non_lifetime_binders/late-const-param-wf.rs create mode 100644 tests/ui/traits/non_lifetime_binders/late-const-param-wf.stderr diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index 8f7dd77420709..ca0b7f2ac3a67 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -120,6 +120,9 @@ ast_passes_fn_without_body = ast_passes_forbidden_bound = bounds cannot be used in this context +ast_passes_forbidden_const_param = + late-bound const parameters cannot be used currently + ast_passes_forbidden_default = `default` is only allowed on items in trait impls .label = `default` because of this diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 783bca6b6958d..215ccd2ab4d9e 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -69,6 +69,13 @@ pub struct ForbiddenBound { pub spans: Vec, } +#[derive(Diagnostic)] +#[diag(ast_passes_forbidden_const_param)] +pub struct ForbiddenConstParam { + #[primary_span] + pub const_param_spans: Vec, +} + #[derive(Diagnostic)] #[diag(ast_passes_fn_param_too_many)] pub struct FnParamTooMany { diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 2178b65727d09..e91dfb2776662 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -162,6 +162,22 @@ impl<'a> PostExpansionVisitor<'a> { crate::fluent_generated::ast_passes_forbidden_non_lifetime_param ); + // FIXME(non_lifetime_binders): Const bound params are pretty broken. + // Let's keep users from using this feature accidentally. + if self.features.non_lifetime_binders { + let const_param_spans: Vec<_> = params + .iter() + .filter_map(|param| match param.kind { + ast::GenericParamKind::Const { .. } => Some(param.ident.span), + _ => None, + }) + .collect(); + + if !const_param_spans.is_empty() { + self.sess.dcx().emit_err(errors::ForbiddenConstParam { const_param_spans }); + } + } + for param in params { if !param.bounds.is_empty() { let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect(); diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 7930f54038daf..349dc9ad00ed3 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -2094,11 +2094,7 @@ pub fn deny_non_region_late_bound( format!("late-bound {what} parameter not allowed on {where_}"), ); - let guar = if tcx.features().non_lifetime_binders && first { - diag.emit() - } else { - diag.delay_as_bug() - }; + let guar = diag.emit_unless(!tcx.features().non_lifetime_binders || !first); first = false; *arg = ResolvedArg::Error(guar); diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index dc7200465d97e..51414d785963d 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2763,7 +2763,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { let res = match kind { RibKind::Item(..) | RibKind::AssocItem => Res::Def(def_kind, def_id.to_def_id()), RibKind::Normal => { - if self.r.tcx.features().non_lifetime_binders { + // FIXME(non_lifetime_binders): Stop special-casing + // const params to error out here. + if self.r.tcx.features().non_lifetime_binders + && matches!(param.kind, GenericParamKind::Type { .. }) + { Res::Def(def_kind, def_id.to_def_id()) } else { Res::Err diff --git a/tests/crashes/127009.rs b/tests/crashes/127009.rs deleted file mode 100644 index 74ca14393e4e9..0000000000000 --- a/tests/crashes/127009.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ known-bug: #127009 - -#![feature(non_lifetime_binders)] - -fn b() -where - for [(); C]: Copy, -{ -} - -fn main() {} diff --git a/tests/ui/closures/binder/const-bound.rs b/tests/ui/closures/binder/const-bound.rs index b1c79db137510..10d869fcc8512 100644 --- a/tests/ui/closures/binder/const-bound.rs +++ b/tests/ui/closures/binder/const-bound.rs @@ -3,5 +3,6 @@ fn main() { for || -> () {}; - //~^ ERROR late-bound const parameter not allowed on closures + //~^ ERROR late-bound const parameters cannot be used currently + //~| ERROR late-bound const parameter not allowed on closures } diff --git a/tests/ui/closures/binder/const-bound.stderr b/tests/ui/closures/binder/const-bound.stderr index 9c4fd95ed76ed..b805879f7fab5 100644 --- a/tests/ui/closures/binder/const-bound.stderr +++ b/tests/ui/closures/binder/const-bound.stderr @@ -1,3 +1,9 @@ +error: late-bound const parameters cannot be used currently + --> $DIR/const-bound.rs:5:15 + | +LL | for || -> () {}; + | ^ + warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/const-bound.rs:1:37 | @@ -13,5 +19,5 @@ error: late-bound const parameter not allowed on closures LL | for || -> () {}; | ^^^^^^^^^^^^ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/const-generics/generic_const_exprs/no-entry-found-for-key-ice-gce-nlb-113133.rs b/tests/ui/const-generics/generic_const_exprs/no-entry-found-for-key-ice-gce-nlb-113133.rs index 5673f1dd0738f..ffa9d960e048b 100644 --- a/tests/ui/const-generics/generic_const_exprs/no-entry-found-for-key-ice-gce-nlb-113133.rs +++ b/tests/ui/const-generics/generic_const_exprs/no-entry-found-for-key-ice-gce-nlb-113133.rs @@ -7,7 +7,8 @@ pub fn foo() where for ():, - //~^ ERROR defaults for generic parameters are not allowed in `for<...>` binders + //~^ ERROR late-bound const parameters cannot be used currently + //~| ERROR defaults for generic parameters are not allowed in `for<...>` binders {} fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/no-entry-found-for-key-ice-gce-nlb-113133.stderr b/tests/ui/const-generics/generic_const_exprs/no-entry-found-for-key-ice-gce-nlb-113133.stderr index 5924a673da944..814022f26b90f 100644 --- a/tests/ui/const-generics/generic_const_exprs/no-entry-found-for-key-ice-gce-nlb-113133.stderr +++ b/tests/ui/const-generics/generic_const_exprs/no-entry-found-for-key-ice-gce-nlb-113133.stderr @@ -1,8 +1,14 @@ +error: late-bound const parameters cannot be used currently + --> $DIR/no-entry-found-for-key-ice-gce-nlb-113133.rs:9:15 + | +LL | for ():, + | ^ + error: defaults for generic parameters are not allowed in `for<...>` binders --> $DIR/no-entry-found-for-key-ice-gce-nlb-113133.rs:9:9 | LL | for ():, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors diff --git a/tests/ui/traits/non_lifetime_binders/bad-suggestion-on-missing-assoc.rs b/tests/ui/traits/non_lifetime_binders/bad-suggestion-on-missing-assoc.rs index fc64381b961d4..b61a21eab419c 100644 --- a/tests/ui/traits/non_lifetime_binders/bad-suggestion-on-missing-assoc.rs +++ b/tests/ui/traits/non_lifetime_binders/bad-suggestion-on-missing-assoc.rs @@ -18,7 +18,8 @@ trait TraitC {} fn foo() where for T: TraitA>, - //~^ ERROR defaults for generic parameters are not allowed in `for<...>` binders + //~^ ERROR late-bound const parameters cannot be used currently + //~| ERROR defaults for generic parameters are not allowed in `for<...>` binders //~| ERROR `impl Trait` is not allowed in bounds { } diff --git a/tests/ui/traits/non_lifetime_binders/bad-suggestion-on-missing-assoc.stderr b/tests/ui/traits/non_lifetime_binders/bad-suggestion-on-missing-assoc.stderr index a4a79413a9be6..e891df3f0c092 100644 --- a/tests/ui/traits/non_lifetime_binders/bad-suggestion-on-missing-assoc.stderr +++ b/tests/ui/traits/non_lifetime_binders/bad-suggestion-on-missing-assoc.stderr @@ -1,3 +1,9 @@ +error: late-bound const parameters cannot be used currently + --> $DIR/bad-suggestion-on-missing-assoc.rs:20:15 + | +LL | for T: TraitA>, + | ^ + warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/bad-suggestion-on-missing-assoc.rs:1:12 | @@ -29,6 +35,6 @@ LL | for T: TraitA` binders (||1usize)() }> V: IntoIterator -//~^^^ ERROR defaults for generic parameters are not allowed in `for<...>` binders -//~^^ ERROR cannot find type `V` in this scope +//~^ ERROR cannot find type `V` in this scope { } diff --git a/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.stderr b/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.stderr index edc55a3c8e68f..d9e77dec794a7 100644 --- a/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.stderr +++ b/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.stderr @@ -1,5 +1,5 @@ error[E0412]: cannot find type `V` in this scope - --> $DIR/binder-defaults-112547.rs:8:4 + --> $DIR/binder-defaults-112547.rs:10:4 | LL | }> V: IntoIterator | ^ not found in this scope @@ -9,6 +9,12 @@ help: you might be missing a type parameter LL | pub fn bar() | +++ +error: late-bound const parameters cannot be used currently + --> $DIR/binder-defaults-112547.rs:6:15 + | +LL | for $DIR/binder-defaults-112547.rs:1:12 | @@ -23,10 +29,12 @@ error: defaults for generic parameters are not allowed in `for<...>` binders | LL | for V: IntoIterator | |_^ -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0412`. diff --git a/tests/ui/traits/non_lifetime_binders/binder-defaults-119489.rs b/tests/ui/traits/non_lifetime_binders/binder-defaults-119489.rs index f33da416ad8ae..bdfe41ca11b04 100644 --- a/tests/ui/traits/non_lifetime_binders/binder-defaults-119489.rs +++ b/tests/ui/traits/non_lifetime_binders/binder-defaults-119489.rs @@ -5,8 +5,9 @@ fn fun() where for ():, -//~^ ERROR defaults for generic parameters are not allowed in `for<...>` binders -//~| ERROR defaults for generic parameters are not allowed in `for<...>` binders + //~^ ERROR late-bound const parameters cannot be used currently + //~| ERROR defaults for generic parameters are not allowed in `for<...>` binders + //~| ERROR defaults for generic parameters are not allowed in `for<...>` binders {} fn main() {} diff --git a/tests/ui/traits/non_lifetime_binders/binder-defaults-119489.stderr b/tests/ui/traits/non_lifetime_binders/binder-defaults-119489.stderr index 7fe82f1f097c4..947dd3a73bf12 100644 --- a/tests/ui/traits/non_lifetime_binders/binder-defaults-119489.stderr +++ b/tests/ui/traits/non_lifetime_binders/binder-defaults-119489.stderr @@ -1,3 +1,9 @@ +error: late-bound const parameters cannot be used currently + --> $DIR/binder-defaults-119489.rs:7:23 + | +LL | for ():, + | ^ + warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/binder-defaults-119489.rs:1:12 | @@ -27,5 +33,5 @@ error: defaults for generic parameters are not allowed in `for<...>` binders LL | for ():, | ^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors; 2 warnings emitted +error: aborting due to 3 previous errors; 2 warnings emitted diff --git a/tests/ui/traits/non_lifetime_binders/late-const-param-wf.rs b/tests/ui/traits/non_lifetime_binders/late-const-param-wf.rs new file mode 100644 index 0000000000000..2d44388f875f9 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/late-const-param-wf.rs @@ -0,0 +1,11 @@ +#![feature(non_lifetime_binders)] +//~^ WARN the feature `non_lifetime_binders` is incomplete + +fn b() +where + for [(); C]: Copy, + //~^ ERROR late-bound const parameters cannot be used currently +{ +} + +fn main() {} diff --git a/tests/ui/traits/non_lifetime_binders/late-const-param-wf.stderr b/tests/ui/traits/non_lifetime_binders/late-const-param-wf.stderr new file mode 100644 index 0000000000000..136d533a03c40 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/late-const-param-wf.stderr @@ -0,0 +1,17 @@ +error: late-bound const parameters cannot be used currently + --> $DIR/late-const-param-wf.rs:6:15 + | +LL | for [(); C]: Copy, + | ^ + +warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/late-const-param-wf.rs:1:12 + | +LL | #![feature(non_lifetime_binders)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #108185 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: aborting due to 1 previous error; 1 warning emitted +