From 3d0297a1e1b74ab50b97f78cf4fd056cb0ed51a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Mon, 1 Jan 2024 19:29:27 +0100 Subject: [PATCH] Deny defaults for higher-ranked generic parameters --- compiler/rustc_ast_lowering/messages.ftl | 5 +- compiler/rustc_ast_lowering/src/errors.rs | 4 +- compiler/rustc_ast_lowering/src/lib.rs | 70 +++++++++++-------- tests/ui/closures/issue-112547.rs | 15 ---- .../parser/generic-param-default-in-binder.rs | 10 +++ tests/ui/parser/issue-119042.rs | 7 -- .../binder-defaults-112547.rs | 16 +++++ .../binder-defaults-112547.stderr} | 15 +++- ...ue-118697.rs => binder-defaults-118697.rs} | 2 +- ...7.stderr => binder-defaults-118697.stderr} | 12 ++-- .../binder-defaults-119489.rs | 12 ++++ .../binder-defaults-119489.stderr | 31 ++++++++ 12 files changed, 133 insertions(+), 66 deletions(-) delete mode 100644 tests/ui/closures/issue-112547.rs create mode 100644 tests/ui/parser/generic-param-default-in-binder.rs delete mode 100644 tests/ui/parser/issue-119042.rs create mode 100644 tests/ui/traits/non_lifetime_binders/binder-defaults-112547.rs rename tests/ui/{closures/issue-112547.stderr => traits/non_lifetime_binders/binder-defaults-112547.stderr} (62%) rename tests/ui/traits/non_lifetime_binders/{issue-118697.rs => binder-defaults-118697.rs} (74%) rename tests/ui/traits/non_lifetime_binders/{issue-118697.stderr => binder-defaults-118697.stderr} (61%) create mode 100644 tests/ui/traits/non_lifetime_binders/binder-defaults-119489.rs create mode 100644 tests/ui/traits/non_lifetime_binders/binder-defaults-119489.stderr diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl index 5a1b1c799eb98..fd94e7e9341d4 100644 --- a/compiler/rustc_ast_lowering/messages.ftl +++ b/compiler/rustc_ast_lowering/messages.ftl @@ -45,8 +45,6 @@ ast_lowering_closure_cannot_be_static = closures cannot be static ast_lowering_coroutine_too_many_parameters = too many parameters for a coroutine (expected 0 or 1 parameters) -ast_lowering_default_parameter_in_binder = default parameter is not allowed in this binder - ast_lowering_does_not_support_modifiers = the `{$class_name}` register class does not support template modifiers @@ -58,6 +56,9 @@ ast_lowering_functional_record_update_destructuring_assignment = functional record updates are not allowed in destructuring assignments .suggestion = consider removing the trailing pattern +ast_lowering_generic_param_default_in_binder = + defaults for generic parameters are not allowed in `for<...>` binders + ast_lowering_generic_type_with_parentheses = parenthesized type parameters may only be used with a `Fn` trait .label = only `Fn` traits may use parentheses diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 718a5b03cf27b..710690d0d86a4 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -397,8 +397,8 @@ pub enum BadReturnTypeNotation { } #[derive(Diagnostic)] -#[diag(ast_lowering_default_parameter_in_binder)] -pub(crate) struct UnexpectedDefaultParameterInBinder { +#[diag(ast_lowering_generic_param_default_in_binder)] +pub(crate) struct GenericParamDefaultInBinder { #[primary_span] pub span: Span, } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 92fd29c47aff3..c7c77bf56b7b0 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -66,7 +66,6 @@ use rustc_session::parse::{add_feature_diagnostics, feature_err}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{DesugaringKind, Span, DUMMY_SP}; use smallvec::SmallVec; -use std::borrow::Cow; use std::collections::hash_map::Entry; use thin_vec::ThinVec; @@ -884,27 +883,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { binder: NodeId, generic_params: &[GenericParam], ) -> &'hir [hir::GenericParam<'hir>] { - let mut generic_params: Vec<_> = generic_params - .iter() - .map(|param| { - let param = match param.kind { - GenericParamKind::Type { ref default } if let Some(ty) = default => { - // Default type is not permitted in non-lifetime binders. - // So we emit an error and default to `None` to prevent - // potential ice. - self.dcx().emit_err(errors::UnexpectedDefaultParameterInBinder { - span: ty.span(), - }); - let param = GenericParam { - kind: GenericParamKind::Type { default: None }, - ..param.clone() - }; - Cow::Owned(param) - } - _ => Cow::Borrowed(param), - }; - self.lower_generic_param(param.as_ref(), hir::GenericParamSource::Binder) - }) + let mut generic_params: Vec<_> = self + .lower_generic_params_mut(generic_params, hir::GenericParamSource::Binder) .collect(); let extra_lifetimes = self.resolver.take_extra_lifetime_params(binder); debug!(?extra_lifetimes); @@ -2136,7 +2116,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { param: &GenericParam, source: hir::GenericParamSource, ) -> hir::GenericParam<'hir> { - let (name, kind) = self.lower_generic_param_kind(param); + let (name, kind) = self.lower_generic_param_kind(param, source); let hir_id = self.lower_node_id(param.id); self.lower_attrs(hir_id, ¶m.attrs); @@ -2155,6 +2135,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_generic_param_kind( &mut self, param: &GenericParam, + source: hir::GenericParamSource, ) -> (hir::ParamName, hir::GenericParamKind<'hir>) { match ¶m.kind { GenericParamKind::Lifetime => { @@ -2173,22 +2154,51 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { (param_name, kind) } GenericParamKind::Type { default, .. } => { - let kind = hir::GenericParamKind::Type { - default: default.as_ref().map(|x| { + // Not only do we deny type param defaults in binders but we also map them to `None` + // since later compiler stages cannot handle them (and shouldn't need to be able to). + let default = default + .as_ref() + .filter(|_| match source { + hir::GenericParamSource::Generics => true, + hir::GenericParamSource::Binder => { + self.dcx().emit_err(errors::GenericParamDefaultInBinder { + span: param.span(), + }); + + false + } + }) + .map(|def| { self.lower_ty( - x, + def, &ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault), ) - }), - synthetic: false, - }; + }); + + let kind = hir::GenericParamKind::Type { default, synthetic: false }; (hir::ParamName::Plain(self.lower_ident(param.ident)), kind) } GenericParamKind::Const { ty, kw_span: _, default } => { let ty = self .lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault)); - let default = default.as_ref().map(|def| self.lower_anon_const(def)); + + // Not only do we deny const param defaults in binders but we also map them to `None` + // since later compiler stages cannot handle them (and shouldn't need to be able to). + let default = default + .as_ref() + .filter(|_| match source { + hir::GenericParamSource::Generics => true, + hir::GenericParamSource::Binder => { + self.dcx().emit_err(errors::GenericParamDefaultInBinder { + span: param.span(), + }); + + false + } + }) + .map(|def| self.lower_anon_const(def)); + ( hir::ParamName::Plain(self.lower_ident(param.ident)), hir::GenericParamKind::Const { ty, default, is_host_effect: false }, diff --git a/tests/ui/closures/issue-112547.rs b/tests/ui/closures/issue-112547.rs deleted file mode 100644 index 8ecb2abccd4f9..0000000000000 --- a/tests/ui/closures/issue-112547.rs +++ /dev/null @@ -1,15 +0,0 @@ -#![feature(non_lifetime_binders)] - //~^ WARNING the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - -pub fn bar() -where - for V: IntoIterator -//~^ ERROR cannot find type `V` in this scope [E0412] -{ -} - -fn main() { - bar(); -} diff --git a/tests/ui/parser/generic-param-default-in-binder.rs b/tests/ui/parser/generic-param-default-in-binder.rs new file mode 100644 index 0000000000000..78dc4186b3a53 --- /dev/null +++ b/tests/ui/parser/generic-param-default-in-binder.rs @@ -0,0 +1,10 @@ +// Check that defaults for generic parameters in `for<...>` binders are +// syntactically valid. See also PR #119042. + +// check-pass + +macro_rules! a { ($ty:ty) => {} } + +a! { for fn() } + +fn main() {} diff --git a/tests/ui/parser/issue-119042.rs b/tests/ui/parser/issue-119042.rs deleted file mode 100644 index a4fee169d1cbc..0000000000000 --- a/tests/ui/parser/issue-119042.rs +++ /dev/null @@ -1,7 +0,0 @@ -// check-pass - -macro_rules! a { ($ty:ty) => {} } - -a! { for fn() } - -fn main() {} diff --git a/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.rs b/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.rs new file mode 100644 index 0000000000000..c6bf0dc1f720f --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.rs @@ -0,0 +1,16 @@ +#![feature(non_lifetime_binders)] +//~^ WARN the feature `non_lifetime_binders` is incomplete + +pub fn bar() +where + for V: IntoIterator +//~^^^ ERROR defaults for generic parameters are not allowed in `for<...>` binders +//~^^ ERROR cannot find type `V` in this scope +{ +} + +fn main() { + bar(); +} diff --git a/tests/ui/closures/issue-112547.stderr b/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.stderr similarity index 62% rename from tests/ui/closures/issue-112547.stderr rename to tests/ui/traits/non_lifetime_binders/binder-defaults-112547.stderr index f47ea60729763..edc55a3c8e68f 100644 --- a/tests/ui/closures/issue-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/issue-112547.rs:8:4 + --> $DIR/binder-defaults-112547.rs:8:4 | LL | }> V: IntoIterator | ^ not found in this scope @@ -10,7 +10,7 @@ LL | pub fn bar() | +++ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-112547.rs:1:12 + --> $DIR/binder-defaults-112547.rs:1:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ @@ -18,6 +18,15 @@ 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 +error: defaults for generic parameters are not allowed in `for<...>` binders + --> $DIR/binder-defaults-112547.rs:6:9 + | +LL | for V: IntoIterator + | |_^ + +error: aborting due to 2 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0412`. diff --git a/tests/ui/traits/non_lifetime_binders/issue-118697.rs b/tests/ui/traits/non_lifetime_binders/binder-defaults-118697.rs similarity index 74% rename from tests/ui/traits/non_lifetime_binders/issue-118697.rs rename to tests/ui/traits/non_lifetime_binders/binder-defaults-118697.rs index a282d0c5a40d9..2dc9fb98b153d 100644 --- a/tests/ui/traits/non_lifetime_binders/issue-118697.rs +++ b/tests/ui/traits/non_lifetime_binders/binder-defaults-118697.rs @@ -2,7 +2,7 @@ #![feature(non_lifetime_binders)] type T = dyn for Fn(()); -//~^ ERROR default parameter is not allowed in this binder +//~^ ERROR defaults for generic parameters are not allowed in `for<...>` binders //~| ERROR cannot find type `A` in this scope //~| ERROR late-bound type parameter not allowed on trait object types diff --git a/tests/ui/traits/non_lifetime_binders/issue-118697.stderr b/tests/ui/traits/non_lifetime_binders/binder-defaults-118697.stderr similarity index 61% rename from tests/ui/traits/non_lifetime_binders/issue-118697.stderr rename to tests/ui/traits/non_lifetime_binders/binder-defaults-118697.stderr index 52ce568d69ddc..6b93f52dbfcaa 100644 --- a/tests/ui/traits/non_lifetime_binders/issue-118697.stderr +++ b/tests/ui/traits/non_lifetime_binders/binder-defaults-118697.stderr @@ -1,20 +1,20 @@ error[E0412]: cannot find type `A` in this scope - --> $DIR/issue-118697.rs:4:22 + --> $DIR/binder-defaults-118697.rs:4:22 | LL | type T = dyn for Fn(()); | ^ not found in this scope -error: default parameter is not allowed in this binder - --> $DIR/issue-118697.rs:4:22 +error: defaults for generic parameters are not allowed in `for<...>` binders + --> $DIR/binder-defaults-118697.rs:4:18 | LL | type T = dyn for Fn(()); - | ^^^^^^ + | ^^^^^^^^^^ error: late-bound type parameter not allowed on trait object types - --> $DIR/issue-118697.rs:4:18 + --> $DIR/binder-defaults-118697.rs:4:18 | LL | type T = dyn for Fn(()); - | ^ + | ^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/tests/ui/traits/non_lifetime_binders/binder-defaults-119489.rs b/tests/ui/traits/non_lifetime_binders/binder-defaults-119489.rs new file mode 100644 index 0000000000000..f33da416ad8ae --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/binder-defaults-119489.rs @@ -0,0 +1,12 @@ +#![feature(non_lifetime_binders, generic_const_exprs)] +//~^ WARN the feature `non_lifetime_binders` is incomplete +//~| WARN the feature `generic_const_exprs` is incomplete + +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 +{} + +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 new file mode 100644 index 0000000000000..7fe82f1f097c4 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/binder-defaults-119489.stderr @@ -0,0 +1,31 @@ +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 + | +LL | #![feature(non_lifetime_binders, generic_const_exprs)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #108185 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/binder-defaults-119489.rs:1:34 + | +LL | #![feature(non_lifetime_binders, generic_const_exprs)] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #76560 for more information + +error: defaults for generic parameters are not allowed in `for<...>` binders + --> $DIR/binder-defaults-119489.rs:7:9 + | +LL | for ():, + | ^^^^^^ + +error: defaults for generic parameters are not allowed in `for<...>` binders + --> $DIR/binder-defaults-119489.rs:7:17 + | +LL | for ():, + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors; 2 warnings emitted +