Skip to content

Commit 3e7bfbe

Browse files
Auto merge of #150912 - matthiaskrgr:rollup-SHXgjYS, r=matthiaskrgr
Rollup of 11 pull requests Successful merges: - #150269 (Remove inactive nvptx maintainer) - #150713 (mgca: Type-check fields of struct expr const args) - #150765 (rustc_parse_format: improve error for missing `:` before `?` in format args) - #150847 (Fix broken documentation links to SipHash) - #150867 (rustdoc_json: Remove one call to `std::mem::take` in `after_krate`) - #150872 (Fix some loop block coercion diagnostics) - #150874 (Ignore `rustc-src-gpl` in fast try builds) - #150875 (Refactor artifact keep mode in bootstrap) - #150876 (Mention that `rustc_codegen_gcc` is a subtree in `rustc-dev-guide`) - #150882 (Supress unused_parens lint for guard patterns) - #150884 (Update bors email in CI postprocessing step) Failed merges: - #150869 (Emit error instead of delayed bug when meeting mismatch type for const tuple) r? @ghost
2 parents 1b9ae9e + 9399309 commit 3e7bfbe

File tree

34 files changed

+495
-123
lines changed

34 files changed

+495
-123
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ jobs:
289289
fi
290290
291291
# Get closest bors merge commit
292-
PARENT_COMMIT=`git rev-list --author='bors <bors@rust-lang.org>' -n1 --first-parent HEAD^1`
292+
PARENT_COMMIT=`git rev-list --author='122020455+rust-bors\[bot\]@users.noreply.github.com' -n1 --first-parent HEAD^1`
293293
294294
./build/citool/debug/citool postprocess-metrics \
295295
--job-name ${CI_JOB_NAME} \

compiler/rustc_builtin_macros/messages.ftl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,8 @@ builtin_macros_expected_other = expected operand, {$is_inline_asm ->
182182
183183
builtin_macros_export_macro_rules = cannot export macro_rules! macros from a `proc-macro` crate type currently
184184
185+
builtin_macros_format_add_missing_colon = add a colon before the format specifier
186+
185187
builtin_macros_format_duplicate_arg = duplicate argument named `{$ident}`
186188
.label1 = previously here
187189
.label2 = duplicate argument

compiler/rustc_builtin_macros/src/errors.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,15 @@ pub(crate) enum InvalidFormatStringSuggestion {
643643
span: Span,
644644
replacement: String,
645645
},
646+
#[suggestion(
647+
builtin_macros_format_add_missing_colon,
648+
code = ":?",
649+
applicability = "machine-applicable"
650+
)]
651+
AddMissingColon {
652+
#[primary_span]
653+
span: Span,
654+
},
646655
}
647656

648657
#[derive(Diagnostic)]

compiler/rustc_builtin_macros/src/format.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,10 @@ fn make_format_args(
329329
replacement,
330330
});
331331
}
332+
parse::Suggestion::AddMissingColon(span) => {
333+
let span = fmt_span.from_inner(InnerSpan::new(span.start, span.end));
334+
e.sugg_ = Some(errors::InvalidFormatStringSuggestion::AddMissingColon { span });
335+
}
332336
}
333337
let guar = ecx.dcx().emit_err(e);
334338
return ExpandResult::Ready(Err(guar));

compiler/rustc_hir_typeck/src/coercion.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ use rustc_middle::ty::adjustment::{
5454
};
5555
use rustc_middle::ty::error::TypeError;
5656
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
57-
use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Span};
57+
use rustc_span::{BytePos, DUMMY_SP, Span};
5858
use rustc_trait_selection::infer::InferCtxtExt as _;
5959
use rustc_trait_selection::solve::inspect::{self, InferCtxtProofTreeExt, ProofTreeVisitor};
6060
use rustc_trait_selection::solve::{Certainty, Goal, NoSolution};
@@ -1828,10 +1828,9 @@ impl<'tcx> CoerceMany<'tcx> {
18281828
// If the block is from an external macro or try (`?`) desugaring, then
18291829
// do not suggest adding a semicolon, because there's nowhere to put it.
18301830
// See issues #81943 and #87051.
1831-
&& matches!(
1832-
cond_expr.span.desugaring_kind(),
1833-
None | Some(DesugaringKind::WhileLoop)
1834-
)
1831+
// Similarly, if the block is from a loop desugaring, then also do not
1832+
// suggest adding a semicolon. See issue #150850.
1833+
&& cond_expr.span.desugaring_kind().is_none()
18351834
&& !cond_expr.span.in_external_macro(fcx.tcx.sess.source_map())
18361835
&& !matches!(
18371836
cond_expr.kind,

compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
1010
use rustc_hir::lang_items::LangItem;
1111
use rustc_hir::{
1212
self as hir, Arm, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind,
13-
GenericBound, HirId, Node, PatExpr, PatExprKind, Path, QPath, Stmt, StmtKind, TyKind,
14-
WherePredicateKind, expr_needs_parens, is_range_literal,
13+
GenericBound, HirId, LoopSource, Node, PatExpr, PatExprKind, Path, QPath, Stmt, StmtKind,
14+
TyKind, WherePredicateKind, expr_needs_parens, is_range_literal,
1515
};
1616
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
1717
use rustc_hir_analysis::suggest_impl_trait;
@@ -1170,23 +1170,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11701170
}
11711171
let found = self.resolve_vars_if_possible(found);
11721172

1173-
let in_loop = self.is_loop(id)
1174-
|| self
1175-
.tcx
1173+
let innermost_loop = if self.is_loop(id) {
1174+
Some(self.tcx.hir_node(id))
1175+
} else {
1176+
self.tcx
11761177
.hir_parent_iter(id)
11771178
.take_while(|(_, node)| {
11781179
// look at parents until we find the first body owner
11791180
node.body_id().is_none()
11801181
})
1181-
.any(|(parent_id, _)| self.is_loop(parent_id));
1182+
.find_map(|(parent_id, node)| self.is_loop(parent_id).then_some(node))
1183+
};
1184+
let can_break_with_value = innermost_loop.is_some_and(|node| {
1185+
matches!(
1186+
node,
1187+
Node::Expr(Expr { kind: ExprKind::Loop(_, _, LoopSource::Loop, ..), .. })
1188+
)
1189+
});
11821190

11831191
let in_local_statement = self.is_local_statement(id)
11841192
|| self
11851193
.tcx
11861194
.hir_parent_iter(id)
11871195
.any(|(parent_id, _)| self.is_local_statement(parent_id));
11881196

1189-
if in_loop && in_local_statement {
1197+
if can_break_with_value && in_local_statement {
11901198
err.multipart_suggestion(
11911199
"you might have meant to break the loop with this value",
11921200
vec![

compiler/rustc_lint/src/unused.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,6 +1190,8 @@ impl UnusedParens {
11901190
// `&(a..=b)`, there is a recursive `check_pat` on `a` and `b`, but we will assume
11911191
// that if there are unnecessary parens they serve a purpose of readability.
11921192
PatKind::Range(..) => return,
1193+
// Parentheses may be necessary to disambiguate precedence in guard patterns.
1194+
PatKind::Guard(..) => return,
11931195
// Avoid `p0 | .. | pn` if we should.
11941196
PatKind::Or(..) if avoid_or => return,
11951197
// Avoid `mut x` and `mut x @ p` if we should:

compiler/rustc_middle/src/ty/consts/valtree.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,7 @@ impl<'tcx> Value<'tcx> {
191191
}
192192
}
193193

194-
/// Destructures array, ADT or tuple constants into the constants
195-
/// of their fields.
194+
/// Destructures ADT constants into the constants of their fields.
196195
pub fn destructure_adt_const(&self) -> ty::DestructuredAdtConst<'tcx> {
197196
let fields = self.to_branch();
198197

compiler/rustc_parse_format/src/lib.rs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,9 @@ pub enum Suggestion {
184184
/// `format!("{foo:?x}")` -> `format!("{foo:x?}")`
185185
/// `format!("{foo:?X}")` -> `format!("{foo:X?}")`
186186
ReorderFormatParameter(Range<usize>, String),
187+
/// Add missing colon:
188+
/// `format!("{foo?}")` -> `format!("{foo:?}")`
189+
AddMissingColon(Range<usize>),
187190
}
188191

189192
/// The parser structure for interpreting the input format string. This is
@@ -453,10 +456,11 @@ impl<'input> Parser<'input> {
453456
suggestion: Suggestion::None,
454457
});
455458

456-
if let Some((_, _, c)) = self.peek() {
457-
match c {
458-
'?' => self.suggest_format_debug(),
459-
'<' | '^' | '>' => self.suggest_format_align(c),
459+
if let (Some((_, _, c)), Some((_, _, nc))) = (self.peek(), self.peek_ahead()) {
460+
match (c, nc) {
461+
('?', '}') => self.missing_colon_before_debug_formatter(),
462+
('?', _) => self.suggest_format_debug(),
463+
('<' | '^' | '>', _) => self.suggest_format_align(c),
460464
_ => self.suggest_positional_arg_instead_of_captured_arg(arg),
461465
}
462466
}
@@ -849,6 +853,23 @@ impl<'input> Parser<'input> {
849853
}
850854
}
851855

856+
fn missing_colon_before_debug_formatter(&mut self) {
857+
if let Some((range, _)) = self.consume_pos('?') {
858+
let span = range.clone();
859+
self.errors.insert(
860+
0,
861+
ParseError {
862+
description: "expected `}`, found `?`".to_owned(),
863+
note: Some(format!("to print `{{`, you can escape it using `{{{{`",)),
864+
label: "expected `:` before `?` to format with `Debug`".to_owned(),
865+
span: range,
866+
secondary_label: None,
867+
suggestion: Suggestion::AddMissingColon(span),
868+
},
869+
);
870+
}
871+
}
872+
852873
fn suggest_format_align(&mut self, alignment: char) {
853874
if let Some((range, _)) = self.consume_pos(alignment) {
854875
self.errors.insert(

compiler/rustc_trait_selection/src/traits/wf.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1051,7 +1051,53 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
10511051
| ty::ConstKind::Placeholder(..) => {
10521052
// These variants are trivially WF, so nothing to do here.
10531053
}
1054-
ty::ConstKind::Value(..) => {
1054+
ty::ConstKind::Value(val) => {
1055+
// FIXME(mgca): no need to feature-gate once valtree lifetimes are not erased
1056+
if tcx.features().min_generic_const_args() {
1057+
match val.ty.kind() {
1058+
ty::Adt(adt_def, args) => {
1059+
let adt_val = val.destructure_adt_const();
1060+
let variant_def = adt_def.variant(adt_val.variant);
1061+
let cause = self.cause(ObligationCauseCode::WellFormed(None));
1062+
self.out.extend(variant_def.fields.iter().zip(adt_val.fields).map(
1063+
|(field_def, &field_val)| {
1064+
let field_ty =
1065+
tcx.type_of(field_def.did).instantiate(tcx, args);
1066+
let predicate = ty::PredicateKind::Clause(
1067+
ty::ClauseKind::ConstArgHasType(field_val, field_ty),
1068+
);
1069+
traits::Obligation::with_depth(
1070+
tcx,
1071+
cause.clone(),
1072+
self.recursion_depth,
1073+
self.param_env,
1074+
predicate,
1075+
)
1076+
},
1077+
));
1078+
}
1079+
ty::Tuple(field_tys) => {
1080+
let field_vals = val.to_branch();
1081+
let cause = self.cause(ObligationCauseCode::WellFormed(None));
1082+
self.out.extend(field_tys.iter().zip(field_vals).map(
1083+
|(field_ty, &field_val)| {
1084+
let predicate = ty::PredicateKind::Clause(
1085+
ty::ClauseKind::ConstArgHasType(field_val, field_ty),
1086+
);
1087+
traits::Obligation::with_depth(
1088+
tcx,
1089+
cause.clone(),
1090+
self.recursion_depth,
1091+
self.param_env,
1092+
predicate,
1093+
)
1094+
},
1095+
));
1096+
}
1097+
_ => {}
1098+
}
1099+
}
1100+
10551101
// FIXME: Enforce that values are structurally-matchable.
10561102
}
10571103
}

0 commit comments

Comments
 (0)