@@ -8,6 +8,7 @@ use super::{
8
8
9
9
use crate :: errors;
10
10
use crate :: maybe_recover_from_interpolated_ty_qpath;
11
+ use ast:: { Path , PathSegment } ;
11
12
use core:: mem;
12
13
use rustc_ast:: ptr:: P ;
13
14
use rustc_ast:: token:: { self , Delimiter , Token , TokenKind } ;
@@ -29,6 +30,7 @@ use rustc_session::errors::{report_lit_error, ExprParenthesesNeeded};
29
30
use rustc_session:: lint:: builtin:: BREAK_WITH_LABEL_AND_LOOP ;
30
31
use rustc_session:: lint:: BuiltinLintDiagnostics ;
31
32
use rustc_span:: source_map:: { self , Span , Spanned } ;
33
+ use rustc_span:: symbol:: kw:: PathRoot ;
32
34
use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
33
35
use rustc_span:: { BytePos , Pos } ;
34
36
use thin_vec:: { thin_vec, ThinVec } ;
@@ -607,6 +609,9 @@ impl<'a> Parser<'a> {
607
609
let operand_expr = this. parse_expr_dot_or_call ( Default :: default ( ) ) ?;
608
610
this. recover_from_prefix_increment ( operand_expr, pre_span, starts_stmt)
609
611
}
612
+ token:: Ident ( ..) if this. token . is_keyword ( kw:: Box ) => {
613
+ make_it ! ( this, attrs, |this, _| this. parse_expr_box( lo) )
614
+ }
610
615
token:: Ident ( ..) if this. may_recover ( ) && this. is_mistaken_not_ident_negation ( ) => {
611
616
make_it ! ( this, attrs, |this, _| this. recover_not_expr( lo) )
612
617
}
@@ -633,6 +638,29 @@ impl<'a> Parser<'a> {
633
638
self . parse_expr_unary ( lo, UnOp :: Not )
634
639
}
635
640
641
+ /// Parse `box expr` - this syntax has been removed, but we still parse this
642
+ /// for now to provide an automated way to fix usages of it
643
+ fn parse_expr_box ( & mut self , lo : Span ) -> PResult < ' a , ( Span , ExprKind ) > {
644
+ let ( span, expr) = self . parse_expr_prefix_common ( lo) ?;
645
+ let code = self . sess . source_map ( ) . span_to_snippet ( span. with_lo ( lo. hi ( ) ) ) . unwrap ( ) ;
646
+ self . sess . emit_err ( errors:: BoxSyntaxRemoved { span, code : code. trim ( ) } ) ;
647
+ // So typechecking works, parse `box <expr>` as `::std::boxed::Box::new(expr)`
648
+ let path = Path {
649
+ span,
650
+ segments : [
651
+ PathSegment :: from_ident ( Ident :: with_dummy_span ( PathRoot ) ) ,
652
+ PathSegment :: from_ident ( Ident :: with_dummy_span ( sym:: std) ) ,
653
+ PathSegment :: from_ident ( Ident :: from_str ( "boxed" ) ) ,
654
+ PathSegment :: from_ident ( Ident :: from_str ( "Box" ) ) ,
655
+ PathSegment :: from_ident ( Ident :: with_dummy_span ( sym:: new) ) ,
656
+ ]
657
+ . into ( ) ,
658
+ tokens : None ,
659
+ } ;
660
+ let path = self . mk_expr ( span, ExprKind :: Path ( None , path) ) ;
661
+ Ok ( ( span, self . mk_call ( path, ThinVec :: from ( [ expr] ) ) ) )
662
+ }
663
+
636
664
fn is_mistaken_not_ident_negation ( & self ) -> bool {
637
665
let token_cannot_continue_expr = |t : & Token | match t. uninterpolate ( ) . kind {
638
666
// These tokens can start an expression after `!`, but
0 commit comments