Skip to content

Rollup of 8 pull requests #137710

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 23 commits into from
Feb 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
c293af9
add `IntoBounds::intersect` and `RangeBounds::is_empty`
pitaj Feb 20, 2025
db1f0d0
Return error on unexpected termination in `Thread::join`.
fuzzypixelz Feb 23, 2025
5d6a6e7
compiletest: disambiguate between root build dir vs test suite specif…
jieyouxu Feb 4, 2025
5238337
bootstrap: remove `--build-base` and use `--build-root` and `--build-…
jieyouxu Feb 4, 2025
7d2e4e4
bootstrap: remove redundant `to_path_buf()`
jieyouxu Feb 4, 2025
1ccdc06
Remove speculation on cause of error
fuzzypixelz Feb 24, 2025
7058f62
Use `.expect(..)` instead
fuzzypixelz Feb 25, 2025
3477297
Fix UB in ThinVec::flat_map_in_place
bjorn3 Jan 24, 2025
864cca8
Print out destructor
compiler-errors Feb 23, 2025
df845c9
Spruce up `AttributeKind` docs
aDotInTheVoid Feb 26, 2025
a8364f3
In `AssocOp::AssignOp`, use `BinOpKind` instead of `BinOpToken`
nnethercote Dec 19, 2024
ceafbad
Introduce `AssocOp::Binary`.
nnethercote Dec 19, 2024
fc8e87b
Replace `AssocOp::DotDot{,Eq}` with `AssocOp::Range`.
nnethercote Dec 19, 2024
2ac46f6
Rename `AssocOp::As` as `AssocOp::Cast`.
nnethercote Dec 19, 2024
ef66cbb
require trait impls to have matching const stabilities as the traits
fee1-dead Feb 7, 2025
f435138
Rollup merge of #136542 - jieyouxu:build-base, r=onur-ozkan
matthiaskrgr Feb 27, 2025
18c47ad
Rollup merge of #136579 - bjorn3:fix_thinvec_ext_ub, r=BoxyUwU
matthiaskrgr Feb 27, 2025
88dcab7
Rollup merge of #136688 - fee1-dead-contrib:push-nppsusmpokqo, r=comp…
matthiaskrgr Feb 27, 2025
4ecca4c
Rollup merge of #136846 - nnethercote:make-AssocOp-more-like-ExprKind…
matthiaskrgr Feb 27, 2025
3499846
Rollup merge of #137304 - pitaj:rangebounds-is_empty-intersect, r=ibr…
matthiaskrgr Feb 27, 2025
25db95e
Rollup merge of #137455 - compiler-errors:drop-lint-dtor, r=oli-obk
matthiaskrgr Feb 27, 2025
f19d4b5
Rollup merge of #137480 - fuzzypixelz:fix/124466, r=workingjubilee
matthiaskrgr Feb 27, 2025
89a202d
Rollup merge of #137694 - aDotInTheVoid:aDotInTheVoid-patch-1, r=jdon…
matthiaskrgr Feb 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3916,6 +3916,7 @@ dependencies = [
"rustc_target",
"rustc_trait_selection",
"rustc_type_ir",
"smallvec",
"tracing",
"unicode-security",
]
Expand Down
44 changes: 41 additions & 3 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub use crate::format::*;
use crate::ptr::P;
use crate::token::{self, CommentKind, Delimiter};
use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream};
use crate::util::parser::{AssocOp, ExprPrecedence};
use crate::util::parser::{ExprPrecedence, Fixity};

/// A "Label" is an identifier of some point in sources,
/// e.g. in the following code:
Expand Down Expand Up @@ -937,8 +937,37 @@ impl BinOpKind {
matches!(self, BinOpKind::And | BinOpKind::Or)
}

pub fn precedence(&self) -> ExprPrecedence {
use BinOpKind::*;
match *self {
Mul | Div | Rem => ExprPrecedence::Product,
Add | Sub => ExprPrecedence::Sum,
Shl | Shr => ExprPrecedence::Shift,
BitAnd => ExprPrecedence::BitAnd,
BitXor => ExprPrecedence::BitXor,
BitOr => ExprPrecedence::BitOr,
Lt | Gt | Le | Ge | Eq | Ne => ExprPrecedence::Compare,
And => ExprPrecedence::LAnd,
Or => ExprPrecedence::LOr,
}
}

pub fn fixity(&self) -> Fixity {
use BinOpKind::*;
match self {
Eq | Ne | Lt | Le | Gt | Ge => Fixity::None,
Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => {
Fixity::Left
}
}
}

pub fn is_comparison(self) -> bool {
crate::util::parser::AssocOp::from_ast_binop(self).is_comparison()
use BinOpKind::*;
match self {
Eq | Ne | Lt | Le | Gt | Ge => true,
Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => false,
}
}

/// Returns `true` if the binary operator takes its arguments by value.
Expand Down Expand Up @@ -1332,7 +1361,7 @@ impl Expr {
ExprKind::Range(..) => ExprPrecedence::Range,

// Binop-like expr kinds, handled by `AssocOp`.
ExprKind::Binary(op, ..) => AssocOp::from_ast_binop(op.node).precedence(),
ExprKind::Binary(op, ..) => op.node.precedence(),
ExprKind::Cast(..) => ExprPrecedence::Cast,

ExprKind::Assign(..) |
Expand Down Expand Up @@ -1424,6 +1453,15 @@ pub enum RangeLimits {
Closed,
}

impl RangeLimits {
pub fn as_str(&self) -> &'static str {
match self {
RangeLimits::HalfOpen => "..",
RangeLimits::Closed => "..=",
}
}
}

/// A method call (e.g. `x.foo::<Bar, Baz>(a, b, c)`).
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct MethodCall {
Expand Down
216 changes: 62 additions & 154 deletions compiler/rustc_ast/src/util/parser.rs
Original file line number Diff line number Diff line change
@@ -1,59 +1,21 @@
use rustc_span::kw;

use crate::ast::{self, BinOpKind};
use crate::ast::{self, BinOpKind, RangeLimits};
use crate::token::{self, BinOpToken, Token};

/// Associative operator with precedence.
///
/// This is the enum which specifies operator precedence and fixity to the parser.
/// Associative operator.
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum AssocOp {
/// `+`
Add,
/// `-`
Subtract,
/// `*`
Multiply,
/// `/`
Divide,
/// `%`
Modulus,
/// `&&`
LAnd,
/// `||`
LOr,
/// `^`
BitXor,
/// `&`
BitAnd,
/// `|`
BitOr,
/// `<<`
ShiftLeft,
/// `>>`
ShiftRight,
/// `==`
Equal,
/// `<`
Less,
/// `<=`
LessEqual,
/// `!=`
NotEqual,
/// `>`
Greater,
/// `>=`
GreaterEqual,
/// A binary op.
Binary(BinOpKind),
/// `?=` where ? is one of the assignable BinOps
AssignOp(BinOpKind),
/// `=`
Assign,
/// `?=` where ? is one of the BinOpToken
AssignOp(BinOpToken),
/// `as`
As,
/// `..` range
DotDot,
/// `..=` range
DotDotEq,
Cast,
/// `..` or `..=` range
Range(RangeLimits),
}

#[derive(PartialEq, Debug)]
Expand All @@ -67,81 +29,56 @@ pub enum Fixity {
}

impl AssocOp {
/// Creates a new AssocOP from a token
/// Creates a new AssocOp from a token.
pub fn from_token(t: &Token) -> Option<AssocOp> {
use AssocOp::*;
match t.kind {
token::BinOpEq(k) => Some(AssignOp(k)),
token::Eq => Some(Assign),
token::BinOp(BinOpToken::Star) => Some(Multiply),
token::BinOp(BinOpToken::Slash) => Some(Divide),
token::BinOp(BinOpToken::Percent) => Some(Modulus),
token::BinOp(BinOpToken::Plus) => Some(Add),
token::BinOp(BinOpToken::Minus) => Some(Subtract),
token::BinOp(BinOpToken::Shl) => Some(ShiftLeft),
token::BinOp(BinOpToken::Shr) => Some(ShiftRight),
token::BinOp(BinOpToken::And) => Some(BitAnd),
token::BinOp(BinOpToken::Caret) => Some(BitXor),
token::BinOp(BinOpToken::Or) => Some(BitOr),
token::Lt => Some(Less),
token::Le => Some(LessEqual),
token::Ge => Some(GreaterEqual),
token::Gt => Some(Greater),
token::EqEq => Some(Equal),
token::Ne => Some(NotEqual),
token::AndAnd => Some(LAnd),
token::OrOr => Some(LOr),
token::DotDot => Some(DotDot),
token::DotDotEq => Some(DotDotEq),
token::BinOp(BinOpToken::Plus) => Some(Binary(BinOpKind::Add)),
token::BinOp(BinOpToken::Minus) => Some(Binary(BinOpKind::Sub)),
token::BinOp(BinOpToken::Star) => Some(Binary(BinOpKind::Mul)),
token::BinOp(BinOpToken::Slash) => Some(Binary(BinOpKind::Div)),
token::BinOp(BinOpToken::Percent) => Some(Binary(BinOpKind::Rem)),
token::BinOp(BinOpToken::Caret) => Some(Binary(BinOpKind::BitXor)),
token::BinOp(BinOpToken::And) => Some(Binary(BinOpKind::BitAnd)),
token::BinOp(BinOpToken::Or) => Some(Binary(BinOpKind::BitOr)),
token::BinOp(BinOpToken::Shl) => Some(Binary(BinOpKind::Shl)),
token::BinOp(BinOpToken::Shr) => Some(Binary(BinOpKind::Shr)),
token::BinOpEq(BinOpToken::Plus) => Some(AssignOp(BinOpKind::Add)),
token::BinOpEq(BinOpToken::Minus) => Some(AssignOp(BinOpKind::Sub)),
token::BinOpEq(BinOpToken::Star) => Some(AssignOp(BinOpKind::Mul)),
token::BinOpEq(BinOpToken::Slash) => Some(AssignOp(BinOpKind::Div)),
token::BinOpEq(BinOpToken::Percent) => Some(AssignOp(BinOpKind::Rem)),
token::BinOpEq(BinOpToken::Caret) => Some(AssignOp(BinOpKind::BitXor)),
token::BinOpEq(BinOpToken::And) => Some(AssignOp(BinOpKind::BitAnd)),
token::BinOpEq(BinOpToken::Or) => Some(AssignOp(BinOpKind::BitOr)),
token::BinOpEq(BinOpToken::Shl) => Some(AssignOp(BinOpKind::Shl)),
token::BinOpEq(BinOpToken::Shr) => Some(AssignOp(BinOpKind::Shr)),
token::Lt => Some(Binary(BinOpKind::Lt)),
token::Le => Some(Binary(BinOpKind::Le)),
token::Ge => Some(Binary(BinOpKind::Ge)),
token::Gt => Some(Binary(BinOpKind::Gt)),
token::EqEq => Some(Binary(BinOpKind::Eq)),
token::Ne => Some(Binary(BinOpKind::Ne)),
token::AndAnd => Some(Binary(BinOpKind::And)),
token::OrOr => Some(Binary(BinOpKind::Or)),
token::DotDot => Some(Range(RangeLimits::HalfOpen)),
// DotDotDot is no longer supported, but we need some way to display the error
token::DotDotDot => Some(DotDotEq),
token::DotDotEq | token::DotDotDot => Some(Range(RangeLimits::Closed)),
// `<-` should probably be `< -`
token::LArrow => Some(Less),
_ if t.is_keyword(kw::As) => Some(As),
token::LArrow => Some(Binary(BinOpKind::Lt)),
_ if t.is_keyword(kw::As) => Some(Cast),
_ => None,
}
}

/// Creates a new AssocOp from ast::BinOpKind.
pub fn from_ast_binop(op: BinOpKind) -> Self {
use AssocOp::*;
match op {
BinOpKind::Lt => Less,
BinOpKind::Gt => Greater,
BinOpKind::Le => LessEqual,
BinOpKind::Ge => GreaterEqual,
BinOpKind::Eq => Equal,
BinOpKind::Ne => NotEqual,
BinOpKind::Mul => Multiply,
BinOpKind::Div => Divide,
BinOpKind::Rem => Modulus,
BinOpKind::Add => Add,
BinOpKind::Sub => Subtract,
BinOpKind::Shl => ShiftLeft,
BinOpKind::Shr => ShiftRight,
BinOpKind::BitAnd => BitAnd,
BinOpKind::BitXor => BitXor,
BinOpKind::BitOr => BitOr,
BinOpKind::And => LAnd,
BinOpKind::Or => LOr,
}
}

/// Gets the precedence of this operator
pub fn precedence(&self) -> ExprPrecedence {
use AssocOp::*;
match *self {
As => ExprPrecedence::Cast,
Multiply | Divide | Modulus => ExprPrecedence::Product,
Add | Subtract => ExprPrecedence::Sum,
ShiftLeft | ShiftRight => ExprPrecedence::Shift,
BitAnd => ExprPrecedence::BitAnd,
BitXor => ExprPrecedence::BitXor,
BitOr => ExprPrecedence::BitOr,
Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual => ExprPrecedence::Compare,
LAnd => ExprPrecedence::LAnd,
LOr => ExprPrecedence::LOr,
DotDot | DotDotEq => ExprPrecedence::Range,
Cast => ExprPrecedence::Cast,
Binary(bin_op) => bin_op.precedence(),
Range(_) => ExprPrecedence::Range,
Assign | AssignOp(_) => ExprPrecedence::Assign,
}
}
Expand All @@ -152,57 +89,25 @@ impl AssocOp {
// NOTE: it is a bug to have an operators that has same precedence but different fixities!
match *self {
Assign | AssignOp(_) => Fixity::Right,
As | Multiply | Divide | Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd
| BitXor | BitOr | LAnd | LOr => Fixity::Left,
Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual | DotDot | DotDotEq => {
Fixity::None
}
Binary(binop) => binop.fixity(),
Cast => Fixity::Left,
Range(_) => Fixity::None,
}
}

pub fn is_comparison(&self) -> bool {
use 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 | DotDot | DotDotEq => {
false
}
Binary(binop) => binop.is_comparison(),
Assign | AssignOp(_) | Cast | Range(_) => false,
}
}

pub fn is_assign_like(&self) -> bool {
use AssocOp::*;
match *self {
Assign | AssignOp(_) => true,
Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual | As | Multiply
| Divide | Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd | BitXor
| BitOr | LAnd | LOr | DotDot | DotDotEq => false,
}
}

pub fn to_ast_binop(&self) -> Option<BinOpKind> {
use AssocOp::*;
match *self {
Less => Some(BinOpKind::Lt),
Greater => Some(BinOpKind::Gt),
LessEqual => Some(BinOpKind::Le),
GreaterEqual => Some(BinOpKind::Ge),
Equal => Some(BinOpKind::Eq),
NotEqual => Some(BinOpKind::Ne),
Multiply => Some(BinOpKind::Mul),
Divide => Some(BinOpKind::Div),
Modulus => Some(BinOpKind::Rem),
Add => Some(BinOpKind::Add),
Subtract => Some(BinOpKind::Sub),
ShiftLeft => Some(BinOpKind::Shl),
ShiftRight => Some(BinOpKind::Shr),
BitAnd => Some(BinOpKind::BitAnd),
BitXor => Some(BinOpKind::BitXor),
BitOr => Some(BinOpKind::BitOr),
LAnd => Some(BinOpKind::And),
LOr => Some(BinOpKind::Or),
Assign | AssignOp(_) | As | DotDot | DotDotEq => None,
Cast | Binary(_) | Range(_) => false,
}
}

Expand All @@ -212,20 +117,23 @@ impl AssocOp {
/// parentheses while having a high degree of confidence on the correctness of the suggestion.
pub fn can_continue_expr_unambiguously(&self) -> bool {
use AssocOp::*;
use BinOpKind::*;
matches!(
self,
BitXor | // `{ 42 } ^ 3`
Assign | // `{ 42 } = { 42 }`
Divide | // `{ 42 } / 42`
Modulus | // `{ 42 } % 2`
ShiftRight | // `{ 42 } >> 2`
LessEqual | // `{ 42 } <= 3`
Greater | // `{ 42 } > 3`
GreaterEqual | // `{ 42 } >= 3`
Binary(
BitXor | // `{ 42 } ^ 3`
Div | // `{ 42 } / 42`
Rem | // `{ 42 } % 2`
Shr | // `{ 42 } >> 2`
Le | // `{ 42 } <= 3`
Gt | // `{ 42 } > 3`
Ge // `{ 42 } >= 3`
) |
AssignOp(_) | // `{ 42 } +=`
// Equal | // `{ 42 } == { 42 }` Accepting these here would regress incorrect
// NotEqual | // `{ 42 } != { 42 } struct literals parser recovery.
As // `{ 42 } as usize`
Cast // `{ 42 } as usize`
)
}
}
Expand Down
7 changes: 3 additions & 4 deletions compiler/rustc_ast_pretty/src/pprust/state/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use itertools::{Itertools, Position};
use rustc_ast::ptr::P;
use rustc_ast::util::classify;
use rustc_ast::util::literal::escape_byte_str_symbol;
use rustc_ast::util::parser::{self, AssocOp, ExprPrecedence, Fixity};
use rustc_ast::util::parser::{self, ExprPrecedence, Fixity};
use rustc_ast::{
self as ast, BlockCheckMode, FormatAlignment, FormatArgPosition, FormatArgsPiece, FormatCount,
FormatDebugHex, FormatSign, FormatTrait, token,
Expand Down Expand Up @@ -279,12 +279,11 @@ impl<'a> State<'a> {
rhs: &ast::Expr,
fixup: FixupContext,
) {
let assoc_op = AssocOp::from_ast_binop(op.node);
let binop_prec = assoc_op.precedence();
let binop_prec = op.node.precedence();
let left_prec = lhs.precedence();
let right_prec = rhs.precedence();

let (mut left_needs_paren, right_needs_paren) = match assoc_op.fixity() {
let (mut left_needs_paren, right_needs_paren) = match op.node.fixity() {
Fixity::Left => (left_prec < binop_prec, right_prec <= binop_prec),
Fixity::Right => (left_prec <= binop_prec, right_prec < binop_prec),
Fixity::None => (left_prec <= binop_prec, right_prec <= binop_prec),
Expand Down
Loading
Loading