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 10 pull requests #104749

Closed
wants to merge 45 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
aef3d93
Add powerpc64-ibm-aix as Tier-3 target
ecnelises Aug 25, 2022
4e9ceef
Refactor `must_use` lint into two parts
Noratrieb Nov 13, 2022
644a5a3
enable fuzzy_provenance_casts lint in liballoc
RalfJung Nov 20, 2022
7f5addd
enable fuzzy_provenance_casts lint in libstd
RalfJung Nov 20, 2022
1a69666
dont attempt strict provenance in SGX
RalfJung Nov 21, 2022
2752e32
Allow opaque types in trait impl headers and rely on coherence to rej…
oli-obk Oct 24, 2022
94fe30f
Treat different opaque types of the same def id as equal during coher…
oli-obk Oct 27, 2022
ae80c76
Add an always-ambiguous predicate to make sure that we don't accident…
oli-obk Nov 2, 2022
9cd44f8
nit treat different opaque types
oli-obk Nov 14, 2022
9a8e1ee
Move a field around
oli-obk Nov 14, 2022
f42e490
Register obligations from type relation
oli-obk Nov 14, 2022
11ae334
Remove a function that doesn't actually do anything
oli-obk Nov 15, 2022
7301cd7
Type generalization should not look at opaque type in coherence
oli-obk Nov 17, 2022
11adf03
Add some more assertions for type relations not used during coherence
oli-obk Nov 17, 2022
c16a90f
Test generalization during coherence
oli-obk Nov 17, 2022
98cb7c8
Suggest `.clone()` or `ref binding` on E0382
estebank Nov 3, 2022
fface0c
Do not suggest `ref` multiple times for the same binding
estebank Nov 3, 2022
cca960d
Fix clippy code
estebank Nov 3, 2022
242dd83
Use `type_implements_trait`
estebank Nov 3, 2022
e88009b
Extract suggestion logic to its own method
estebank Nov 3, 2022
0994f8d
Remove logic duplication
estebank Nov 3, 2022
4918d4f
Tweak output in for loops
estebank Nov 3, 2022
33a6dc9
Fix wording
estebank Nov 3, 2022
6f77be4
Fix rustfmt
estebank Nov 3, 2022
a930d44
Tweak output to account for alternative bindings in the same pattern
estebank Nov 3, 2022
5bf1413
Fix rebase
estebank Nov 3, 2022
95a5beb
remove spurious commented out code
estebank Nov 4, 2022
2698d24
review comments: inline bindings and fix typo
estebank Nov 12, 2022
9a39012
Account for `x @ y` and suggest `ref x @ ref y`
estebank Nov 15, 2022
7cc4fb5
Account for closures
estebank Nov 16, 2022
3099dfd
Forbid inlining `thread_local!`'s `__getit` function on Windows
thomcc Sep 3, 2022
2d5d692
Add failing test for projections used as const generic
GuillaumeGomez Nov 22, 2022
04610ad
Fix `ClosureKind::to_def_id`
WaffleLapkin Nov 22, 2022
b80356a
Use `tcx.require_lang_item` instead of unwrapping
WaffleLapkin Nov 22, 2022
f2830f2
Speed up mpsc_stress test
Nov 22, 2022
06ee531
Rollup merge of #101368 - thomcc:wintls-noinline, r=ChrisDenton
Manishearth Nov 22, 2022
ba2996c
Rollup merge of #102293 - ecnelises:aix.initial, r=davidtwco
Manishearth Nov 22, 2022
06666bb
Rollup merge of #103488 - oli-obk:impl_trait_for_tait, r=lcnr
Manishearth Nov 22, 2022
2847060
Rollup merge of #103908 - estebank:consider-cloning, r=compiler-errors
Manishearth Nov 22, 2022
4e090d4
Rollup merge of #104359 - Nilstrieb:plus-one, r=fee1-dead
Manishearth Nov 22, 2022
ba47cf7
Rollup merge of #104647 - RalfJung:alloc-strict-provenance, r=thomcc
Manishearth Nov 22, 2022
93c2861
Rollup merge of #104717 - GuillaumeGomez:test-projection-used-as-cons…
Manishearth Nov 22, 2022
48bbae7
Rollup merge of #104722 - mejrs:stress, r=ChrisDenton
Manishearth Nov 22, 2022
1e65fcc
Rollup merge of #104724 - WaffleLapkin:to_def_idn't, r=compiler-errors
Manishearth Nov 22, 2022
c416700
Rollup merge of #104728 - WaffleLapkin:require-lang-items-politely, r…
Manishearth Nov 22, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1376,7 +1376,7 @@ pub enum ExprKind {
/// Conditionless loop (can be exited with `break`, `continue`, or `return`).
///
/// `'label: loop { block }`
Loop(P<Block>, Option<Label>),
Loop(P<Block>, Option<Label>, Span),
/// A `match` block.
Match(P<Expr>, Vec<Arm>),
/// A closure (e.g., `move |a, b, c| a + b + c`).
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1355,9 +1355,10 @@ pub fn noop_visit_expr<T: MutVisitor>(
vis.visit_block(body);
visit_opt(label, |label| vis.visit_label(label));
}
ExprKind::Loop(body, label) => {
ExprKind::Loop(body, label, span) => {
vis.visit_block(body);
visit_opt(label, |label| vis.visit_label(label));
vis.visit_span(span);
}
ExprKind::Match(expr, arms) => {
vis.visit_expr(expr);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
visitor.visit_expr(subexpression);
visitor.visit_block(block);
}
ExprKind::Loop(block, opt_label) => {
ExprKind::Loop(block, opt_label, _) => {
walk_list!(visitor, visit_label, opt_label);
visitor.visit_block(block);
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
this.lower_expr_while_in_loop_scope(span, cond, body, opt_label)
})
}
ExprKind::Loop(ref body, opt_label) => self.with_loop_scope(e.id, |this| {
ExprKind::Loop(ref body, opt_label, span) => self.with_loop_scope(e.id, |this| {
hir::ExprKind::Loop(
this.lower_block(body, false),
this.lower_label(opt_label),
hir::LoopSource::Loop,
DUMMY_SP,
this.lower_span(span),
)
}),
ExprKind::TryBlock(ref body) => self.lower_expr_try_block(body),
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_pretty/src/pprust/state/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ impl<'a> State<'a> {
self.space();
self.print_block_with_attrs(blk, attrs);
}
ast::ExprKind::Loop(ref blk, opt_label) => {
ast::ExprKind::Loop(ref blk, opt_label, _) => {
if let Some(label) = opt_label {
self.print_ident(label.ident);
self.word_space(":");
Expand Down
229 changes: 197 additions & 32 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rustc_errors::{
};
use rustc_hir as hir;
use rustc_hir::intravisit::{walk_block, walk_expr, Visitor};
use rustc_hir::{AsyncGeneratorKind, GeneratorKind};
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, LangItem};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::ObligationCause;
use rustc_middle::mir::tcx::PlaceTy;
Expand Down Expand Up @@ -167,10 +167,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
);
}

self.add_moved_or_invoked_closure_note(location, used_place, &mut err);
let closure = self.add_moved_or_invoked_closure_note(location, used_place, &mut err);

let mut is_loop_move = false;
let mut in_pattern = false;
let mut seen_spans = FxHashSet::default();

for move_site in &move_site_vec {
let move_out = self.move_data.moves[(*move_site).moi];
Expand All @@ -191,37 +192,25 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
is_loop_move = true;
}

self.explain_captures(
&mut err,
span,
move_span,
move_spans,
*moved_place,
partially_str,
loop_message,
move_msg,
is_loop_move,
maybe_reinitialized_locations.is_empty(),
);

if let (UseSpans::PatUse(span), []) =
(move_spans, &maybe_reinitialized_locations[..])
{
if maybe_reinitialized_locations.is_empty() {
err.span_suggestion_verbose(
span.shrink_to_lo(),
&format!(
"borrow this field in the pattern to avoid moving {}",
self.describe_place(moved_place.as_ref())
.map(|n| format!("`{}`", n))
.unwrap_or_else(|| "the value".to_string())
),
"ref ",
Applicability::MachineApplicable,
);
in_pattern = true;
if !seen_spans.contains(&move_span) {
if !closure {
self.suggest_ref_or_clone(mpi, move_span, &mut err, &mut in_pattern);
}

self.explain_captures(
&mut err,
span,
move_span,
move_spans,
*moved_place,
partially_str,
loop_message,
move_msg,
is_loop_move,
maybe_reinitialized_locations.is_empty(),
);
}
seen_spans.insert(move_span);
}

use_spans.var_path_only_subdiag(&mut err, desired_action);
Expand Down Expand Up @@ -317,6 +306,160 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
}

fn suggest_ref_or_clone(
&mut self,
mpi: MovePathIndex,
move_span: Span,
err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>,
in_pattern: &mut bool,
) {
struct ExpressionFinder<'hir> {
expr_span: Span,
expr: Option<&'hir hir::Expr<'hir>>,
pat: Option<&'hir hir::Pat<'hir>>,
parent_pat: Option<&'hir hir::Pat<'hir>>,
}
impl<'hir> Visitor<'hir> for ExpressionFinder<'hir> {
fn visit_expr(&mut self, e: &'hir hir::Expr<'hir>) {
if e.span == self.expr_span {
self.expr = Some(e);
}
hir::intravisit::walk_expr(self, e);
}
fn visit_pat(&mut self, p: &'hir hir::Pat<'hir>) {
if p.span == self.expr_span {
self.pat = Some(p);
}
if let hir::PatKind::Binding(hir::BindingAnnotation::NONE, _, i, sub) = p.kind {
if i.span == self.expr_span || p.span == self.expr_span {
self.pat = Some(p);
}
// Check if we are in a situation of `ident @ ident` where we want to suggest
// `ref ident @ ref ident` or `ref ident @ Struct { ref ident }`.
if let Some(subpat) = sub && self.pat.is_none() {
self.visit_pat(subpat);
if self.pat.is_some() {
self.parent_pat = Some(p);
}
return;
}
}
hir::intravisit::walk_pat(self, p);
}
}
let hir = self.infcx.tcx.hir();
if let Some(hir::Node::Item(hir::Item {
kind: hir::ItemKind::Fn(_, _, body_id),
..
})) = hir.find(hir.local_def_id_to_hir_id(self.mir_def_id()))
&& let Some(hir::Node::Expr(expr)) = hir.find(body_id.hir_id)
{
let place = &self.move_data.move_paths[mpi].place;
let span = place.as_local()
.map(|local| self.body.local_decls[local].source_info.span);
let mut finder = ExpressionFinder {
expr_span: move_span,
expr: None,
pat: None,
parent_pat: None,
};
finder.visit_expr(expr);
if let Some(span) = span && let Some(expr) = finder.expr {
for (_, expr) in hir.parent_iter(expr.hir_id) {
if let hir::Node::Expr(expr) = expr {
if expr.span.contains(span) {
// If the let binding occurs within the same loop, then that
// loop isn't relevant, like in the following, the outermost `loop`
// doesn't play into `x` being moved.
// ```
// loop {
// let x = String::new();
// loop {
// foo(x);
// }
// }
// ```
break;
}
if let hir::ExprKind::Loop(.., loop_span) = expr.kind {
err.span_label(loop_span, "inside of this loop");
}
}
}
let typeck = self.infcx.tcx.typeck(self.mir_def_id());
let hir_id = hir.get_parent_node(expr.hir_id);
if let Some(parent) = hir.find(hir_id) {
let (def_id, args, offset) = if let hir::Node::Expr(parent_expr) = parent
&& let hir::ExprKind::MethodCall(_, _, args, _) = parent_expr.kind
&& let Some(def_id) = typeck.type_dependent_def_id(parent_expr.hir_id)
{
(def_id.as_local(), args, 1)
} else if let hir::Node::Expr(parent_expr) = parent
&& let hir::ExprKind::Call(call, args) = parent_expr.kind
&& let ty::FnDef(def_id, _) = typeck.node_type(call.hir_id).kind()
{
(def_id.as_local(), args, 0)
} else {
(None, &[][..], 0)
};
if let Some(def_id) = def_id
&& let Some(node) = hir.find(hir.local_def_id_to_hir_id(def_id))
&& let Some(fn_sig) = node.fn_sig()
&& let Some(ident) = node.ident()
&& let Some(pos) = args.iter().position(|arg| arg.hir_id == expr.hir_id)
&& let Some(arg) = fn_sig.decl.inputs.get(pos + offset)
{
let mut span: MultiSpan = arg.span.into();
span.push_span_label(
arg.span,
"this parameter takes ownership of the value".to_string(),
);
let descr = match node.fn_kind() {
Some(hir::intravisit::FnKind::ItemFn(..)) | None => "function",
Some(hir::intravisit::FnKind::Method(..)) => "method",
Some(hir::intravisit::FnKind::Closure) => "closure",
};
span.push_span_label(
ident.span,
format!("in this {descr}"),
);
err.span_note(
span,
format!(
"consider changing this parameter type in {descr} `{ident}` to \
borrow instead if owning the value isn't necessary",
),
);
}
let place = &self.move_data.move_paths[mpi].place;
let ty = place.ty(self.body, self.infcx.tcx).ty;
if let hir::Node::Expr(parent_expr) = parent
&& let hir::ExprKind::Call(call_expr, _) = parent_expr.kind
&& let hir::ExprKind::Path(
hir::QPath::LangItem(hir::LangItem::IntoIterIntoIter, _, _)
) = call_expr.kind
{
// Do not suggest `.clone()` in a `for` loop, we already suggest borrowing.
} else {
self.suggest_cloning(err, ty, move_span);
}
}
}
if let Some(pat) = finder.pat {
*in_pattern = true;
let mut sugg = vec![(pat.span.shrink_to_lo(), "ref ".to_string())];
if let Some(pat) = finder.parent_pat {
sugg.insert(0, (pat.span.shrink_to_lo(), "ref ".to_string()));
}
err.multipart_suggestion_verbose(
"borrow this binding in the pattern to avoid moving the value",
sugg,
Applicability::MachineApplicable,
);
}
}
}

fn report_use_of_uninitialized(
&self,
mpi: MovePathIndex,
Expand Down Expand Up @@ -590,6 +733,28 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
true
}

fn suggest_cloning(&self, err: &mut Diagnostic, ty: Ty<'tcx>, span: Span) {
let tcx = self.infcx.tcx;
// Try to find predicates on *generic params* that would allow copying `ty`
let infcx = tcx.infer_ctxt().build();
if infcx
.type_implements_trait(
tcx.lang_items().clone_trait().unwrap(),
tcx.erase_regions(ty),
ty::List::empty(),
self.param_env,
)
.must_apply_modulo_regions()
{
err.span_suggestion_verbose(
span.shrink_to_hi(),
"consider cloning the value if the performance cost is acceptable",
".clone()".to_string(),
Applicability::MachineApplicable,
);
}
}

fn suggest_adding_copy_bounds(&self, err: &mut Diagnostic, ty: Ty<'tcx>, span: Span) {
let tcx = self.infcx.tcx;
let generics = tcx.generics_of(self.mir_def_id());
Expand All @@ -601,7 +766,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
else { return; };
// Try to find predicates on *generic params* that would allow copying `ty`
let infcx = tcx.infer_ctxt().build();
let copy_did = infcx.tcx.lang_items().copy_trait().unwrap();
let copy_did = infcx.tcx.require_lang_item(LangItem::Copy, Some(span));
let cause = ObligationCause::new(
span,
self.mir_hir_id(),
Expand Down
8 changes: 5 additions & 3 deletions compiler/rustc_borrowck/src/diagnostics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
location: Location,
place: PlaceRef<'tcx>,
diag: &mut Diagnostic,
) {
) -> bool {
debug!("add_moved_or_invoked_closure_note: location={:?} place={:?}", location, place);
let mut target = place.local_or_deref_local();
for stmt in &self.body[location.block].statements[location.statement_index..] {
Expand Down Expand Up @@ -106,7 +106,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
{
place.local_or_deref_local().unwrap()
}
_ => return,
_ => return false,
};

debug!("add_moved_or_invoked_closure_note: closure={:?}", closure);
Expand All @@ -125,7 +125,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
ty::place_to_string_for_capture(self.infcx.tcx, hir_place)
),
);
return;
return true;
}
}
}
Expand All @@ -149,9 +149,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
ty::place_to_string_for_capture(self.infcx.tcx, hir_place)
),
);
return true;
}
}
}
false
}

/// End-user visible description of `place` if one can be found.
Expand Down
Loading