Skip to content

Commit a6269da

Browse files
committed
Auto merge of #107106 - matthiaskrgr:rollup-g7r1ep0, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #106699 ([drop tracking] Visit break expressions ) - #106738 (Fix known-bug annotations) - #106891 (Tweak "borrow closure argument" suggestion) - #106928 (add raw identifier for keyword in suggestion) - #107065 (Clippy: Make sure to include in beta: Move `unchecked_duration_subtraction` to pedantic) - #107068 (autoderive Subdiagnostic for AddtoExternBlockSuggestion) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 04a41f8 + c44c60c commit a6269da

31 files changed

+278
-132
lines changed

compiler/rustc_ast_passes/src/ast_validation.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -1100,16 +1100,17 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
11001100
replace_span: self.ending_semi_or_hi(item.span),
11011101
extern_block_suggestion: match sig.header.ext {
11021102
Extern::None => None,
1103-
Extern::Implicit(start_span) => Some(ExternBlockSuggestion {
1103+
Extern::Implicit(start_span) => Some(ExternBlockSuggestion::Implicit {
11041104
start_span,
11051105
end_span: item.span.shrink_to_hi(),
1106-
abi: None,
1107-
}),
1108-
Extern::Explicit(abi, start_span) => Some(ExternBlockSuggestion {
1109-
start_span,
1110-
end_span: item.span.shrink_to_hi(),
1111-
abi: Some(abi.symbol_unescaped),
11121106
}),
1107+
Extern::Explicit(abi, start_span) => {
1108+
Some(ExternBlockSuggestion::Explicit {
1109+
start_span,
1110+
end_span: item.span.shrink_to_hi(),
1111+
abi: abi.symbol_unescaped,
1112+
})
1113+
}
11131114
},
11141115
});
11151116
}

compiler/rustc_ast_passes/src/errors.rs

+17-25
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
//! Errors emitted by ast_passes.
22
3-
use rustc_errors::{fluent, AddToDiagnostic, Applicability, Diagnostic, SubdiagnosticMessage};
43
use rustc_macros::{Diagnostic, Subdiagnostic};
54
use rustc_span::{Span, Symbol};
65

@@ -207,28 +206,21 @@ pub struct FnWithoutBody {
207206
pub extern_block_suggestion: Option<ExternBlockSuggestion>,
208207
}
209208

210-
pub struct ExternBlockSuggestion {
211-
pub start_span: Span,
212-
pub end_span: Span,
213-
pub abi: Option<Symbol>,
214-
}
215-
216-
impl AddToDiagnostic for ExternBlockSuggestion {
217-
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
218-
where
219-
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
220-
{
221-
let start_suggestion = if let Some(abi) = self.abi {
222-
format!("extern \"{}\" {{", abi)
223-
} else {
224-
"extern {".to_owned()
225-
};
226-
let end_suggestion = " }".to_owned();
227-
228-
diag.multipart_suggestion(
229-
fluent::extern_block_suggestion,
230-
vec![(self.start_span, start_suggestion), (self.end_span, end_suggestion)],
231-
Applicability::MaybeIncorrect,
232-
);
233-
}
209+
#[derive(Subdiagnostic)]
210+
pub enum ExternBlockSuggestion {
211+
#[multipart_suggestion(ast_passes_extern_block_suggestion, applicability = "maybe-incorrect")]
212+
Implicit {
213+
#[suggestion_part(code = "extern {{")]
214+
start_span: Span,
215+
#[suggestion_part(code = " }}")]
216+
end_span: Span,
217+
},
218+
#[multipart_suggestion(ast_passes_extern_block_suggestion, applicability = "maybe-incorrect")]
219+
Explicit {
220+
#[suggestion_part(code = "extern \"{abi}\" {{")]
221+
start_span: Span,
222+
#[suggestion_part(code = " }}")]
223+
end_span: Span,
224+
abi: Symbol,
225+
},
234226
}

compiler/rustc_error_messages/locales/en-US/ast_passes.ftl

+2-1
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,5 @@ ast_passes_ty_alias_without_body =
8888
ast_passes_fn_without_body =
8989
free function without a body
9090
.suggestion = provide a definition for the function
91-
.extern_block_suggestion = if you meant to declare an externally defined function, use an `extern` block
91+
92+
ast_passes_extern_block_suggestion = if you meant to declare an externally defined function, use an `extern` block

compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs

+17-4
Original file line numberDiff line numberDiff line change
@@ -304,8 +304,8 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> {
304304
let mut reinit = None;
305305
match expr.kind {
306306
ExprKind::Assign(lhs, rhs, _) => {
307-
self.visit_expr(lhs);
308307
self.visit_expr(rhs);
308+
self.visit_expr(lhs);
309309

310310
reinit = Some(lhs);
311311
}
@@ -433,7 +433,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> {
433433
self.drop_ranges.add_control_edge(self.expr_index, *target)
434434
}),
435435

436-
ExprKind::Break(destination, ..) => {
436+
ExprKind::Break(destination, value) => {
437437
// destination either points to an expression or to a block. We use
438438
// find_target_expression_from_destination to use the last expression of the block
439439
// if destination points to a block.
@@ -443,7 +443,11 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> {
443443
// will refer to the end of the block due to the post order traversal.
444444
self.find_target_expression_from_destination(destination).map_or((), |target| {
445445
self.drop_ranges.add_control_edge_hir_id(self.expr_index, target)
446-
})
446+
});
447+
448+
if let Some(value) = value {
449+
self.visit_expr(value);
450+
}
447451
}
448452

449453
ExprKind::Call(f, args) => {
@@ -465,6 +469,12 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> {
465469

466470
ExprKind::AddrOf(..)
467471
| ExprKind::Array(..)
472+
// FIXME(eholk): We probably need special handling for AssignOps. The ScopeTree builder
473+
// in region.rs runs both lhs then rhs and rhs then lhs and then sets all yields to be
474+
// the latest they show up in either traversal. With the older scope-based
475+
// approximation, this was fine, but it's probably not right now. What we probably want
476+
// to do instead is still run both orders, but consider anything that showed up as a
477+
// yield in either order.
468478
| ExprKind::AssignOp(..)
469479
| ExprKind::Binary(..)
470480
| ExprKind::Block(..)
@@ -502,6 +512,9 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> {
502512

503513
// Increment expr_count here to match what InteriorVisitor expects.
504514
self.expr_index = self.expr_index + 1;
515+
516+
// Save a node mapping to get better CFG visualization
517+
self.drop_ranges.add_node_mapping(pat.hir_id, self.expr_index);
505518
}
506519
}
507520

@@ -521,7 +534,7 @@ impl DropRangesBuilder {
521534
}
522535
});
523536
}
524-
debug!("hir_id_map: {:?}", tracked_value_map);
537+
debug!("hir_id_map: {:#?}", tracked_value_map);
525538
let num_values = tracked_value_map.len();
526539
Self {
527540
tracked_value_map,

compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_visualize.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
//! flow graph when needed for debugging.
33
44
use rustc_graphviz as dot;
5+
use rustc_hir::{Expr, ExprKind, Node};
56
use rustc_middle::ty::TyCtxt;
67

78
use super::{DropRangesBuilder, PostOrderId};
@@ -80,10 +81,14 @@ impl<'a> dot::Labeller<'a> for DropRangesGraph<'_, '_> {
8081
.post_order_map
8182
.iter()
8283
.find(|(_hir_id, &post_order_id)| post_order_id == *n)
83-
.map_or("<unknown>".into(), |(hir_id, _)| self
84-
.tcx
85-
.hir()
86-
.node_to_string(*hir_id))
84+
.map_or("<unknown>".into(), |(hir_id, _)| format!(
85+
"{}{}",
86+
self.tcx.hir().node_to_string(*hir_id),
87+
match self.tcx.hir().find(*hir_id) {
88+
Some(Node::Expr(Expr { kind: ExprKind::Yield(..), .. })) => " (yield)",
89+
_ => "",
90+
}
91+
))
8792
)
8893
.into(),
8994
)

compiler/rustc_hir_typeck/src/generator_interior/mod.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,8 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
7171
yield_data.expr_and_pat_count, self.expr_count, source_span
7272
);
7373

74-
if self.fcx.sess().opts.unstable_opts.drop_tracking
75-
&& self
76-
.drop_ranges
77-
.is_dropped_at(hir_id, yield_data.expr_and_pat_count)
74+
if self
75+
.is_dropped_at_yield_location(hir_id, yield_data.expr_and_pat_count)
7876
{
7977
debug!("value is dropped at yield point; not recording");
8078
return false;
@@ -173,6 +171,18 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
173171
}
174172
}
175173
}
174+
175+
/// If drop tracking is enabled, consult drop_ranges to see if a value is
176+
/// known to be dropped at a yield point and therefore can be omitted from
177+
/// the generator witness.
178+
fn is_dropped_at_yield_location(&self, value_hir_id: HirId, yield_location: usize) -> bool {
179+
// short-circuit if drop tracking is not enabled.
180+
if !self.fcx.sess().opts.unstable_opts.drop_tracking {
181+
return false;
182+
}
183+
184+
self.drop_ranges.is_dropped_at(value_hir_id, yield_location)
185+
}
176186
}
177187

178188
pub fn resolve_interior<'a, 'tcx>(

compiler/rustc_middle/src/ty/print/pretty.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ pub trait PrettyPrinter<'tcx>:
393393
match self.tcx().trimmed_def_paths(()).get(&def_id) {
394394
None => Ok((self, false)),
395395
Some(symbol) => {
396-
self.write_str(symbol.as_str())?;
396+
write!(self, "{}", Ident::with_dummy_span(*symbol))?;
397397
Ok((self, true))
398398
}
399399
}

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1350,6 +1350,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
13501350
expected_trait_ref,
13511351
obligation.cause.code(),
13521352
found_node,
1353+
obligation.param_env,
13531354
)
13541355
} else {
13551356
let (closure_span, closure_arg_span, found) = found_did

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+25-8
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ pub trait TypeErrCtxtExt<'tcx> {
283283
expected: ty::PolyTraitRef<'tcx>,
284284
cause: &ObligationCauseCode<'tcx>,
285285
found_node: Option<Node<'_>>,
286+
param_env: ty::ParamEnv<'tcx>,
286287
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>;
287288

288289
fn note_conflicting_closure_bounds(
@@ -1978,6 +1979,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
19781979
expected: ty::PolyTraitRef<'tcx>,
19791980
cause: &ObligationCauseCode<'tcx>,
19801981
found_node: Option<Node<'_>>,
1982+
param_env: ty::ParamEnv<'tcx>,
19811983
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
19821984
pub(crate) fn build_fn_sig_ty<'tcx>(
19831985
infcx: &InferCtxt<'tcx>,
@@ -2040,7 +2042,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
20402042
self.note_conflicting_closure_bounds(cause, &mut err);
20412043

20422044
if let Some(found_node) = found_node {
2043-
hint_missing_borrow(span, found, expected, found_node, &mut err);
2045+
hint_missing_borrow(self, param_env, span, found, expected, found_node, &mut err);
20442046
}
20452047

20462048
err
@@ -3747,6 +3749,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
37473749

37483750
/// Add a hint to add a missing borrow or remove an unnecessary one.
37493751
fn hint_missing_borrow<'tcx>(
3752+
infcx: &InferCtxt<'tcx>,
3753+
param_env: ty::ParamEnv<'tcx>,
37503754
span: Span,
37513755
found: Ty<'tcx>,
37523756
expected: Ty<'tcx>,
@@ -3769,7 +3773,7 @@ fn hint_missing_borrow<'tcx>(
37693773
// This could be a variant constructor, for example.
37703774
let Some(fn_decl) = found_node.fn_decl() else { return; };
37713775

3772-
let arg_spans = fn_decl.inputs.iter().map(|ty| ty.span);
3776+
let args = fn_decl.inputs.iter().map(|ty| ty);
37733777

37743778
fn get_deref_type_and_refs(mut ty: Ty<'_>) -> (Ty<'_>, usize) {
37753779
let mut refs = 0;
@@ -3785,29 +3789,42 @@ fn hint_missing_borrow<'tcx>(
37853789
let mut to_borrow = Vec::new();
37863790
let mut remove_borrow = Vec::new();
37873791

3788-
for ((found_arg, expected_arg), arg_span) in found_args.zip(expected_args).zip(arg_spans) {
3792+
for ((found_arg, expected_arg), arg) in found_args.zip(expected_args).zip(args) {
37893793
let (found_ty, found_refs) = get_deref_type_and_refs(*found_arg);
37903794
let (expected_ty, expected_refs) = get_deref_type_and_refs(*expected_arg);
37913795

3792-
if found_ty == expected_ty {
3796+
if infcx.can_eq(param_env, found_ty, expected_ty).is_ok() {
37933797
if found_refs < expected_refs {
3794-
to_borrow.push((arg_span, expected_arg.to_string()));
3798+
to_borrow.push((arg.span.shrink_to_lo(), "&".repeat(expected_refs - found_refs)));
37953799
} else if found_refs > expected_refs {
3796-
remove_borrow.push((arg_span, expected_arg.to_string()));
3800+
let mut span = arg.span.shrink_to_lo();
3801+
let mut left = found_refs - expected_refs;
3802+
let mut ty = arg;
3803+
while let hir::TyKind::Ref(_, mut_ty) = &ty.kind && left > 0 {
3804+
span = span.with_hi(mut_ty.ty.span.lo());
3805+
ty = mut_ty.ty;
3806+
left -= 1;
3807+
}
3808+
let sugg = if left == 0 {
3809+
(span, String::new())
3810+
} else {
3811+
(arg.span, expected_arg.to_string())
3812+
};
3813+
remove_borrow.push(sugg);
37973814
}
37983815
}
37993816
}
38003817

38013818
if !to_borrow.is_empty() {
3802-
err.multipart_suggestion(
3819+
err.multipart_suggestion_verbose(
38033820
"consider borrowing the argument",
38043821
to_borrow,
38053822
Applicability::MaybeIncorrect,
38063823
);
38073824
}
38083825

38093826
if !remove_borrow.is_empty() {
3810-
err.multipart_suggestion(
3827+
err.multipart_suggestion_verbose(
38113828
"do not borrow the argument",
38123829
remove_borrow,
38133830
Applicability::MaybeIncorrect,

src/tools/clippy/clippy_lints/src/instant_subtraction.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ declare_clippy_lint! {
6161
/// [`Instant::now()`]: std::time::Instant::now;
6262
#[clippy::version = "1.65.0"]
6363
pub UNCHECKED_DURATION_SUBTRACTION,
64-
suspicious,
64+
pedantic,
6565
"finds unchecked subtraction of a 'Duration' from an 'Instant'"
6666
}
6767

src/tools/compiletest/src/header.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -426,10 +426,15 @@ impl TestProps {
426426
self.known_bug = true;
427427
} else {
428428
panic!(
429-
"Invalid known-bug value: {known_bug}\nIt requires comma-separated issue references (`#000` or `chalk#000`) or `unknown`."
429+
"Invalid known-bug value: {known_bug}\nIt requires comma-separated issue references (`#000` or `chalk#000`) or `known-bug: unknown`."
430430
);
431431
}
432+
} else if config.parse_name_directive(ln, KNOWN_BUG) {
433+
panic!(
434+
"Invalid known-bug attribute, requires comma-separated issue references (`#000` or `chalk#000`) or `known-bug: unknown`."
435+
);
432436
}
437+
433438
config.set_name_value_directive(ln, MIR_UNIT_TEST, &mut self.mir_unit_test, |s| {
434439
s.trim().to_string()
435440
});

0 commit comments

Comments
 (0)