From d6c5a6bd3adcc5bb5f077818432a5e3efb224ec0 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 26 Dec 2024 17:35:07 +0000 Subject: [PATCH 1/8] nit: Remove redundant function --- compiler/rustc_infer/src/infer/region_constraints/mod.rs | 4 ---- compiler/rustc_trait_selection/src/traits/auto_trait.rs | 3 +-- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index 6dce4b2b21df1..6496f38269a5e 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -299,10 +299,6 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { self.storage.var_infos.len() } - pub fn region_constraint_data(&self) -> &RegionConstraintData<'tcx> { - &self.storage.data - } - /// Takes (and clears) the current set of constraints. Note that /// the set of variables remains intact, but all relationships /// between them are reset. This is used during NLL checking to diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 6730f28893d1c..9a53e8a5d5190 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -161,8 +161,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { let outlives_env = OutlivesEnvironment::new(full_env); let _ = infcx.process_registered_region_obligations(&outlives_env, |ty, _| Ok(ty)); - let region_data = - infcx.inner.borrow_mut().unwrap_region_constraints().region_constraint_data().clone(); + let region_data = infcx.inner.borrow_mut().unwrap_region_constraints().data().clone(); let vid_to_region = self.map_vid_to_region(®ion_data); From e1b65be4177486979bab4a05f520e0c013b831b4 Mon Sep 17 00:00:00 2001 From: chloefeal <188809157+chloefeal@users.noreply.github.com> Date: Fri, 27 Dec 2024 21:35:57 +0800 Subject: [PATCH 2/8] Fix typos Signed-off-by: chloefeal <188809157+chloefeal@users.noreply.github.com> --- compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs | 2 +- compiler/rustc_llvm/build.rs | 2 +- compiler/rustc_mir_build/src/check_tail_calls.rs | 2 +- compiler/rustc_trait_selection/src/traits/select/mod.rs | 2 +- library/alloc/tests/sort/tests.rs | 2 +- library/core/benches/num/int_pow/mod.rs | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs b/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs index d77c53a398447..876b8f214b017 100644 --- a/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs +++ b/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs @@ -31,7 +31,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { diag: &mut Diag<'_>, ) { // We look at all the locals. Why locals? Because it's the best thing - // I could think of that's correlated with the *instantiated* higer-ranked + // I could think of that's correlated with the *instantiated* higher-ranked // binder for calls, since we don't really store those anywhere else. for ty in self.body.local_decls.iter().map(|local| local.ty) { if !ty.has_opaque_types() { diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index f092110a324ec..d9d28299413b1 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -220,7 +220,7 @@ fn main() { let mut cmd = Command::new(&llvm_config); cmd.arg(llvm_link_arg).arg("--libs"); - // Don't link system libs if cross-compiling unless targetting Windows. + // Don't link system libs if cross-compiling unless targeting Windows. // On Windows system DLLs aren't linked directly, instead import libraries are used. // These import libraries are independent of the host. if !is_crossed || target.contains("windows") { diff --git a/compiler/rustc_mir_build/src/check_tail_calls.rs b/compiler/rustc_mir_build/src/check_tail_calls.rs index b1f46d37d5062..0659e3ea314bb 100644 --- a/compiler/rustc_mir_build/src/check_tail_calls.rs +++ b/compiler/rustc_mir_build/src/check_tail_calls.rs @@ -117,7 +117,7 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> { self.report_arguments_mismatch(expr.span, caller_sig, callee_sig); } - // FIXME(explicit_tail_calls): this currenly fails for cases where opaques are used. + // FIXME(explicit_tail_calls): this currently fails for cases where opaques are used. // e.g. // ``` // fn a() -> impl Sized { become b() } // ICE diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 7857ed95cc716..9e7da5eb3689c 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1843,7 +1843,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { // a global and a non-global where-clause. // // Our handling of where-bounds is generally fairly messy but necessary for backwards - // compatability, see #50825 for why we need to handle global where-bounds like this. + // compatibility, see #50825 for why we need to handle global where-bounds like this. let is_global = |c: ty::PolyTraitPredicate<'tcx>| c.is_global() && !c.has_bound_vars(); let param_candidates = candidates .iter() diff --git a/library/alloc/tests/sort/tests.rs b/library/alloc/tests/sort/tests.rs index 14e6013f965d8..206624e59ea53 100644 --- a/library/alloc/tests/sort/tests.rs +++ b/library/alloc/tests/sort/tests.rs @@ -33,7 +33,7 @@ fn check_is_sorted(v: &mut [T]) { known_good_stable_sort::sort(known_good_sorted_vec.as_mut_slice()); if is_small_test { - eprintln!("Orginal: {:?}", v_orig); + eprintln!("Original: {:?}", v_orig); eprintln!("Expected: {:?}", known_good_sorted_vec); eprintln!("Got: {:?}", v); } else { diff --git a/library/core/benches/num/int_pow/mod.rs b/library/core/benches/num/int_pow/mod.rs index 6cf9021358283..46f47028d56e6 100644 --- a/library/core/benches/num/int_pow/mod.rs +++ b/library/core/benches/num/int_pow/mod.rs @@ -25,7 +25,7 @@ macro_rules! pow_bench_template { let mut exp_iter = black_box(&exp_array).into_iter(); (0..ITERATIONS).fold((0 as IntType, false), |acc, _| { - // Sometimes constants don't propogate all the way to the + // Sometimes constants don't propagate all the way to the // inside of the loop, so we call a custom expression every cycle // rather than iter::repeat(CONST) let base: IntType = $base_macro!(base_iter); From 85aad52ce8b2de4d6b7119812d1daa8717f4b23d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 27 Dec 2024 17:58:16 +0000 Subject: [PATCH 3/8] Make sure there are no registered constraints from creating universal region vids --- compiler/rustc_borrowck/src/type_check/mod.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index c29f3033dd061..f918f005a9b55 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -140,6 +140,12 @@ pub(crate) fn type_check<'a, 'tcx>( &mut constraints, ); + let pre_obligations = infcx.take_registered_region_obligations(); + assert!( + pre_obligations.is_empty(), + "there should be no incoming region obligations = {pre_obligations:#?}", + ); + debug!(?normalized_inputs_and_output); let mut typeck = TypeChecker { From fef8ec5ad9ccd3249d616520e22e43602fa47883 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 27 Dec 2024 13:41:46 -0800 Subject: [PATCH 4/8] Add test of dot after eager statement boundary expr --- tests/ui-fulldeps/pprust-parenthesis-insertion.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs index 94c7964392d1d..8cef9fa13f900 100644 --- a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs +++ b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs @@ -108,6 +108,10 @@ static EXPRS: &[&str] = &[ "{ (match 2 {})() - 1 }", "{ (match 2 {})[0] - 1 }", "{ (loop {}) - 1 }", + "match 2 { _ => (loop {}) - 1 }", + // No eager statement boundary if followed by `.` or `?`. + "{ (loop {}).to_string() - 1 }", // FIXME: no parenthesis needed. + "match 2 { _ => (loop {}).to_string() - 1 }", // FIXME: no parenthesis needed. // Angle bracket is eagerly parsed as a path's generic argument list. "(2 as T) < U", "(2 as T) < V", // FIXME: no parentheses needed. From e67fe3698bfd0f3957abb84c2b396c50822a5b67 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 27 Dec 2024 13:42:25 -0800 Subject: [PATCH 5/8] Skip parenthesis if `.` makes statement boundary unambiguous --- .../rustc_ast_pretty/src/pprust/state/expr.rs | 28 +++++++++++-------- .../src/pprust/state/fixup.rs | 14 ++++++++++ .../pprust-parenthesis-insertion.rs | 4 +-- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index dce76fb1e7707..ab1dd46fe3387 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -245,19 +245,21 @@ impl<'a> State<'a> { base_args: &[P], fixup: FixupContext, ) { - // Unlike in `print_expr_call`, no change to fixup here because + // The fixup here is different than in `print_expr_call` because // statement boundaries never occur in front of a `.` (or `?`) token. // - // match () { _ => f }.method(); + // Needs parens: + // + // (loop { break x; })(); + // + // Does not need parens: + // + // loop { break x; }.method(); // - // Parenthesizing only for precedence and not with regard to statement - // boundaries, `$receiver.method()` can be parsed back as a statement - // containing an expression if and only if `$receiver` can be parsed as - // a statement containing an expression. self.print_expr_cond_paren( receiver, receiver.precedence() < ExprPrecedence::Unambiguous, - fixup, + fixup.leftmost_subexpression_with_dot(), ); self.word("."); @@ -503,7 +505,7 @@ impl<'a> State<'a> { self.print_expr_cond_paren( expr, expr.precedence() < ExprPrecedence::Unambiguous, - fixup, + fixup.leftmost_subexpression_with_dot(), ); self.word_nbsp(".match"); } @@ -567,7 +569,7 @@ impl<'a> State<'a> { self.print_expr_cond_paren( expr, expr.precedence() < ExprPrecedence::Unambiguous, - fixup, + fixup.leftmost_subexpression_with_dot(), ); self.word(".await"); } @@ -606,7 +608,7 @@ impl<'a> State<'a> { self.print_expr_cond_paren( expr, expr.precedence() < ExprPrecedence::Unambiguous, - fixup, + fixup.leftmost_subexpression_with_dot(), ); self.word("."); self.print_ident(*ident); @@ -763,7 +765,11 @@ impl<'a> State<'a> { } } ast::ExprKind::Try(e) => { - self.print_expr_cond_paren(e, e.precedence() < ExprPrecedence::Unambiguous, fixup); + self.print_expr_cond_paren( + e, + e.precedence() < ExprPrecedence::Unambiguous, + fixup.leftmost_subexpression_with_dot(), + ); self.word("?") } ast::ExprKind::TryBlock(blk) => { diff --git a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs index ff466703f7374..3ef21f5cb29eb 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs @@ -138,6 +138,20 @@ impl FixupContext { } } + /// Transform this fixup into the one that should apply when printing a + /// leftmost subexpression followed by a `.` or `?` token, which confer + /// different statement boundary rules compared to other leftmost + /// subexpressions. + pub(crate) fn leftmost_subexpression_with_dot(self) -> Self { + FixupContext { + stmt: self.stmt || self.leftmost_subexpression_in_stmt, + leftmost_subexpression_in_stmt: false, + match_arm: self.match_arm || self.leftmost_subexpression_in_match_arm, + leftmost_subexpression_in_match_arm: false, + ..self + } + } + /// Transform this fixup into the one that should apply when printing any /// subexpression that is neither a leftmost subexpression nor surrounded in /// delimiters. diff --git a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs index 8cef9fa13f900..dc45731dce76f 100644 --- a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs +++ b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs @@ -110,8 +110,8 @@ static EXPRS: &[&str] = &[ "{ (loop {}) - 1 }", "match 2 { _ => (loop {}) - 1 }", // No eager statement boundary if followed by `.` or `?`. - "{ (loop {}).to_string() - 1 }", // FIXME: no parenthesis needed. - "match 2 { _ => (loop {}).to_string() - 1 }", // FIXME: no parenthesis needed. + "{ loop {}.to_string() - 1 }", + "match 2 { _ => loop {}.to_string() - 1 }", // Angle bracket is eagerly parsed as a path's generic argument list. "(2 as T) < U", "(2 as T) < V", // FIXME: no parentheses needed. From c95f9f50de555454cbd931c026814e46793a820a Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 27 Dec 2024 14:18:39 -0800 Subject: [PATCH 6/8] Add pretty-printer test of tuple field function call --- tests/ui-fulldeps/pprust-parenthesis-insertion.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs index 94c7964392d1d..fa9b0300743f3 100644 --- a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs +++ b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs @@ -77,6 +77,9 @@ static EXPRS: &[&str] = &[ // These mean different things. "if let _ = true && false {}", "if let _ = (true && false) {}", + // Parentheses to call a named field, but not an unnamed field. + "(self.fun)()", + "(self.0)()", // FIXME: no parenthesis needed. // Conditions end at the first curly brace, so struct expressions need to be // parenthesized. Except in a match guard, where conditions end at arrow. "if let _ = (Struct {}) {}", From 26bb4e64645d3f3e0ed0b2921738e56888f96fd1 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 27 Dec 2024 14:25:08 -0800 Subject: [PATCH 7/8] Skip parenthesis around tuple struct field calls --- compiler/rustc_ast_pretty/src/pprust/state/expr.rs | 4 +++- compiler/rustc_parse/src/parser/diagnostics.rs | 2 +- compiler/rustc_span/src/symbol.rs | 6 ++++++ tests/ui-fulldeps/pprust-parenthesis-insertion.rs | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index dce76fb1e7707..f7d8edc4743a6 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -213,7 +213,9 @@ impl<'a> State<'a> { fn print_expr_call(&mut self, func: &ast::Expr, args: &[P], fixup: FixupContext) { let needs_paren = match func.kind { - ast::ExprKind::Field(..) => true, + // In order to call a named field, needs parens: `(self.fun)()` + // But not for an unnamed field: `self.0()` + ast::ExprKind::Field(_, name) => !name.is_numeric(), _ => func.precedence() < ExprPrecedence::Unambiguous, }; diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index aab4e1b1afc1b..7df7e7329252c 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1336,7 +1336,7 @@ impl<'a> Parser<'a> { ) -> bool { if let ExprKind::Binary(op, l1, r1) = &inner_op.kind { if let ExprKind::Field(_, ident) = l1.kind - && ident.as_str().parse::().is_err() + && !ident.is_numeric() && !matches!(r1.kind, ExprKind::Lit(_)) { // The parser has encountered `foo.bar bool { self.name.can_be_raw() && self.is_reserved() } + + /// Whether this would be the identifier for a tuple field like `self.0`, as + /// opposed to a named field like `self.thing`. + pub fn is_numeric(self) -> bool { + !self.name.is_empty() && self.as_str().bytes().all(|b| b.is_ascii_digit()) + } } /// Collect all the keywords in a given edition into a vector. diff --git a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs index fa9b0300743f3..2697c5f66ce78 100644 --- a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs +++ b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs @@ -79,7 +79,7 @@ static EXPRS: &[&str] = &[ "if let _ = (true && false) {}", // Parentheses to call a named field, but not an unnamed field. "(self.fun)()", - "(self.0)()", // FIXME: no parenthesis needed. + "self.0()", // Conditions end at the first curly brace, so struct expressions need to be // parenthesized. Except in a match guard, where conditions end at arrow. "if let _ = (Struct {}) {}", From bc054245283069d3b273f22773a3c3425aff07bd Mon Sep 17 00:00:00 2001 From: chloefeal <188809157+chloefeal@users.noreply.github.com> Date: Sat, 28 Dec 2024 10:37:02 +0800 Subject: [PATCH 8/8] Update library/alloc/tests/sort/tests.rs Co-authored-by: David Tolnay --- library/alloc/tests/sort/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/tests/sort/tests.rs b/library/alloc/tests/sort/tests.rs index 206624e59ea53..4cc79010e8fed 100644 --- a/library/alloc/tests/sort/tests.rs +++ b/library/alloc/tests/sort/tests.rs @@ -33,7 +33,7 @@ fn check_is_sorted(v: &mut [T]) { known_good_stable_sort::sort(known_good_sorted_vec.as_mut_slice()); if is_small_test { - eprintln!("Original: {:?}", v_orig); + eprintln!("Original: {:?}", v_orig); eprintln!("Expected: {:?}", known_good_sorted_vec); eprintln!("Got: {:?}", v); } else {