fallback `default` to `None` during ast-loweing for lifetime binder

This commit is contained in:
bohan 2023-12-23 15:57:24 +08:00
parent 1ab783112a
commit e16efbd23a
6 changed files with 69 additions and 2 deletions

View File

@ -45,6 +45,8 @@ 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

View File

@ -395,3 +395,10 @@ pub enum BadReturnTypeNotation {
span: Span,
},
}
#[derive(Diagnostic)]
#[diag(ast_lowering_default_parameter_in_binder)]
pub(crate) struct UnexpectedDefaultParameterInBinder {
#[primary_span]
pub span: Span,
}

View File

@ -33,6 +33,7 @@
#![allow(internal_features)]
#![feature(rustdoc_internals)]
#![doc(rust_logo)]
#![feature(if_let_guard)]
#![feature(box_patterns)]
#![feature(let_chains)]
#![recursion_limit = "256"]
@ -65,6 +66,7 @@ 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;
@ -878,8 +880,27 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
binder: NodeId,
generic_params: &[GenericParam],
) -> &'hir [hir::GenericParam<'hir>] {
let mut generic_params: Vec<_> = self
.lower_generic_params_mut(generic_params, hir::GenericParamSource::Binder)
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)
})
.collect();
let extra_lifetimes = self.resolver.take_extra_lifetime_params(binder);
debug!(?extra_lifetimes);

View File

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

View File

@ -0,0 +1,9 @@
#![allow(incomplete_features)]
#![feature(non_lifetime_binders)]
type T = dyn for<V = A(&())> Fn(());
//~^ ERROR default parameter is not allowed in this binder
//~| ERROR cannot find type `A` in this scope
//~| ERROR late-bound type parameter not allowed on trait object types
fn main() {}

View File

@ -0,0 +1,21 @@
error[E0412]: cannot find type `A` in this scope
--> $DIR/issue-118697.rs:4:22
|
LL | type T = dyn for<V = A(&())> Fn(());
| ^ not found in this scope
error: default parameter is not allowed in this binder
--> $DIR/issue-118697.rs:4:22
|
LL | type T = dyn for<V = A(&())> Fn(());
| ^^^^^^
error: late-bound type parameter not allowed on trait object types
--> $DIR/issue-118697.rs:4:18
|
LL | type T = dyn for<V = A(&())> Fn(());
| ^
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0412`.