1
1
use std:: assert_matches:: assert_matches;
2
+ use std:: ops:: ControlFlow ;
2
3
3
4
use rustc_ast:: ptr:: P as AstP ;
4
5
use rustc_ast:: * ;
@@ -12,6 +13,7 @@ use rustc_span::source_map::{respan, Spanned};
12
13
use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
13
14
use rustc_span:: { DesugaringKind , Span , DUMMY_SP } ;
14
15
use thin_vec:: { thin_vec, ThinVec } ;
16
+ use visit:: { walk_expr, Visitor } ;
15
17
16
18
use super :: errors:: {
17
19
AsyncCoroutinesNotSupported , AwaitOnlyInAsyncFnAndBlocks , BaseExpressionDoubleDot ,
@@ -22,9 +24,32 @@ use super::errors::{
22
24
use super :: {
23
25
GenericArgsMode , ImplTraitContext , LoweringContext , ParamMode , ResolverAstLoweringExt ,
24
26
} ;
25
- use crate :: errors:: YieldInClosure ;
27
+ use crate :: errors:: { InvalidLegacyConstGenericArg , YieldInClosure } ;
26
28
use crate :: { fluent_generated, FnDeclKind , ImplTraitPosition } ;
27
29
30
+ struct WillCreateDefIdsVisitor { }
31
+
32
+ impl < ' v > rustc_ast:: visit:: Visitor < ' v > for WillCreateDefIdsVisitor {
33
+ type Result = ControlFlow < Span > ;
34
+
35
+ fn visit_anon_const ( & mut self , c : & ' v AnonConst ) -> Self :: Result {
36
+ ControlFlow :: Break ( c. value . span )
37
+ }
38
+
39
+ fn visit_item ( & mut self , item : & ' v Item ) -> Self :: Result {
40
+ ControlFlow :: Break ( item. span )
41
+ }
42
+
43
+ fn visit_expr ( & mut self , ex : & ' v Expr ) -> Self :: Result {
44
+ match ex. kind {
45
+ ExprKind :: Gen ( ..) | ExprKind :: ConstBlock ( ..) | ExprKind :: Closure ( ..) => {
46
+ ControlFlow :: Break ( ex. span )
47
+ }
48
+ _ => walk_expr ( self , ex) ,
49
+ }
50
+ }
51
+ }
52
+
28
53
impl < ' hir > LoweringContext < ' _ , ' hir > {
29
54
fn lower_exprs ( & mut self , exprs : & [ AstP < Expr > ] ) -> & ' hir [ hir:: Expr < ' hir > ] {
30
55
self . arena . alloc_from_iter ( exprs. iter ( ) . map ( |x| self . lower_expr_mut ( x) ) )
@@ -392,7 +417,22 @@ impl<'hir> LoweringContext<'_, 'hir> {
392
417
self . create_def ( parent_def_id, node_id, kw:: Empty , DefKind :: AnonConst , f. span ) ;
393
418
}
394
419
395
- let anon_const = AnonConst { id : node_id, value : arg } ;
420
+ let mut visitor = WillCreateDefIdsVisitor { } ;
421
+ let const_value = if let ControlFlow :: Break ( span) = visitor. visit_expr ( & arg) {
422
+ AstP ( Expr {
423
+ id : self . next_node_id ( ) ,
424
+ kind : ExprKind :: Err (
425
+ self . tcx . dcx ( ) . emit_err ( InvalidLegacyConstGenericArg { span } ) ,
426
+ ) ,
427
+ span : f. span ,
428
+ attrs : [ ] . into ( ) ,
429
+ tokens : None ,
430
+ } )
431
+ } else {
432
+ arg
433
+ } ;
434
+
435
+ let anon_const = AnonConst { id : node_id, value : const_value } ;
396
436
generic_args. push ( AngleBracketedArg :: Arg ( GenericArg :: Const ( anon_const) ) ) ;
397
437
} else {
398
438
real_args. push ( arg) ;
0 commit comments