Auto merge of #51052 - nikomatsakis:obsolete-arrow, r=petrochenkov
restore emplacement syntax (obsolete) Fix https://github.com/rust-lang/rust/issues/50832 r? @petrochenkov
This commit is contained in:
commit
1594c6c650
11 changed files with 98 additions and 6 deletions
|
@ -2906,7 +2906,10 @@ impl<'a> LoweringContext<'a> {
|
|||
fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
|
||||
let kind = match e.node {
|
||||
ExprKind::Box(ref inner) => hir::ExprBox(P(self.lower_expr(inner))),
|
||||
|
||||
ExprKind::ObsoleteInPlace(..) => {
|
||||
self.sess.abort_if_errors();
|
||||
span_bug!(e.span, "encountered ObsoleteInPlace expr during lowering");
|
||||
}
|
||||
ExprKind::Array(ref exprs) => {
|
||||
hir::ExprArray(exprs.iter().map(|x| self.lower_expr(x)).collect())
|
||||
}
|
||||
|
|
|
@ -172,6 +172,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
ExprKind::InlineAsm(..) if !self.session.target.target.options.allow_asm => {
|
||||
span_err!(self.session, expr.span, E0472, "asm! is unsupported on this target");
|
||||
}
|
||||
ExprKind::ObsoleteInPlace(..) => {
|
||||
self.err_handler()
|
||||
.struct_span_err(expr.span, "emplacement syntax is obsolete (for now, anyway)")
|
||||
.note("for more information, see \
|
||||
<https://github.com/rust-lang/rust/issues/27779#issuecomment-378416911>")
|
||||
.emit();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
|
|
@ -1010,6 +1010,7 @@ impl Expr {
|
|||
pub fn precedence(&self) -> ExprPrecedence {
|
||||
match self.node {
|
||||
ExprKind::Box(_) => ExprPrecedence::Box,
|
||||
ExprKind::ObsoleteInPlace(..) => ExprPrecedence::ObsoleteInPlace,
|
||||
ExprKind::Array(_) => ExprPrecedence::Array,
|
||||
ExprKind::Call(..) => ExprPrecedence::Call,
|
||||
ExprKind::MethodCall(..) => ExprPrecedence::MethodCall,
|
||||
|
@ -1068,6 +1069,8 @@ pub enum RangeLimits {
|
|||
pub enum ExprKind {
|
||||
/// A `box x` expression.
|
||||
Box(P<Expr>),
|
||||
/// First expr is the place; second expr is the value.
|
||||
ObsoleteInPlace(P<Expr>, P<Expr>),
|
||||
/// An array (`[a, b, c, d]`)
|
||||
Array(Vec<P<Expr>>),
|
||||
/// A function call
|
||||
|
|
|
@ -1690,6 +1690,9 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
|||
gate_feature_post!(&self, type_ascription, e.span,
|
||||
"type ascription is experimental");
|
||||
}
|
||||
ast::ExprKind::ObsoleteInPlace(..) => {
|
||||
// these get a hard error in ast-validation
|
||||
}
|
||||
ast::ExprKind::Yield(..) => {
|
||||
gate_feature_post!(&self, generators,
|
||||
e.span,
|
||||
|
|
|
@ -1194,6 +1194,9 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu
|
|||
ExprKind::Box(e) => {
|
||||
ExprKind::Box(folder.fold_expr(e))
|
||||
}
|
||||
ExprKind::ObsoleteInPlace(a, b) => {
|
||||
ExprKind::ObsoleteInPlace(folder.fold_expr(a), folder.fold_expr(b))
|
||||
}
|
||||
ExprKind::Array(exprs) => {
|
||||
ExprKind::Array(folder.fold_exprs(exprs))
|
||||
}
|
||||
|
|
|
@ -2839,6 +2839,17 @@ impl<'a> Parser<'a> {
|
|||
let (span, e) = self.interpolated_or_expr_span(e)?;
|
||||
(lo.to(span), ExprKind::AddrOf(m, e))
|
||||
}
|
||||
token::Ident(..) if self.token.is_keyword(keywords::In) => {
|
||||
self.bump();
|
||||
let place = self.parse_expr_res(
|
||||
Restrictions::NO_STRUCT_LITERAL,
|
||||
None,
|
||||
)?;
|
||||
let blk = self.parse_block()?;
|
||||
let span = blk.span;
|
||||
let blk_expr = self.mk_expr(span, ExprKind::Block(blk, None), ThinVec::new());
|
||||
(lo.to(span), ExprKind::ObsoleteInPlace(place, blk_expr))
|
||||
}
|
||||
token::Ident(..) if self.token.is_keyword(keywords::Box) => {
|
||||
self.bump();
|
||||
let e = self.parse_prefix_expr(None);
|
||||
|
@ -3042,6 +3053,8 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
AssocOp::Assign =>
|
||||
self.mk_expr(span, ExprKind::Assign(lhs, rhs), ThinVec::new()),
|
||||
AssocOp::ObsoleteInPlace =>
|
||||
self.mk_expr(span, ExprKind::ObsoleteInPlace(lhs, rhs), ThinVec::new()),
|
||||
AssocOp::AssignOp(k) => {
|
||||
let aop = match k {
|
||||
token::Plus => BinOpKind::Add,
|
||||
|
|
|
@ -2057,6 +2057,13 @@ impl<'a> State<'a> {
|
|||
self.word_space("box")?;
|
||||
self.print_expr_maybe_paren(expr, parser::PREC_PREFIX)?;
|
||||
}
|
||||
ast::ExprKind::ObsoleteInPlace(ref place, ref expr) => {
|
||||
let prec = AssocOp::ObsoleteInPlace.precedence() as i8;
|
||||
self.print_expr_maybe_paren(place, prec + 1)?;
|
||||
self.s.space()?;
|
||||
self.word_space("<-")?;
|
||||
self.print_expr_maybe_paren(expr, prec)?;
|
||||
}
|
||||
ast::ExprKind::Array(ref exprs) => {
|
||||
self.print_expr_vec(&exprs[..], attrs)?;
|
||||
}
|
||||
|
|
|
@ -56,6 +56,8 @@ pub enum AssocOp {
|
|||
GreaterEqual,
|
||||
/// `=`
|
||||
Assign,
|
||||
/// `<-`
|
||||
ObsoleteInPlace,
|
||||
/// `?=` where ? is one of the BinOpToken
|
||||
AssignOp(BinOpToken),
|
||||
/// `as`
|
||||
|
@ -84,6 +86,7 @@ impl AssocOp {
|
|||
use self::AssocOp::*;
|
||||
match *t {
|
||||
Token::BinOpEq(k) => Some(AssignOp(k)),
|
||||
Token::LArrow => Some(ObsoleteInPlace),
|
||||
Token::Eq => Some(Assign),
|
||||
Token::BinOp(BinOpToken::Star) => Some(Multiply),
|
||||
Token::BinOp(BinOpToken::Slash) => Some(Divide),
|
||||
|
@ -153,6 +156,7 @@ impl AssocOp {
|
|||
LAnd => 6,
|
||||
LOr => 5,
|
||||
DotDot | DotDotEq => 4,
|
||||
ObsoleteInPlace => 3,
|
||||
Assign | AssignOp(_) => 2,
|
||||
}
|
||||
}
|
||||
|
@ -162,7 +166,7 @@ impl AssocOp {
|
|||
use self::AssocOp::*;
|
||||
// NOTE: it is a bug to have an operators that has same precedence but different fixities!
|
||||
match *self {
|
||||
Assign | AssignOp(_) => Fixity::Right,
|
||||
ObsoleteInPlace | Assign | AssignOp(_) => Fixity::Right,
|
||||
As | Multiply | Divide | Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd |
|
||||
BitXor | BitOr | Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual |
|
||||
LAnd | LOr | Colon => Fixity::Left,
|
||||
|
@ -174,8 +178,8 @@ impl AssocOp {
|
|||
use self::AssocOp::*;
|
||||
match *self {
|
||||
Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual => true,
|
||||
Assign | AssignOp(_) | As | Multiply | Divide | Modulus | Add | Subtract |
|
||||
ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd | LOr |
|
||||
ObsoleteInPlace | Assign | AssignOp(_) | As | Multiply | Divide | Modulus | Add |
|
||||
Subtract | ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd | LOr |
|
||||
DotDot | DotDotEq | Colon => false
|
||||
}
|
||||
}
|
||||
|
@ -183,7 +187,7 @@ impl AssocOp {
|
|||
pub fn is_assign_like(&self) -> bool {
|
||||
use self::AssocOp::*;
|
||||
match *self {
|
||||
Assign | AssignOp(_) => true,
|
||||
Assign | AssignOp(_) | ObsoleteInPlace => true,
|
||||
Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual | As | Multiply | Divide |
|
||||
Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd |
|
||||
LOr | DotDot | DotDotEq | Colon => false
|
||||
|
@ -211,7 +215,7 @@ impl AssocOp {
|
|||
BitOr => Some(BinOpKind::BitOr),
|
||||
LAnd => Some(BinOpKind::And),
|
||||
LOr => Some(BinOpKind::Or),
|
||||
Assign | AssignOp(_) | As | DotDot | DotDotEq | Colon => None
|
||||
ObsoleteInPlace | Assign | AssignOp(_) | As | DotDot | DotDotEq | Colon => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -238,6 +242,7 @@ pub enum ExprPrecedence {
|
|||
|
||||
Binary(BinOpKind),
|
||||
|
||||
ObsoleteInPlace,
|
||||
Cast,
|
||||
Type,
|
||||
|
||||
|
@ -304,6 +309,7 @@ impl ExprPrecedence {
|
|||
|
||||
// Binop-like expr kinds, handled by `AssocOp`.
|
||||
ExprPrecedence::Binary(op) => AssocOp::from_ast_binop(op).precedence() as i8,
|
||||
ExprPrecedence::ObsoleteInPlace => AssocOp::ObsoleteInPlace.precedence() as i8,
|
||||
ExprPrecedence::Cast => AssocOp::As.precedence() as i8,
|
||||
ExprPrecedence::Type => AssocOp::Colon.precedence() as i8,
|
||||
|
||||
|
|
|
@ -660,6 +660,10 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
|
|||
ExprKind::Box(ref subexpression) => {
|
||||
visitor.visit_expr(subexpression)
|
||||
}
|
||||
ExprKind::ObsoleteInPlace(ref place, ref subexpression) => {
|
||||
visitor.visit_expr(place);
|
||||
visitor.visit_expr(subexpression)
|
||||
}
|
||||
ExprKind::Array(ref subexpressions) => {
|
||||
walk_list!(visitor, visit_expr, subexpressions);
|
||||
}
|
||||
|
|
18
src/test/ui/obsolete-in-place/bad.bad.stderr
Normal file
18
src/test/ui/obsolete-in-place/bad.bad.stderr
Normal file
|
@ -0,0 +1,18 @@
|
|||
error: emplacement syntax is obsolete (for now, anyway)
|
||||
--> $DIR/bad.rs:19:5
|
||||
|
|
||||
LL | x <- y; //[bad]~ ERROR emplacement syntax is obsolete
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: for more information, see <https://github.com/rust-lang/rust/issues/27779#issuecomment-378416911>
|
||||
|
||||
error: emplacement syntax is obsolete (for now, anyway)
|
||||
--> $DIR/bad.rs:20:5
|
||||
|
|
||||
LL | in(foo) { bar }; //[bad]~ ERROR emplacement syntax is obsolete
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: for more information, see <https://github.com/rust-lang/rust/issues/27779#issuecomment-378416911>
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
25
src/test/ui/obsolete-in-place/bad.rs
Normal file
25
src/test/ui/obsolete-in-place/bad.rs
Normal file
|
@ -0,0 +1,25 @@
|
|||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Check that `<-` and `in` syntax gets a hard error.
|
||||
|
||||
// revisions: good bad
|
||||
//[good] run-pass
|
||||
|
||||
#[cfg(bad)]
|
||||
fn main() {
|
||||
let (x, y, foo, bar);
|
||||
x <- y; //[bad]~ ERROR emplacement syntax is obsolete
|
||||
in(foo) { bar }; //[bad]~ ERROR emplacement syntax is obsolete
|
||||
}
|
||||
|
||||
#[cfg(good)]
|
||||
fn main() {
|
||||
}
|
Loading…
Add table
Reference in a new issue