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

Rollup of 4 pull requests #134837

Closed
wants to merge 11 commits into from
32 changes: 20 additions & 12 deletions compiler/rustc_ast_pretty/src/pprust/state/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,9 @@ impl<'a> State<'a> {

fn print_expr_call(&mut self, func: &ast::Expr, args: &[P<ast::Expr>], 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,
};

Expand Down Expand Up @@ -245,19 +247,21 @@ impl<'a> State<'a> {
base_args: &[P<ast::Expr>],
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(".");
Expand Down Expand Up @@ -503,7 +507,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");
}
Expand Down Expand Up @@ -567,7 +571,7 @@ impl<'a> State<'a> {
self.print_expr_cond_paren(
expr,
expr.precedence() < ExprPrecedence::Unambiguous,
fixup,
fixup.leftmost_subexpression_with_dot(),
);
self.word(".await");
}
Expand Down Expand Up @@ -606,7 +610,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);
Expand Down Expand Up @@ -763,7 +767,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) => {
Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_ast_pretty/src/pprust/state/fixup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_infer/src/infer/region_constraints/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_llvm/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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") {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/src/check_tail_calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_parse/src/parser/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<i32>().is_err()
&& !ident.is_numeric()
&& !matches!(r1.kind, ExprKind::Lit(_))
{
// The parser has encountered `foo.bar<baz`, the likelihood of the turbofish
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2708,6 +2708,12 @@ impl Ident {
pub fn is_raw_guess(self) -> 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.
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_trait_selection/src/traits/auto_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(&region_data);

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
2 changes: 1 addition & 1 deletion library/alloc/tests/sort/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ fn check_is_sorted<T: Ord + Clone + Debug, S: Sort>(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 {
Expand Down
2 changes: 1 addition & 1 deletion library/core/benches/num/int_pow/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
7 changes: 7 additions & 0 deletions tests/ui-fulldeps/pprust-parenthesis-insertion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()",
// 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 {}) {}",
Expand Down Expand Up @@ -108,6 +111,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 }",
"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<U>) < V", // FIXME: no parentheses needed.
Expand Down
Loading