Skip to content
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

[RFC 2011] Expand expressions where possible #98148

Merged
merged 1 commit into from
Jun 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
92 changes: 90 additions & 2 deletions compiler/rustc_builtin_macros/src/assert/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rustc_ast::{
token,
tokenstream::{DelimSpan, TokenStream, TokenTree},
BorrowKind, Expr, ExprKind, ItemKind, MacArgs, MacCall, MacDelimiter, Mutability, Path,
PathSegment, Stmt, UseTree, UseTreeKind, DUMMY_NODE_ID,
PathSegment, Stmt, StructRest, UseTree, UseTreeKind, DUMMY_NODE_ID,
};
use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashSet;
Expand Down Expand Up @@ -167,15 +167,103 @@ impl<'cx, 'a> Context<'cx, 'a> {
/// See [Self::manage_initial_capture] and [Self::manage_try_capture]
fn manage_cond_expr(&mut self, expr: &mut P<Expr>) {
match (*expr).kind {
ExprKind::AddrOf(_, _, ref mut local_expr) => {
self.manage_cond_expr(local_expr);
}
ExprKind::Array(ref mut local_exprs) => {
for local_expr in local_exprs {
self.manage_cond_expr(local_expr);
}
}
ExprKind::Binary(_, ref mut lhs, ref mut rhs) => {
self.manage_cond_expr(lhs);
self.manage_cond_expr(rhs);
}
ExprKind::Call(_, ref mut local_exprs) => {
for local_expr in local_exprs {
self.manage_cond_expr(local_expr);
}
}
ExprKind::Cast(ref mut local_expr, _) => {
self.manage_cond_expr(local_expr);
}
ExprKind::Index(ref mut prefix, ref mut suffix) => {
self.manage_cond_expr(prefix);
self.manage_cond_expr(suffix);
}
ExprKind::MethodCall(_, ref mut local_exprs, _) => {
for local_expr in local_exprs.iter_mut().skip(1) {
self.manage_cond_expr(local_expr);
}
}
ExprKind::Path(_, Path { ref segments, .. }) if let &[ref path_segment] = &segments[..] => {
let path_ident = path_segment.ident;
self.manage_initial_capture(expr, path_ident);
}
_ => {}
ExprKind::Paren(ref mut local_expr) => {
self.manage_cond_expr(local_expr);
}
ExprKind::Range(ref mut prefix, ref mut suffix, _) => {
if let Some(ref mut elem) = prefix {
self.manage_cond_expr(elem);
}
if let Some(ref mut elem) = suffix {
self.manage_cond_expr(elem);
}
}
ExprKind::Repeat(ref mut local_expr, ref mut elem) => {
self.manage_cond_expr(local_expr);
self.manage_cond_expr(&mut elem.value);
}
ExprKind::Struct(ref mut elem) => {
for field in &mut elem.fields {
self.manage_cond_expr(&mut field.expr);
}
if let StructRest::Base(ref mut local_expr) = elem.rest {
self.manage_cond_expr(local_expr);
}
}
ExprKind::Tup(ref mut local_exprs) => {
for local_expr in local_exprs {
self.manage_cond_expr(local_expr);
}
}
ExprKind::Unary(_, ref mut local_expr) => {
self.manage_cond_expr(local_expr);
}
// Expressions that are not worth or can not be captured.
//
// Full list instead of `_` to catch possible future inclusions and to
// sync with the `rfc-2011-nicer-assert-messages/all-expr-kinds.rs` test.
ExprKind::Assign(_, _, _)
| ExprKind::AssignOp(_, _, _)
| ExprKind::Async(_, _, _)
| ExprKind::Await(_)
| ExprKind::Block(_, _)
| ExprKind::Box(_)
| ExprKind::Break(_, _)
| ExprKind::Closure(_, _, _, _, _, _)
| ExprKind::ConstBlock(_)
| ExprKind::Continue(_)
| ExprKind::Err
| ExprKind::Field(_, _)
| ExprKind::ForLoop(_, _, _, _)
| ExprKind::If(_, _, _)
| ExprKind::InlineAsm(_)
| ExprKind::Let(_, _, _)
| ExprKind::Lit(_)
| ExprKind::Loop(_, _)
| ExprKind::MacCall(_)
| ExprKind::Match(_, _)
| ExprKind::Path(_, _)
| ExprKind::Ret(_)
| ExprKind::Try(_)
| ExprKind::TryBlock(_)
| ExprKind::Type(_, _)
| ExprKind::Underscore
| ExprKind::While(_, _, _)
| ExprKind::Yeet(_)
| ExprKind::Yield(_) => {}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,56 @@ struct Foo {
bar: i32
}

impl Foo {
fn add(&self, a: i32, b: i32) -> i32 { a + b }
}

fn add(a: i32, b: i32) -> i32 { a + b }

fn main() {
// ***** Allowed *****

tests!(
let mut elem = 1i32;

// addr of
[ &elem == &3 ] => "Assertion failed: &elem == &3\nWith captures:\n elem = 1\n"

// array
[ [elem][0] == 3 ] => "Assertion failed: [elem][0] == 3\nWith captures:\n elem = 1\n"

// binary
[ elem + 1 == 3 ] => "Assertion failed: elem + 1 == 3\nWith captures:\n elem = 1\n"

// call
[ add(elem, elem) == 3 ] => "Assertion failed: add(elem, elem) == 3\nWith captures:\n elem = 1\n"

// cast
[ elem as i32 == 3 ] => "Assertion failed: elem as i32 == 3\nWith captures:\n elem = 1\n"

// index
[ [1i32, 1][elem as usize] == 3 ] => "Assertion failed: [1i32, 1][elem as usize] == 3\nWith captures:\n elem = 1\n"

// method call
[ FOO.add(elem, elem) == 3 ] => "Assertion failed: FOO.add(elem, elem) == 3\nWith captures:\n elem = 1\n"

// paren
[ (elem) == 3 ] => "Assertion failed: (elem) == 3\nWith captures:\n elem = 1\n"

// range
[ (0..elem) == (0..3) ] => "Assertion failed: (0..elem) == (0..3)\nWith captures:\n elem = 1\n"

// repeat
[ [elem; 1] == [3; 1] ] => "Assertion failed: [elem; 1] == [3; 1]\nWith captures:\n elem = 1\n"

// struct
[ Foo { bar: elem } == Foo { bar: 3 } ] => "Assertion failed: Foo { bar: elem } == Foo { bar: 3 }\nWith captures:\n elem = 1\n"

// tuple
[ (elem, 1) == (3, 3) ] => "Assertion failed: (elem, 1) == (3, 3)\nWith captures:\n elem = 1\n"

// unary
[ -elem == -3 ] => "Assertion failed: -elem == -3\nWith captures:\n elem = 1\n"
);

// ***** Disallowed *****
Expand Down