mirror of
				https://github.com/rust-lang/rust-analyzer.git
				synced 2025-10-31 20:09:01 +00:00 
			
		
		
		
	Merge pull request #19250 from Veykril/push-tmrnrlotwtmr
Have inline_local_variable use precedence calculation for parentheses
This commit is contained in:
		
						commit
						fe84446166
					
				
					 5 changed files with 44 additions and 67 deletions
				
			
		|  | @ -39,25 +39,10 @@ pub(crate) fn inline_const_as_literal(acc: &mut Assists, ctx: &AssistContext<'_> | ||||||
|         // FIXME: Add support to handle type aliases for builtin scalar types.
 |         // FIXME: Add support to handle type aliases for builtin scalar types.
 | ||||||
|         validate_type_recursively(ctx, Some(&konst_ty), false, fuel)?; |         validate_type_recursively(ctx, Some(&konst_ty), false, fuel)?; | ||||||
| 
 | 
 | ||||||
|         let expr = konst.value(ctx.sema.db)?; |         let value = konst | ||||||
| 
 |  | ||||||
|         let value = match expr { |  | ||||||
|             ast::Expr::BlockExpr(_) |  | ||||||
|             | ast::Expr::Literal(_) |  | ||||||
|             | ast::Expr::RefExpr(_) |  | ||||||
|             | ast::Expr::ArrayExpr(_) |  | ||||||
|             | ast::Expr::TupleExpr(_) |  | ||||||
|             | ast::Expr::IfExpr(_) |  | ||||||
|             | ast::Expr::ParenExpr(_) |  | ||||||
|             | ast::Expr::MatchExpr(_) |  | ||||||
|             | ast::Expr::MacroExpr(_) |  | ||||||
|             | ast::Expr::BinExpr(_) |  | ||||||
|             | ast::Expr::CallExpr(_) => konst |  | ||||||
|             .eval(ctx.sema.db) |             .eval(ctx.sema.db) | ||||||
|             .ok()? |             .ok()? | ||||||
|                 .render(ctx.sema.db, konst.krate(ctx.sema.db).edition(ctx.sema.db)), |             .render(ctx.sema.db, konst.krate(ctx.sema.db).edition(ctx.sema.db)); | ||||||
|             _ => return None, |  | ||||||
|         }; |  | ||||||
| 
 | 
 | ||||||
|         let id = AssistId("inline_const_as_literal", AssistKind::RefactorInline); |         let id = AssistId("inline_const_as_literal", AssistKind::RefactorInline); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -5,7 +5,11 @@ use ide_db::{ | ||||||
|     EditionedFileId, RootDatabase, |     EditionedFileId, RootDatabase, | ||||||
| }; | }; | ||||||
| use syntax::{ | use syntax::{ | ||||||
|     ast::{self, AstNode, AstToken, HasName}, |     ast::{ | ||||||
|  |         self, | ||||||
|  |         prec::{precedence, ExprPrecedence}, | ||||||
|  |         AstNode, AstToken, HasName, | ||||||
|  |     }, | ||||||
|     SyntaxElement, TextRange, |     SyntaxElement, TextRange, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | @ -79,33 +83,16 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_>) | ||||||
|                 Some(u) => u, |                 Some(u) => u, | ||||||
|                 None => return Some((range, name_ref, false)), |                 None => return Some((range, name_ref, false)), | ||||||
|             }; |             }; | ||||||
|             let initializer = matches!( |             let initializer = precedence(&initializer_expr); | ||||||
|                 initializer_expr, |             let parent = precedence(&usage_parent); | ||||||
|                 ast::Expr::CallExpr(_) |             Some(( | ||||||
|                     | ast::Expr::IndexExpr(_) |                 range, | ||||||
|                     | ast::Expr::MethodCallExpr(_) |                 name_ref, | ||||||
|                     | ast::Expr::FieldExpr(_) |                 parent != ExprPrecedence::Unambiguous | ||||||
|                     | ast::Expr::TryExpr(_) |                     && initializer < parent | ||||||
|                     | ast::Expr::Literal(_) |                     // initializer == ExprPrecedence::Prefix -> parent != ExprPrecedence::Jump
 | ||||||
|                     | ast::Expr::TupleExpr(_) |                     && (initializer != ExprPrecedence::Prefix || parent != ExprPrecedence::Jump), | ||||||
|                     | ast::Expr::ArrayExpr(_) |             )) | ||||||
|                     | ast::Expr::ParenExpr(_) |  | ||||||
|                     | ast::Expr::PathExpr(_) |  | ||||||
|                     | ast::Expr::BlockExpr(_), |  | ||||||
|             ); |  | ||||||
|             let parent = matches!( |  | ||||||
|                 usage_parent, |  | ||||||
|                 ast::Expr::TupleExpr(_) |  | ||||||
|                     | ast::Expr::ArrayExpr(_) |  | ||||||
|                     | ast::Expr::ParenExpr(_) |  | ||||||
|                     | ast::Expr::ForExpr(_) |  | ||||||
|                     | ast::Expr::WhileExpr(_) |  | ||||||
|                     | ast::Expr::BreakExpr(_) |  | ||||||
|                     | ast::Expr::ReturnExpr(_) |  | ||||||
|                     | ast::Expr::MatchExpr(_) |  | ||||||
|                     | ast::Expr::BlockExpr(_) |  | ||||||
|             ); |  | ||||||
|             Some((range, name_ref, !(initializer || parent))) |  | ||||||
|         }) |         }) | ||||||
|         .collect::<Option<Vec<_>>>()?; |         .collect::<Option<Vec<_>>>()?; | ||||||
| 
 | 
 | ||||||
|  | @ -281,11 +268,11 @@ fn foo() { | ||||||
|             r" |             r" | ||||||
| fn bar(a: usize) {} | fn bar(a: usize) {} | ||||||
| fn foo() { | fn foo() { | ||||||
|     (1 + 1) + 1; |     1 + 1 + 1; | ||||||
|     if (1 + 1) > 10 { |     if 1 + 1 > 10 { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     while (1 + 1) > 10 { |     while 1 + 1 > 10 { | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
|     let b = (1 + 1) * 10; |     let b = (1 + 1) * 10; | ||||||
|  | @ -350,14 +337,14 @@ fn foo() { | ||||||
|             r" |             r" | ||||||
| fn bar(a: usize) -> usize { a } | fn bar(a: usize) -> usize { a } | ||||||
| fn foo() { | fn foo() { | ||||||
|     (bar(1) as u64) + 1; |     bar(1) as u64 + 1; | ||||||
|     if (bar(1) as u64) > 10 { |     if bar(1) as u64 > 10 { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     while (bar(1) as u64) > 10 { |     while bar(1) as u64 > 10 { | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
|     let b = (bar(1) as u64) * 10; |     let b = bar(1) as u64 * 10; | ||||||
|     bar(bar(1) as u64); |     bar(bar(1) as u64); | ||||||
| }",
 | }",
 | ||||||
|         ); |         ); | ||||||
|  | @ -574,7 +561,7 @@ fn foo() { | ||||||
|             r" |             r" | ||||||
| fn foo() { | fn foo() { | ||||||
|     let bar = 10; |     let bar = 10; | ||||||
|     let b = (&bar) * 10; |     let b = &bar * 10; | ||||||
| }",
 | }",
 | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -259,10 +259,8 @@ fn needs_parens_for_adjustment_hints(expr: &ast::Expr, postfix: bool) -> (bool, | ||||||
|     let prec = expr.precedence(); |     let prec = expr.precedence(); | ||||||
|     if postfix { |     if postfix { | ||||||
|         // postfix ops have higher precedence than any other operator, so we need to wrap
 |         // postfix ops have higher precedence than any other operator, so we need to wrap
 | ||||||
|         // any inner expression that is below (except for jumps if they don't have a value)
 |         // any inner expression that is below
 | ||||||
|         let needs_inner_parens = prec < ExprPrecedence::Postfix && { |         let needs_inner_parens = prec < ExprPrecedence::Postfix; | ||||||
|             prec != ExprPrecedence::Jump || !expr.is_ret_like_with_no_value() |  | ||||||
|         }; |  | ||||||
|         // given we are the higher precedence, no parent expression will have stronger requirements
 |         // given we are the higher precedence, no parent expression will have stronger requirements
 | ||||||
|         let needs_outer_parens = false; |         let needs_outer_parens = false; | ||||||
|         (needs_outer_parens, needs_inner_parens) |         (needs_outer_parens, needs_inner_parens) | ||||||
|  | @ -275,13 +273,13 @@ fn needs_parens_for_adjustment_hints(expr: &ast::Expr, postfix: bool) -> (bool, | ||||||
|             .and_then(ast::Expr::cast) |             .and_then(ast::Expr::cast) | ||||||
|             // if we are already wrapped, great, no need to wrap again
 |             // if we are already wrapped, great, no need to wrap again
 | ||||||
|             .filter(|it| !matches!(it, ast::Expr::ParenExpr(_))) |             .filter(|it| !matches!(it, ast::Expr::ParenExpr(_))) | ||||||
|             .map(|it| it.precedence()); |             .map(|it| it.precedence()) | ||||||
|  |             .filter(|&prec| prec != ExprPrecedence::Unambiguous); | ||||||
| 
 | 
 | ||||||
|         // if we have no parent, we don't need outer parens to disambiguate
 |         // if we have no parent, we don't need outer parens to disambiguate
 | ||||||
|         // otherwise anything with higher precedence than what we insert needs to wrap us
 |         // otherwise anything with higher precedence than what we insert needs to wrap us
 | ||||||
|         // that means only postfix ops
 |  | ||||||
|         let needs_outer_parens = |         let needs_outer_parens = | ||||||
|             parent.is_some_and(|parent_prec| parent_prec == ExprPrecedence::Postfix); |             parent.is_some_and(|parent_prec| parent_prec > ExprPrecedence::Prefix); | ||||||
|         (needs_outer_parens, needs_inner_parens) |         (needs_outer_parens, needs_inner_parens) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -7,7 +7,7 @@ use crate::{ | ||||||
| 
 | 
 | ||||||
| #[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] | #[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] | ||||||
| pub enum ExprPrecedence { | pub enum ExprPrecedence { | ||||||
|     // return, break, yield, closures
 |     // return val, break val, yield val, closures
 | ||||||
|     Jump, |     Jump, | ||||||
|     // = += -= *= /= %= &= |= ^= <<= >>=
 |     // = += -= *= /= %= &= |= ^= <<= >>=
 | ||||||
|     Assign, |     Assign, | ||||||
|  | @ -58,12 +58,18 @@ pub fn precedence(expr: &ast::Expr) -> ExprPrecedence { | ||||||
|             Some(_) => ExprPrecedence::Unambiguous, |             Some(_) => ExprPrecedence::Unambiguous, | ||||||
|         }, |         }, | ||||||
| 
 | 
 | ||||||
|  |         Expr::BreakExpr(e) if e.expr().is_some() => ExprPrecedence::Jump, | ||||||
|  |         Expr::BecomeExpr(e) if e.expr().is_some() => ExprPrecedence::Jump, | ||||||
|  |         Expr::ReturnExpr(e) if e.expr().is_some() => ExprPrecedence::Jump, | ||||||
|  |         Expr::YeetExpr(e) if e.expr().is_some() => ExprPrecedence::Jump, | ||||||
|  |         Expr::YieldExpr(e) if e.expr().is_some() => ExprPrecedence::Jump, | ||||||
|  | 
 | ||||||
|         Expr::BreakExpr(_) |         Expr::BreakExpr(_) | ||||||
|         | Expr::BecomeExpr(_) |         | Expr::BecomeExpr(_) | ||||||
|         | Expr::ContinueExpr(_) |  | ||||||
|         | Expr::ReturnExpr(_) |         | Expr::ReturnExpr(_) | ||||||
|         | Expr::YeetExpr(_) |         | Expr::YeetExpr(_) | ||||||
|         | Expr::YieldExpr(_) => ExprPrecedence::Jump, |         | Expr::YieldExpr(_) | ||||||
|  |         | Expr::ContinueExpr(_) => ExprPrecedence::Unambiguous, | ||||||
| 
 | 
 | ||||||
|         Expr::RangeExpr(..) => ExprPrecedence::Range, |         Expr::RangeExpr(..) => ExprPrecedence::Range, | ||||||
| 
 | 
 | ||||||
|  | @ -387,6 +393,7 @@ impl Expr { | ||||||
|             BreakExpr(e) => e.expr().is_none(), |             BreakExpr(e) => e.expr().is_none(), | ||||||
|             ContinueExpr(_) => true, |             ContinueExpr(_) => true, | ||||||
|             YieldExpr(e) => e.expr().is_none(), |             YieldExpr(e) => e.expr().is_none(), | ||||||
|  |             BecomeExpr(e) => e.expr().is_none(), | ||||||
|             _ => false, |             _ => false, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -269,7 +269,7 @@ impl ast::ByteString { | ||||||
|             } |             } | ||||||
|             (Ok(c), true) => { |             (Ok(c), true) => { | ||||||
|                 buf.reserve_exact(text.len()); |                 buf.reserve_exact(text.len()); | ||||||
|                 buf.extend_from_slice(text[..prev_end].as_bytes()); |                 buf.extend_from_slice(&text.as_bytes()[..prev_end]); | ||||||
|                 buf.push(c as u8); |                 buf.push(c as u8); | ||||||
|             } |             } | ||||||
|             (Err(e), _) => has_error = Some(e), |             (Err(e), _) => has_error = Some(e), | ||||||
|  | @ -333,7 +333,7 @@ impl ast::CString { | ||||||
|             } |             } | ||||||
|             (Ok(u), true) => { |             (Ok(u), true) => { | ||||||
|                 buf.reserve_exact(text.len()); |                 buf.reserve_exact(text.len()); | ||||||
|                 buf.extend(text[..prev_end].as_bytes()); |                 buf.extend(&text.as_bytes()[..prev_end]); | ||||||
|                 extend_unit(&mut buf, u); |                 extend_unit(&mut buf, u); | ||||||
|             } |             } | ||||||
|             (Err(e), _) => has_error = Some(e), |             (Err(e), _) => has_error = Some(e), | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Lukas Wirth
						Lukas Wirth