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 6 pull requests #91775

Closed
wants to merge 44 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
18c14ad
Add a `try_clone()` function to `OwnedFd`.
sunfishcode Sep 9, 2021
622dfcc
Fix Windows compilation errors.
sunfishcode Sep 9, 2021
c986c6b
Fix more Windows compilation errors.
sunfishcode Sep 9, 2021
2d6a4c8
Fix another Windows compilation error.
sunfishcode Sep 9, 2021
53e072f
Fix compilation on WASI, which doesn't yet support `dup`.
sunfishcode Oct 5, 2021
8f68bdc
Make `Borrow` and `BorrowMut` impls `const`
lilasta Dec 4, 2021
70855b2
Add spin_loop hint for RISC-V architecture
luojia65 Dec 5, 2021
f4f3b2d
When `.await` is called on a non-`Future` expression, suggest removal
estebank Nov 16, 2021
f002610
Reduce verbosity when calling `for`-loop on non-`Iterator` expression
estebank Nov 16, 2021
f0608fc
Reduce verbosity for `?` on non-`Try` expressions
estebank Nov 16, 2021
51d3489
Further silence `?` errors
estebank Nov 16, 2021
335a6e2
Remove yet more output from `for`-loop and `?` errors
estebank Nov 16, 2021
26b1f6c
Remove unnecessary argument
estebank Nov 16, 2021
fa156c2
Fix mistake
estebank Nov 16, 2021
4f5ba7a
Keep info on pre-desugaring expression for better "incorrect `.await`…
estebank Nov 16, 2021
fc2298c
Fix clippy uses of QPath::LangItem
estebank Nov 16, 2021
0ccf58b
Update stdarch dependency
luojia65 Dec 9, 2021
a3cdbc4
Fix rebase and clippy tests
estebank Nov 16, 2021
4884d8e
tidy fix
estebank Nov 16, 2021
d94eaa5
Simplify diagnostic logic
estebank Nov 17, 2021
df5439c
review comments
estebank Dec 2, 2021
a310dfb
review comment: change wording of suggestion
estebank Dec 10, 2021
d10fe26
Point at capture points for non-`'static` reference crossing a `yield…
estebank Oct 10, 2021
dd81e98
Clean up visual output logic
estebank Oct 11, 2021
ab45ab8
review comments
estebank Oct 12, 2021
09dbf37
Add filtering based on involved required lifetime
estebank Oct 12, 2021
ee0fd10
Point at return type when it introduces `'static` obligation
estebank Oct 12, 2021
10a74ac
Use a more accurate `Span` for `'static` obligation from return type
estebank Oct 12, 2021
0ee723e
Update nll test
estebank Oct 12, 2021
ff13ad7
rebase and update nll test
estebank Oct 12, 2021
83ce1aa
Tweak wording
estebank Oct 15, 2021
9cc7bd7
Review comments
estebank Nov 16, 2021
d33fa13
Remove field from `ErrorValue`
estebank Nov 16, 2021
da5b0cc
review comment
estebank Dec 10, 2021
40f161a
fix tests after rebase
estebank Dec 10, 2021
99789d0
fix clippy tests
estebank Dec 10, 2021
d2d9eb3
fmt
estebank Dec 10, 2021
e273152
Suggest using a temporary variable to fix borrowck errors
camelid Mar 15, 2021
7c2ed85
Rollup merge of #83174 - camelid:borrow-help, r=oli-obk
matthiaskrgr Dec 11, 2021
b6d96a1
Rollup merge of #88794 - sunfishcode:sunfishcode/try-clone, r=joshtri…
matthiaskrgr Dec 11, 2021
d9df1a8
Rollup merge of #89734 - estebank:issue-72312, r=nikomatsakis
matthiaskrgr Dec 11, 2021
ae9dafc
Rollup merge of #90270 - woppopo:const_borrow_trait, r=dtolnay
matthiaskrgr Dec 11, 2021
56c68bd
Rollup merge of #90939 - estebank:wg-af-polish, r=tmandry
matthiaskrgr Dec 11, 2021
1305bc5
Rollup merge of #91548 - luojia65:hint-spin-loop-riscv, r=Amanieu
matthiaskrgr Dec 11, 2021
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
70 changes: 55 additions & 15 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::AsyncGeneratorKind::Block,
|this| this.with_new_scopes(|this| this.lower_block_expr(block)),
),
ExprKind::Await(ref expr) => self.lower_expr_await(e.span, expr),
ExprKind::Await(ref expr) => {
let span = if expr.span.hi() < e.span.hi() {
expr.span.shrink_to_hi().with_hi(e.span.hi())
} else {
// this is a recovered `await expr`
e.span
};
self.lower_expr_await(span, expr)
}
ExprKind::Closure(
capture_clause,
asyncness,
Expand Down Expand Up @@ -479,8 +487,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
expr: &'hir hir::Expr<'hir>,
overall_span: Span,
) -> &'hir hir::Expr<'hir> {
let constructor =
self.arena.alloc(self.expr_lang_item_path(method_span, lang_item, ThinVec::new()));
let constructor = self.arena.alloc(self.expr_lang_item_path(
method_span,
lang_item,
ThinVec::new(),
None,
));
self.expr_call(overall_span, constructor, std::slice::from_ref(expr))
}

Expand Down Expand Up @@ -584,8 +596,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
// `future::from_generator`:
let unstable_span =
self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());
let gen_future =
self.expr_lang_item_path(unstable_span, hir::LangItem::FromGenerator, ThinVec::new());
let gen_future = self.expr_lang_item_path(
unstable_span,
hir::LangItem::FromGenerator,
ThinVec::new(),
None,
);

// `future::from_generator(generator)`:
hir::ExprKind::Call(self.arena.alloc(gen_future), arena_vec![self; generator])
Expand All @@ -607,6 +623,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
/// }
/// ```
fn lower_expr_await(&mut self, await_span: Span, expr: &Expr) -> hir::ExprKind<'hir> {
let dot_await_span = expr.span.shrink_to_hi().to(await_span);
match self.generator_kind {
Some(hir::GeneratorKind::Async(_)) => {}
Some(hir::GeneratorKind::Gen) | None => {
Expand All @@ -623,13 +640,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
err.emit();
}
}
let span = self.mark_span_with_reason(DesugaringKind::Await, await_span, None);
let span = self.mark_span_with_reason(DesugaringKind::Await, dot_await_span, None);
let gen_future_span = self.mark_span_with_reason(
DesugaringKind::Await,
await_span,
self.allow_gen_future.clone(),
);
let expr = self.lower_expr_mut(expr);
let expr_hir_id = expr.hir_id;

let pinned_ident = Ident::with_dummy_span(sym::pinned);
let (pinned_pat, pinned_pat_hid) =
Expand All @@ -656,16 +674,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
span,
hir::LangItem::PinNewUnchecked,
arena_vec![self; ref_mut_pinned],
Some(expr_hir_id),
);
let get_context = self.expr_call_lang_item_fn_mut(
gen_future_span,
hir::LangItem::GetContext,
arena_vec![self; task_context],
Some(expr_hir_id),
);
let call = self.expr_call_lang_item_fn(
span,
hir::LangItem::FuturePoll,
arena_vec![self; new_unchecked, get_context],
Some(expr_hir_id),
);
self.arena.alloc(self.expr_unsafe(call))
};
Expand All @@ -678,18 +699,28 @@ impl<'hir> LoweringContext<'_, 'hir> {
let (x_pat, x_pat_hid) = self.pat_ident(span, x_ident);
let x_expr = self.expr_ident(span, x_ident, x_pat_hid);
let ready_field = self.single_pat_field(span, x_pat);
let ready_pat = self.pat_lang_item_variant(span, hir::LangItem::PollReady, ready_field);
let ready_pat = self.pat_lang_item_variant(
span,
hir::LangItem::PollReady,
ready_field,
Some(expr_hir_id),
);
let break_x = self.with_loop_scope(loop_node_id, move |this| {
let expr_break =
hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr));
this.arena.alloc(this.expr(await_span, expr_break, ThinVec::new()))
this.arena.alloc(this.expr(span, expr_break, ThinVec::new()))
});
self.arm(ready_pat, break_x)
};

// `::std::task::Poll::Pending => {}`
let pending_arm = {
let pending_pat = self.pat_lang_item_variant(span, hir::LangItem::PollPending, &[]);
let pending_pat = self.pat_lang_item_variant(
span,
hir::LangItem::PollPending,
&[],
Some(expr_hir_id),
);
let empty_block = self.expr_block_empty(span);
self.arm(pending_pat, empty_block)
};
Expand All @@ -709,7 +740,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let unit = self.expr_unit(span);
let yield_expr = self.expr(
span,
hir::ExprKind::Yield(unit, hir::YieldSource::Await { expr: Some(expr.hir_id) }),
hir::ExprKind::Yield(unit, hir::YieldSource::Await { expr: Some(expr_hir_id) }),
ThinVec::new(),
);
let yield_expr = self.arena.alloc(yield_expr);
Expand Down Expand Up @@ -756,6 +787,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
into_future_span,
hir::LangItem::IntoFutureIntoFuture,
arena_vec![self; expr],
Some(expr_hir_id),
);

// match <into_future_expr> {
Expand Down Expand Up @@ -1160,7 +1192,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn lower_expr_range_closed(&mut self, span: Span, e1: &Expr, e2: &Expr) -> hir::ExprKind<'hir> {
let e1 = self.lower_expr_mut(e1);
let e2 = self.lower_expr_mut(e2);
let fn_path = hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, self.lower_span(span));
let fn_path =
hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, self.lower_span(span), None);
let fn_expr =
self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), ThinVec::new()));
hir::ExprKind::Call(fn_expr, arena_vec![self; e1, e2])
Expand Down Expand Up @@ -1194,7 +1227,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
);

hir::ExprKind::Struct(
self.arena.alloc(hir::QPath::LangItem(lang_item, self.lower_span(span))),
self.arena.alloc(hir::QPath::LangItem(lang_item, self.lower_span(span), None)),
fields,
None,
)
Expand Down Expand Up @@ -1389,6 +1422,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
head_span,
hir::LangItem::IteratorNext,
arena_vec![self; ref_mut_iter],
None,
);
let arms = arena_vec![self; none_arm, some_arm];

Expand Down Expand Up @@ -1417,6 +1451,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
head_span,
hir::LangItem::IntoIterIntoIter,
arena_vec![self; head],
None,
)
};

Expand Down Expand Up @@ -1472,6 +1507,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
unstable_span,
hir::LangItem::TryTraitBranch,
arena_vec![self; sub_expr],
None,
)
};

Expand Down Expand Up @@ -1628,8 +1664,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
span: Span,
lang_item: hir::LangItem,
args: &'hir [hir::Expr<'hir>],
hir_id: Option<hir::HirId>,
) -> hir::Expr<'hir> {
let path = self.arena.alloc(self.expr_lang_item_path(span, lang_item, ThinVec::new()));
let path =
self.arena.alloc(self.expr_lang_item_path(span, lang_item, ThinVec::new(), hir_id));
self.expr_call_mut(span, path, args)
}

Expand All @@ -1638,19 +1676,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
span: Span,
lang_item: hir::LangItem,
args: &'hir [hir::Expr<'hir>],
hir_id: Option<hir::HirId>,
) -> &'hir hir::Expr<'hir> {
self.arena.alloc(self.expr_call_lang_item_fn_mut(span, lang_item, args))
self.arena.alloc(self.expr_call_lang_item_fn_mut(span, lang_item, args, hir_id))
}

fn expr_lang_item_path(
&mut self,
span: Span,
lang_item: hir::LangItem,
attrs: AttrVec,
hir_id: Option<hir::HirId>,
) -> hir::Expr<'hir> {
self.expr(
span,
hir::ExprKind::Path(hir::QPath::LangItem(lang_item, self.lower_span(span))),
hir::ExprKind::Path(hir::QPath::LangItem(lang_item, self.lower_span(span), hir_id)),
attrs,
)
}
Expand Down
11 changes: 6 additions & 5 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2140,21 +2140,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {

fn pat_cf_continue(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
let field = self.single_pat_field(span, pat);
self.pat_lang_item_variant(span, hir::LangItem::ControlFlowContinue, field)
self.pat_lang_item_variant(span, hir::LangItem::ControlFlowContinue, field, None)
}

fn pat_cf_break(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
let field = self.single_pat_field(span, pat);
self.pat_lang_item_variant(span, hir::LangItem::ControlFlowBreak, field)
self.pat_lang_item_variant(span, hir::LangItem::ControlFlowBreak, field, None)
}

fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
let field = self.single_pat_field(span, pat);
self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field)
self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field, None)
}

fn pat_none(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[])
self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[], None)
}

fn single_pat_field(
Expand All @@ -2177,8 +2177,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
span: Span,
lang_item: hir::LangItem,
fields: &'hir [hir::PatField<'hir>],
hir_id: Option<hir::HirId>,
) -> &'hir hir::Pat<'hir> {
let qpath = hir::QPath::LangItem(lang_item, self.lower_span(span));
let qpath = hir::QPath::LangItem(lang_item, self.lower_span(span), hir_id);
self.pat(span, hir::PatKind::Struct(qpath, fields, false))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ fn try_extract_error_from_fulfill_cx<'tcx>(
error_region,
cause.clone(),
placeholder_region,
vec![],
),
),
(Some(error_region), _) => NiceRegionError::new(
Expand Down
89 changes: 87 additions & 2 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,18 @@ use rustc_span::symbol::sym;
use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP};
use rustc_trait_selection::infer::InferCtxtExt;

use crate::borrow_set::TwoPhaseActivation;
use crate::borrowck_errors;

use crate::diagnostics::find_all_local_uses;
use crate::{
borrow_set::BorrowData, diagnostics::Instance, prefixes::IsPrefixOf,
InitializationRequiringAction, MirBorrowckCtxt, PrefixSet, WriteKind,
};

use super::{
explain_borrow::BorrowExplanation, FnSelfUseKind, IncludingDowncast, RegionName,
RegionNameSource, UseSpans,
explain_borrow::{BorrowExplanation, LaterUseKind},
FnSelfUseKind, IncludingDowncast, RegionName, RegionNameSource, UseSpans,
};

#[derive(Debug)]
Expand Down Expand Up @@ -768,9 +770,92 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
Some((issued_span, span)),
);

self.suggest_using_local_if_applicable(
&mut err,
location,
(place, span),
gen_borrow_kind,
issued_borrow,
explanation,
);

err
}

#[instrument(level = "debug", skip(self, err))]
fn suggest_using_local_if_applicable(
&self,
err: &mut DiagnosticBuilder<'_>,
location: Location,
(place, span): (Place<'tcx>, Span),
gen_borrow_kind: BorrowKind,
issued_borrow: &BorrowData<'tcx>,
explanation: BorrowExplanation,
) {
let used_in_call =
matches!(explanation, BorrowExplanation::UsedLater(LaterUseKind::Call, _call_span, _));
if !used_in_call {
debug!("not later used in call");
return;
}

let outer_call_loc =
if let TwoPhaseActivation::ActivatedAt(loc) = issued_borrow.activation_location {
loc
} else {
issued_borrow.reserve_location
};
let outer_call_stmt = self.body.stmt_at(outer_call_loc);

let inner_param_location = location;
let Some(inner_param_stmt) = self.body.stmt_at(inner_param_location).left() else {
debug!("`inner_param_location` {:?} is not for a statement", inner_param_location);
return;
};
let Some(&inner_param) = inner_param_stmt.kind.as_assign().map(|(p, _)| p) else {
debug!(
"`inner_param_location` {:?} is not for an assignment: {:?}",
inner_param_location, inner_param_stmt
);
return;
};
let inner_param_uses = find_all_local_uses::find(self.body, inner_param.local);
let Some((inner_call_loc,inner_call_term)) = inner_param_uses.into_iter().find_map(|loc| {
let Either::Right(term) = self.body.stmt_at(loc) else {
debug!("{:?} is a statement, so it can't be a call", loc);
return None;
};
let TerminatorKind::Call { args, .. } = &term.kind else {
debug!("not a call: {:?}", term);
return None;
};
debug!("checking call args for uses of inner_param: {:?}", args);
if args.contains(&Operand::Move(inner_param)) {
Some((loc,term))
} else {
None
}
}) else {
debug!("no uses of inner_param found as a by-move call arg");
return;
};
debug!("===> outer_call_loc = {:?}, inner_call_loc = {:?}", outer_call_loc, inner_call_loc);

let inner_call_span = inner_call_term.source_info.span;
let outer_call_span = outer_call_stmt.either(|s| s.source_info, |t| t.source_info).span;
if outer_call_span == inner_call_span || !outer_call_span.contains(inner_call_span) {
// FIXME: This stops the suggestion in some cases where it should be emitted.
// Fix the spans for those cases so it's emitted correctly.
debug!(
"outer span {:?} does not strictly contain inner span {:?}",
outer_call_span, inner_call_span
);
return;
}
err.span_help(inner_call_span, "try adding a local storing this argument...");
err.span_help(outer_call_span, "...and then using that local as the argument to this call");
}

fn suggest_split_at_mut_if_applicable(
&self,
err: &mut DiagnosticBuilder<'_>,
Expand Down
Loading