Skip to content

Commit

Permalink
Auto merge of #68269 - csmoe:temp, r=estebank
Browse files Browse the repository at this point in the history
Suggest to shorten temporary borrow from raw pointer

Closes #65436
r? @estebank
cc @tmandry
  • Loading branch information
bors committed Jan 25, 2020
2 parents 8647aa1 + cd7b5ed commit 8bf1758
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 6 deletions.
37 changes: 32 additions & 5 deletions src/librustc/traits/error_reporting/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use rustc_errors::{
error_code, pluralize, struct_span_err, Applicability, DiagnosticBuilder, Style,
};
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor;
use rustc_hir::Node;
Expand Down Expand Up @@ -1366,14 +1367,40 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {

if let Some(expr_id) = expr {
let expr = hir.expect_expr(expr_id);
let is_ref = tables.expr_adjustments(expr).iter().any(|adj| adj.is_region_borrow());
debug!("target_ty evaluated from {:?}", expr);

let parent = hir.get_parent_node(expr_id);
if let Some(hir::Node::Expr(e)) = hir.find(parent) {
let method_span = hir.span(parent);
if tables.is_method_call(e) && is_ref {
let parent_span = hir.span(parent);
let parent_did = parent.owner_def_id();
// ```rust
// impl T {
// fn foo(&self) -> i32 {}
// }
// T.foo();
// ^^^^^^^ a temporary `&T` created inside this method call due to `&self`
// ```
//
let is_region_borrow =
tables.expr_adjustments(expr).iter().any(|adj| adj.is_region_borrow());

// ```rust
// struct Foo(*const u8);
// bar(Foo(std::ptr::null())).await;
// ^^^^^^^^^^^^^^^^^^^^^ raw-ptr `*T` created inside this struct ctor.
// ```
debug!("parent_def_kind: {:?}", self.tcx.def_kind(parent_did));
let is_raw_borrow_inside_fn_like_call = match self.tcx.def_kind(parent_did) {
Some(DefKind::Fn) | Some(DefKind::Ctor(..)) => target_ty.is_unsafe_ptr(),
_ => false,
};

if (tables.is_method_call(e) && is_region_borrow)
|| is_raw_borrow_inside_fn_like_call
{
err.span_help(
method_span,
"consider moving this method call into a `let` \
parent_span,
"consider moving this into a `let` \
binding to create a shorter lived borrow",
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/async-await/issue-64130-4-async-move.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ LL | let _x = get().await;
...
LL | }
| - `client` is later dropped here
help: consider moving this method call into a `let` binding to create a shorter lived borrow
help: consider moving this into a `let` binding to create a shorter lived borrow
--> $DIR/issue-64130-4-async-move.rs:19:15
|
LL | match client.status() {
Expand Down
16 changes: 16 additions & 0 deletions src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// edition:2018

struct Foo(*const u8);

unsafe impl Send for Foo {}

async fn bar(_: Foo) {}

fn assert_send<T: Send>(_: T) {}

fn main() {
assert_send(async {
//~^ ERROR future cannot be sent between threads safely
bar(Foo(std::ptr::null())).await;
})
}
26 changes: 26 additions & 0 deletions src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
error: future cannot be sent between threads safely
--> $DIR/issue-65436-raw-ptr-not-send.rs:12:5
|
LL | fn assert_send<T: Send>(_: T) {}
| ----------- ---- required by this bound in `assert_send`
...
LL | assert_send(async {
| ^^^^^^^^^^^ future returned by `main` is not `Send`
|
= help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `*const u8`
note: future is not `Send` as this value is used across an await
--> $DIR/issue-65436-raw-ptr-not-send.rs:14:9
|
LL | bar(Foo(std::ptr::null())).await;
| ^^^^^^^^----------------^^^^^^^^- `std::ptr::null()` is later dropped here
| | |
| | has type `*const u8`
| await occurs here, with `std::ptr::null()` maybe used later
help: consider moving this into a `let` binding to create a shorter lived borrow
--> $DIR/issue-65436-raw-ptr-not-send.rs:14:13
|
LL | bar(Foo(std::ptr::null())).await;
| ^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

0 comments on commit 8bf1758

Please sign in to comment.