Rollup merge of #119494 - fmease:deny-hr-param-defaults, r=compiler-errors

Deny defaults for higher-ranked generic parameters

Fixes #119489 (incl. https://github.com/rust-lang/rust/issues/119489#issuecomment-1873399208).
Partially reverts #119042.

cc ```@bvanjoi```
r? ```@compiler-errors``` or compiler
This commit is contained in:
León Orell Valerian Liehr 2024-01-03 16:08:29 +01:00 committed by GitHub
commit b5618bc222
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 133 additions and 66 deletions

View File

@ -45,8 +45,6 @@ ast_lowering_closure_cannot_be_static = closures cannot be static
ast_lowering_coroutine_too_many_parameters = ast_lowering_coroutine_too_many_parameters =
too many parameters for a coroutine (expected 0 or 1 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 = ast_lowering_does_not_support_modifiers =
the `{$class_name}` register class does not support template 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 functional record updates are not allowed in destructuring assignments
.suggestion = consider removing the trailing pattern .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 = ast_lowering_generic_type_with_parentheses =
parenthesized type parameters may only be used with a `Fn` trait parenthesized type parameters may only be used with a `Fn` trait
.label = only `Fn` traits may use parentheses .label = only `Fn` traits may use parentheses

View File

@ -397,8 +397,8 @@ pub enum BadReturnTypeNotation {
} }
#[derive(Diagnostic)] #[derive(Diagnostic)]
#[diag(ast_lowering_default_parameter_in_binder)] #[diag(ast_lowering_generic_param_default_in_binder)]
pub(crate) struct UnexpectedDefaultParameterInBinder { pub(crate) struct GenericParamDefaultInBinder {
#[primary_span] #[primary_span]
pub span: Span, pub span: Span,
} }

View File

@ -66,7 +66,6 @@ use rustc_session::parse::{add_feature_diagnostics, feature_err};
use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{DesugaringKind, Span, DUMMY_SP}; use rustc_span::{DesugaringKind, Span, DUMMY_SP};
use smallvec::SmallVec; use smallvec::SmallVec;
use std::borrow::Cow;
use std::collections::hash_map::Entry; use std::collections::hash_map::Entry;
use thin_vec::ThinVec; use thin_vec::ThinVec;
@ -884,27 +883,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
binder: NodeId, binder: NodeId,
generic_params: &[GenericParam], generic_params: &[GenericParam],
) -> &'hir [hir::GenericParam<'hir>] { ) -> &'hir [hir::GenericParam<'hir>] {
let mut generic_params: Vec<_> = generic_params let mut generic_params: Vec<_> = self
.iter() .lower_generic_params_mut(generic_params, hir::GenericParamSource::Binder)
.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)
})
.collect(); .collect();
let extra_lifetimes = self.resolver.take_extra_lifetime_params(binder); let extra_lifetimes = self.resolver.take_extra_lifetime_params(binder);
debug!(?extra_lifetimes); debug!(?extra_lifetimes);
@ -2136,7 +2116,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
param: &GenericParam, param: &GenericParam,
source: hir::GenericParamSource, source: hir::GenericParamSource,
) -> hir::GenericParam<'hir> { ) -> 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); let hir_id = self.lower_node_id(param.id);
self.lower_attrs(hir_id, &param.attrs); self.lower_attrs(hir_id, &param.attrs);
@ -2155,6 +2135,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_generic_param_kind( fn lower_generic_param_kind(
&mut self, &mut self,
param: &GenericParam, param: &GenericParam,
source: hir::GenericParamSource,
) -> (hir::ParamName, hir::GenericParamKind<'hir>) { ) -> (hir::ParamName, hir::GenericParamKind<'hir>) {
match &param.kind { match &param.kind {
GenericParamKind::Lifetime => { GenericParamKind::Lifetime => {
@ -2173,22 +2154,51 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
(param_name, kind) (param_name, kind)
} }
GenericParamKind::Type { default, .. } => { GenericParamKind::Type { default, .. } => {
let kind = hir::GenericParamKind::Type { // Not only do we deny type param defaults in binders but we also map them to `None`
default: default.as_ref().map(|x| { // 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( self.lower_ty(
x, def,
&ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault), &ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault),
) )
}), });
synthetic: false,
}; let kind = hir::GenericParamKind::Type { default, synthetic: false };
(hir::ParamName::Plain(self.lower_ident(param.ident)), kind) (hir::ParamName::Plain(self.lower_ident(param.ident)), kind)
} }
GenericParamKind::Const { ty, kw_span: _, default } => { GenericParamKind::Const { ty, kw_span: _, default } => {
let ty = self let ty = self
.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault)); .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::ParamName::Plain(self.lower_ident(param.ident)),
hir::GenericParamKind::Const { ty, default, is_host_effect: false }, hir::GenericParamKind::Const { ty, default, is_host_effect: false },

View File

@ -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<const N: usize = {
(||1usize)()
}> V: IntoIterator
//~^ ERROR cannot find type `V` in this scope [E0412]
{
}
fn main() {
bar();
}

View File

@ -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<T = &i32> fn() }
fn main() {}

View File

@ -1,7 +0,0 @@
// check-pass
macro_rules! a { ($ty:ty) => {} }
a! { for<T = &i32> fn() }
fn main() {}

View File

@ -0,0 +1,16 @@
#![feature(non_lifetime_binders)]
//~^ WARN the feature `non_lifetime_binders` is incomplete
pub fn bar()
where
for<const N: usize = {
(||1usize)()
}> V: IntoIterator
//~^^^ ERROR defaults for generic parameters are not allowed in `for<...>` binders
//~^^ ERROR cannot find type `V` in this scope
{
}
fn main() {
bar();
}

View File

@ -1,5 +1,5 @@
error[E0412]: cannot find type `V` in this scope 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 LL | }> V: IntoIterator
| ^ not found in this scope | ^ not found in this scope
@ -10,7 +10,7 @@ LL | pub fn bar<V>()
| +++ | +++
warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes 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)] LL | #![feature(non_lifetime_binders)]
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -18,6 +18,15 @@ LL | #![feature(non_lifetime_binders)]
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
= note: `#[warn(incomplete_features)]` on by default = 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<const N: usize = {
| _________^
LL | | (||1usize)()
LL | | }> V: IntoIterator
| |_^
error: aborting due to 2 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0412`. For more information about this error, try `rustc --explain E0412`.

View File

@ -2,7 +2,7 @@
#![feature(non_lifetime_binders)] #![feature(non_lifetime_binders)]
type T = dyn for<V = A(&())> Fn(()); type T = dyn for<V = A(&())> 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 cannot find type `A` in this scope
//~| ERROR late-bound type parameter not allowed on trait object types //~| ERROR late-bound type parameter not allowed on trait object types

View File

@ -1,20 +1,20 @@
error[E0412]: cannot find type `A` in this scope 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<V = A(&())> Fn(()); LL | type T = dyn for<V = A(&())> Fn(());
| ^ not found in this scope | ^ not found in this scope
error: default parameter is not allowed in this binder error: defaults for generic parameters are not allowed in `for<...>` binders
--> $DIR/issue-118697.rs:4:22 --> $DIR/binder-defaults-118697.rs:4:18
| |
LL | type T = dyn for<V = A(&())> Fn(()); LL | type T = dyn for<V = A(&())> Fn(());
| ^^^^^^ | ^^^^^^^^^^
error: late-bound type parameter not allowed on trait object types 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<V = A(&())> Fn(()); LL | type T = dyn for<V = A(&())> Fn(());
| ^ | ^^^^^^^^^^
error: aborting due to 3 previous errors error: aborting due to 3 previous errors

View File

@ -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<T = (), const N: usize = 1> ():,
//~^ ERROR defaults for generic parameters are not allowed in `for<...>` binders
//~| ERROR defaults for generic parameters are not allowed in `for<...>` binders
{}
fn main() {}

View File

@ -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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/76560> for more information
error: defaults for generic parameters are not allowed in `for<...>` binders
--> $DIR/binder-defaults-119489.rs:7:9
|
LL | for<T = (), const N: usize = 1> ():,
| ^^^^^^
error: defaults for generic parameters are not allowed in `for<...>` binders
--> $DIR/binder-defaults-119489.rs:7:17
|
LL | for<T = (), const N: usize = 1> ():,
| ^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors; 2 warnings emitted