Auto merge of #68269 - csmoe:temp, r=estebank
Suggest to shorten temporary borrow from raw pointer Closes https://github.com/rust-lang/rust/issues/65436 r? @estebank cc @tmandry
This commit is contained in:
commit
8bf17584e0
4 changed files with 75 additions and 6 deletions
|
@ -12,6 +12,7 @@ use rustc_errors::{
|
||||||
error_code, pluralize, struct_span_err, Applicability, DiagnosticBuilder, Style,
|
error_code, pluralize, struct_span_err, Applicability, DiagnosticBuilder, Style,
|
||||||
};
|
};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::intravisit::Visitor;
|
use rustc_hir::intravisit::Visitor;
|
||||||
use rustc_hir::Node;
|
use rustc_hir::Node;
|
||||||
|
@ -1366,14 +1367,40 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
if let Some(expr_id) = expr {
|
if let Some(expr_id) = expr {
|
||||||
let expr = hir.expect_expr(expr_id);
|
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);
|
let parent = hir.get_parent_node(expr_id);
|
||||||
if let Some(hir::Node::Expr(e)) = hir.find(parent) {
|
if let Some(hir::Node::Expr(e)) = hir.find(parent) {
|
||||||
let method_span = hir.span(parent);
|
let parent_span = hir.span(parent);
|
||||||
if tables.is_method_call(e) && is_ref {
|
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(
|
err.span_help(
|
||||||
method_span,
|
parent_span,
|
||||||
"consider moving this method call into a `let` \
|
"consider moving this into a `let` \
|
||||||
binding to create a shorter lived borrow",
|
binding to create a shorter lived borrow",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ LL | let _x = get().await;
|
||||||
...
|
...
|
||||||
LL | }
|
LL | }
|
||||||
| - `client` is later dropped here
|
| - `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
|
--> $DIR/issue-64130-4-async-move.rs:19:15
|
||||||
|
|
|
|
||||||
LL | match client.status() {
|
LL | match client.status() {
|
||||||
|
|
|
@ -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;
|
||||||
|
})
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue