Skip to content

Commit

Permalink
Auto merge of #107106 - matthiaskrgr:rollup-g7r1ep0, r=matthiaskrgr
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Jan 20, 2023
2 parents 04a41f8 + c44c60c commit a6269da
Show file tree
Hide file tree
Showing 31 changed files with 278 additions and 132 deletions.
15 changes: 8 additions & 7 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1100,16 +1100,17 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
replace_span: self.ending_semi_or_hi(item.span),
extern_block_suggestion: match sig.header.ext {
Extern::None => None,
Extern::Implicit(start_span) => Some(ExternBlockSuggestion {
Extern::Implicit(start_span) => Some(ExternBlockSuggestion::Implicit {
start_span,
end_span: item.span.shrink_to_hi(),
abi: None,
}),
Extern::Explicit(abi, start_span) => Some(ExternBlockSuggestion {
start_span,
end_span: item.span.shrink_to_hi(),
abi: Some(abi.symbol_unescaped),
}),
Extern::Explicit(abi, start_span) => {
Some(ExternBlockSuggestion::Explicit {
start_span,
end_span: item.span.shrink_to_hi(),
abi: abi.symbol_unescaped,
})
}
},
});
}
Expand Down
42 changes: 17 additions & 25 deletions compiler/rustc_ast_passes/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//! Errors emitted by ast_passes.

use rustc_errors::{fluent, AddToDiagnostic, Applicability, Diagnostic, SubdiagnosticMessage};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::{Span, Symbol};

Expand Down Expand Up @@ -207,28 +206,21 @@ pub struct FnWithoutBody {
pub extern_block_suggestion: Option<ExternBlockSuggestion>,
}

pub struct ExternBlockSuggestion {
pub start_span: Span,
pub end_span: Span,
pub abi: Option<Symbol>,
}

impl AddToDiagnostic for ExternBlockSuggestion {
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
where
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
{
let start_suggestion = if let Some(abi) = self.abi {
format!("extern \"{}\" {{", abi)
} else {
"extern {".to_owned()
};
let end_suggestion = " }".to_owned();

diag.multipart_suggestion(
fluent::extern_block_suggestion,
vec![(self.start_span, start_suggestion), (self.end_span, end_suggestion)],
Applicability::MaybeIncorrect,
);
}
#[derive(Subdiagnostic)]
pub enum ExternBlockSuggestion {
#[multipart_suggestion(ast_passes_extern_block_suggestion, applicability = "maybe-incorrect")]
Implicit {
#[suggestion_part(code = "extern {{")]
start_span: Span,
#[suggestion_part(code = " }}")]
end_span: Span,
},
#[multipart_suggestion(ast_passes_extern_block_suggestion, applicability = "maybe-incorrect")]
Explicit {
#[suggestion_part(code = "extern \"{abi}\" {{")]
start_span: Span,
#[suggestion_part(code = " }}")]
end_span: Span,
abi: Symbol,
},
}
3 changes: 2 additions & 1 deletion compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,5 @@ ast_passes_ty_alias_without_body =
ast_passes_fn_without_body =
free function without a body
.suggestion = provide a definition for the function
.extern_block_suggestion = if you meant to declare an externally defined function, use an `extern` block
ast_passes_extern_block_suggestion = if you meant to declare an externally defined function, use an `extern` block
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,8 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> {
let mut reinit = None;
match expr.kind {
ExprKind::Assign(lhs, rhs, _) => {
self.visit_expr(lhs);
self.visit_expr(rhs);
self.visit_expr(lhs);

reinit = Some(lhs);
}
Expand Down Expand Up @@ -433,7 +433,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> {
self.drop_ranges.add_control_edge(self.expr_index, *target)
}),

ExprKind::Break(destination, ..) => {
ExprKind::Break(destination, value) => {
// destination either points to an expression or to a block. We use
// find_target_expression_from_destination to use the last expression of the block
// if destination points to a block.
Expand All @@ -443,7 +443,11 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> {
// will refer to the end of the block due to the post order traversal.
self.find_target_expression_from_destination(destination).map_or((), |target| {
self.drop_ranges.add_control_edge_hir_id(self.expr_index, target)
})
});

if let Some(value) = value {
self.visit_expr(value);
}
}

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

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

// Increment expr_count here to match what InteriorVisitor expects.
self.expr_index = self.expr_index + 1;

// Save a node mapping to get better CFG visualization
self.drop_ranges.add_node_mapping(pat.hir_id, self.expr_index);
}
}

Expand All @@ -521,7 +534,7 @@ impl DropRangesBuilder {
}
});
}
debug!("hir_id_map: {:?}", tracked_value_map);
debug!("hir_id_map: {:#?}", tracked_value_map);
let num_values = tracked_value_map.len();
Self {
tracked_value_map,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//! flow graph when needed for debugging.

use rustc_graphviz as dot;
use rustc_hir::{Expr, ExprKind, Node};
use rustc_middle::ty::TyCtxt;

use super::{DropRangesBuilder, PostOrderId};
Expand Down Expand Up @@ -80,10 +81,14 @@ impl<'a> dot::Labeller<'a> for DropRangesGraph<'_, '_> {
.post_order_map
.iter()
.find(|(_hir_id, &post_order_id)| post_order_id == *n)
.map_or("<unknown>".into(), |(hir_id, _)| self
.tcx
.hir()
.node_to_string(*hir_id))
.map_or("<unknown>".into(), |(hir_id, _)| format!(
"{}{}",
self.tcx.hir().node_to_string(*hir_id),
match self.tcx.hir().find(*hir_id) {
Some(Node::Expr(Expr { kind: ExprKind::Yield(..), .. })) => " (yield)",
_ => "",
}
))
)
.into(),
)
Expand Down
18 changes: 14 additions & 4 deletions compiler/rustc_hir_typeck/src/generator_interior/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,8 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
yield_data.expr_and_pat_count, self.expr_count, source_span
);

if self.fcx.sess().opts.unstable_opts.drop_tracking
&& self
.drop_ranges
.is_dropped_at(hir_id, yield_data.expr_and_pat_count)
if self
.is_dropped_at_yield_location(hir_id, yield_data.expr_and_pat_count)
{
debug!("value is dropped at yield point; not recording");
return false;
Expand Down Expand Up @@ -173,6 +171,18 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
}
}
}

/// If drop tracking is enabled, consult drop_ranges to see if a value is
/// known to be dropped at a yield point and therefore can be omitted from
/// the generator witness.
fn is_dropped_at_yield_location(&self, value_hir_id: HirId, yield_location: usize) -> bool {
// short-circuit if drop tracking is not enabled.
if !self.fcx.sess().opts.unstable_opts.drop_tracking {
return false;
}

self.drop_ranges.is_dropped_at(value_hir_id, yield_location)
}
}

pub fn resolve_interior<'a, 'tcx>(
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ pub trait PrettyPrinter<'tcx>:
match self.tcx().trimmed_def_paths(()).get(&def_id) {
None => Ok((self, false)),
Some(symbol) => {
self.write_str(symbol.as_str())?;
write!(self, "{}", Ident::with_dummy_span(*symbol))?;
Ok((self, true))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1350,6 +1350,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
expected_trait_ref,
obligation.cause.code(),
found_node,
obligation.param_env,
)
} else {
let (closure_span, closure_arg_span, found) = found_did
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ pub trait TypeErrCtxtExt<'tcx> {
expected: ty::PolyTraitRef<'tcx>,
cause: &ObligationCauseCode<'tcx>,
found_node: Option<Node<'_>>,
param_env: ty::ParamEnv<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>;

fn note_conflicting_closure_bounds(
Expand Down Expand Up @@ -1978,6 +1979,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
expected: ty::PolyTraitRef<'tcx>,
cause: &ObligationCauseCode<'tcx>,
found_node: Option<Node<'_>>,
param_env: ty::ParamEnv<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
pub(crate) fn build_fn_sig_ty<'tcx>(
infcx: &InferCtxt<'tcx>,
Expand Down Expand Up @@ -2040,7 +2042,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
self.note_conflicting_closure_bounds(cause, &mut err);

if let Some(found_node) = found_node {
hint_missing_borrow(span, found, expected, found_node, &mut err);
hint_missing_borrow(self, param_env, span, found, expected, found_node, &mut err);
}

err
Expand Down Expand Up @@ -3747,6 +3749,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {

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

let arg_spans = fn_decl.inputs.iter().map(|ty| ty.span);
let args = fn_decl.inputs.iter().map(|ty| ty);

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

for ((found_arg, expected_arg), arg_span) in found_args.zip(expected_args).zip(arg_spans) {
for ((found_arg, expected_arg), arg) in found_args.zip(expected_args).zip(args) {
let (found_ty, found_refs) = get_deref_type_and_refs(*found_arg);
let (expected_ty, expected_refs) = get_deref_type_and_refs(*expected_arg);

if found_ty == expected_ty {
if infcx.can_eq(param_env, found_ty, expected_ty).is_ok() {
if found_refs < expected_refs {
to_borrow.push((arg_span, expected_arg.to_string()));
to_borrow.push((arg.span.shrink_to_lo(), "&".repeat(expected_refs - found_refs)));
} else if found_refs > expected_refs {
remove_borrow.push((arg_span, expected_arg.to_string()));
let mut span = arg.span.shrink_to_lo();
let mut left = found_refs - expected_refs;
let mut ty = arg;
while let hir::TyKind::Ref(_, mut_ty) = &ty.kind && left > 0 {
span = span.with_hi(mut_ty.ty.span.lo());
ty = mut_ty.ty;
left -= 1;
}
let sugg = if left == 0 {
(span, String::new())
} else {
(arg.span, expected_arg.to_string())
};
remove_borrow.push(sugg);
}
}
}

if !to_borrow.is_empty() {
err.multipart_suggestion(
err.multipart_suggestion_verbose(
"consider borrowing the argument",
to_borrow,
Applicability::MaybeIncorrect,
);
}

if !remove_borrow.is_empty() {
err.multipart_suggestion(
err.multipart_suggestion_verbose(
"do not borrow the argument",
remove_borrow,
Applicability::MaybeIncorrect,
Expand Down
2 changes: 1 addition & 1 deletion src/tools/clippy/clippy_lints/src/instant_subtraction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ declare_clippy_lint! {
/// [`Instant::now()`]: std::time::Instant::now;
#[clippy::version = "1.65.0"]
pub UNCHECKED_DURATION_SUBTRACTION,
suspicious,
pedantic,
"finds unchecked subtraction of a 'Duration' from an 'Instant'"
}

Expand Down
7 changes: 6 additions & 1 deletion src/tools/compiletest/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -426,10 +426,15 @@ impl TestProps {
self.known_bug = true;
} else {
panic!(
"Invalid known-bug value: {known_bug}\nIt requires comma-separated issue references (`#000` or `chalk#000`) or `unknown`."
"Invalid known-bug value: {known_bug}\nIt requires comma-separated issue references (`#000` or `chalk#000`) or `known-bug: unknown`."
);
}
} else if config.parse_name_directive(ln, KNOWN_BUG) {
panic!(
"Invalid known-bug attribute, requires comma-separated issue references (`#000` or `chalk#000`) or `known-bug: unknown`."
);
}

config.set_name_value_directive(ln, MIR_UNIT_TEST, &mut self.mir_unit_test, |s| {
s.trim().to_string()
});
Expand Down
Loading

0 comments on commit a6269da

Please sign in to comment.