about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbohan <bohan-zhang@foxmail.com>2023-12-23 15:57:24 +0800
committerbohan <bohan-zhang@foxmail.com>2023-12-26 16:10:29 +0800
commite16efbd23afe98d1bda104d850e0285591d3a5d8 (patch)
treee1443ff56e2edfb7cd6f73cbd812149fef373808
parent1ab783112ab4e4807304dbd249b39771246013ef (diff)
downloadrust-e16efbd23afe98d1bda104d850e0285591d3a5d8.tar.gz
rust-e16efbd23afe98d1bda104d850e0285591d3a5d8.zip
fallback `default` to `None` during ast-loweing for lifetime binder
-rw-r--r--compiler/rustc_ast_lowering/messages.ftl2
-rw-r--r--compiler/rustc_ast_lowering/src/errors.rs7
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs25
-rw-r--r--tests/ui/parser/issue-119042.rs7
-rw-r--r--tests/ui/traits/non_lifetime_binders/issue-118697.rs9
-rw-r--r--tests/ui/traits/non_lifetime_binders/issue-118697.stderr21
6 files changed, 69 insertions, 2 deletions
diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl
index 6bde4f2d8fa..5a1b1c799eb 100644
--- a/compiler/rustc_ast_lowering/messages.ftl
+++ b/compiler/rustc_ast_lowering/messages.ftl
@@ -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
 
diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs
index 11bb559719b..718a5b03cf2 100644
--- a/compiler/rustc_ast_lowering/src/errors.rs
+++ b/compiler/rustc_ast_lowering/src/errors.rs
@@ -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,
+}
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index e3954116288..243f278a520 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -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);
diff --git a/tests/ui/parser/issue-119042.rs b/tests/ui/parser/issue-119042.rs
new file mode 100644
index 00000000000..a4fee169d1c
--- /dev/null
+++ b/tests/ui/parser/issue-119042.rs
@@ -0,0 +1,7 @@
+// check-pass
+
+macro_rules! a { ($ty:ty) => {} }
+
+a! { for<T = &i32> fn() }
+
+fn main() {}
diff --git a/tests/ui/traits/non_lifetime_binders/issue-118697.rs b/tests/ui/traits/non_lifetime_binders/issue-118697.rs
new file mode 100644
index 00000000000..a282d0c5a40
--- /dev/null
+++ b/tests/ui/traits/non_lifetime_binders/issue-118697.rs
@@ -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() {}
diff --git a/tests/ui/traits/non_lifetime_binders/issue-118697.stderr b/tests/ui/traits/non_lifetime_binders/issue-118697.stderr
new file mode 100644
index 00000000000..52ce568d69d
--- /dev/null
+++ b/tests/ui/traits/non_lifetime_binders/issue-118697.stderr
@@ -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`.