From 638fbff33c88525d6318fc04357b4e6bd5dd8571 Mon Sep 17 00:00:00 2001 From: mu001999 Date: Tue, 31 Mar 2026 22:32:02 +0800 Subject: [PATCH] Emit fatal on defaults for generic params in binders if with nested defs --- compiler/rustc_ast_lowering/src/expr.rs | 26 +++++++++---------- compiler/rustc_ast_lowering/src/lib.rs | 19 +++++++++----- tests/crashes/123629.rs | 10 ------- ...ults-for-generic-param-in-binder-123629.rs | 12 +++++++++ ...-for-generic-param-in-binder-123629.stderr | 26 +++++++++++++++++++ 5 files changed, 63 insertions(+), 30 deletions(-) delete mode 100644 tests/crashes/123629.rs create mode 100644 tests/ui/const-generics/generic_const_exprs/bad-defaults-for-generic-param-in-binder-123629.rs create mode 100644 tests/ui/const-generics/generic_const_exprs/bad-defaults-for-generic-param-in-binder-123629.stderr diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index b6bc122051cbc..e0ec8ba3dcb9d 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -29,7 +29,7 @@ use super::{ use crate::errors::{InvalidLegacyConstGenericArg, UseConstGenericArg, YieldInClosure}; use crate::{AllowReturnTypeNotation, FnDeclKind, ImplTraitPosition, TryBlockScope}; -struct WillCreateDefIdsVisitor {} +pub(super) struct WillCreateDefIdsVisitor; impl<'v> rustc_ast::visit::Visitor<'v> for WillCreateDefIdsVisitor { type Result = ControlFlow; @@ -479,18 +479,18 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { DefPathData::LateAnonConst, f.span, ); - let mut visitor = WillCreateDefIdsVisitor {}; - let const_value = if let ControlFlow::Break(span) = visitor.visit_expr(&arg) { - Box::new(Expr { - id: self.next_node_id(), - kind: ExprKind::Err(invalid_expr_error(self.tcx, span)), - span: f.span, - attrs: [].into(), - tokens: None, - }) - } else { - arg - }; + let const_value = + if let ControlFlow::Break(span) = WillCreateDefIdsVisitor.visit_expr(&arg) { + Box::new(Expr { + id: self.next_node_id(), + kind: ExprKind::Err(invalid_expr_error(self.tcx, span)), + span: f.span, + attrs: [].into(), + tokens: None, + }) + } else { + arg + }; let anon_const = AnonConst { id: node_id, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 5db86d2e879c1..10fdb4e01d0ab 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -39,7 +39,7 @@ use std::mem; use std::sync::Arc; use rustc_ast::node_id::NodeMap; -use rustc_ast::visit::AssocCtxt; +use rustc_ast::visit::{AssocCtxt, Visitor}; use rustc_ast::{self as ast, *}; use rustc_attr_parsing::{AttributeParser, Late, OmitDoc}; use rustc_data_structures::fingerprint::Fingerprint; @@ -2236,14 +2236,19 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { // since later compiler stages cannot handle them (and shouldn't need to be able to). let default = default .as_ref() - .filter(|_| match source { + .filter(|anon_const| match source { hir::GenericParamSource::Generics => true, hir::GenericParamSource::Binder => { - self.dcx().emit_err(errors::GenericParamDefaultInBinder { - span: param.span(), - }); - - false + let err = errors::GenericParamDefaultInBinder { span: param.span() }; + if expr::WillCreateDefIdsVisitor + .visit_expr(&anon_const.value) + .is_break() + { + self.dcx().emit_fatal(err) + } else { + self.dcx().emit_err(err); + false + } } }) .map(|def| self.lower_anon_const_to_const_arg_and_alloc(def)); diff --git a/tests/crashes/123629.rs b/tests/crashes/123629.rs deleted file mode 100644 index 615323218067d..0000000000000 --- a/tests/crashes/123629.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ known-bug: #123629 -#![feature(generic_assert)] - -fn foo() -where - for ():, -{ -} - -fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/bad-defaults-for-generic-param-in-binder-123629.rs b/tests/ui/const-generics/generic_const_exprs/bad-defaults-for-generic-param-in-binder-123629.rs new file mode 100644 index 0000000000000..c45f59a8d896e --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/bad-defaults-for-generic-param-in-binder-123629.rs @@ -0,0 +1,12 @@ +#![feature(generic_assert)] + +fn foo() +where + for ():, + //~^ ERROR cannot find value `u` in this scope + //~^^ ERROR only lifetime parameters can be used in this context + //~^^^ ERROR defaults for generic parameters are not allowed in `for<...>` binders +{ +} + +fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/bad-defaults-for-generic-param-in-binder-123629.stderr b/tests/ui/const-generics/generic_const_exprs/bad-defaults-for-generic-param-in-binder-123629.stderr new file mode 100644 index 0000000000000..9092c83d95121 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/bad-defaults-for-generic-param-in-binder-123629.stderr @@ -0,0 +1,26 @@ +error[E0425]: cannot find value `u` in this scope + --> $DIR/bad-defaults-for-generic-param-in-binder-123629.rs:5:36 + | +LL | for ():, + | ^ not found in this scope + +error[E0658]: only lifetime parameters can be used in this context + --> $DIR/bad-defaults-for-generic-param-in-binder-123629.rs:5:15 + | +LL | for ():, + | ^ + | + = note: see issue #108185 for more information + = help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: defaults for generic parameters are not allowed in `for<...>` binders + --> $DIR/bad-defaults-for-generic-param-in-binder-123629.rs:5:9 + | +LL | for ():, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0425, E0658. +For more information about an error, try `rustc --explain E0425`.