Rollup merge of #114469 - estebank:arbitrary-self-types-mut-diff, r=davidtwco
Detect method not found on arbitrary self type with different mutability ``` error[E0599]: no method named `x` found for struct `Pin<&S>` in the current scope --> $DIR/arbitrary_self_type_mut_difference.rs:11:18 | LL | Pin::new(&S).x(); | ^ help: there is a method with a similar name: `y` | note: method is available for `Pin<&mut S>` --> $DIR/arbitrary_self_type_mut_difference.rs:6:5 | LL | fn x(self: Pin<&mut Self>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ``` Related to #57994, as one of the presented cases can lead to code like this.
This commit is contained in:
commit
90c0371ca9
@ -13,7 +13,7 @@
|
|||||||
YieldExprOutsideOfGenerator,
|
YieldExprOutsideOfGenerator,
|
||||||
};
|
};
|
||||||
use crate::fatally_break_rust;
|
use crate::fatally_break_rust;
|
||||||
use crate::method::SelfSource;
|
use crate::method::{MethodCallComponents, SelfSource};
|
||||||
use crate::type_error_struct;
|
use crate::type_error_struct;
|
||||||
use crate::Expectation::{self, ExpectCastableToType, ExpectHasType, NoExpectation};
|
use crate::Expectation::{self, ExpectCastableToType, ExpectHasType, NoExpectation};
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -1281,7 +1281,7 @@ fn check_method_call(
|
|||||||
segment.ident,
|
segment.ident,
|
||||||
SelfSource::MethodCall(rcvr),
|
SelfSource::MethodCall(rcvr),
|
||||||
error,
|
error,
|
||||||
Some((rcvr, args)),
|
Some(MethodCallComponents { receiver: rcvr, args, full_expr: expr }),
|
||||||
expected,
|
expected,
|
||||||
false,
|
false,
|
||||||
) {
|
) {
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
pub mod probe;
|
pub mod probe;
|
||||||
mod suggest;
|
mod suggest;
|
||||||
|
|
||||||
pub use self::suggest::SelfSource;
|
pub use self::suggest::{MethodCallComponents, SelfSource};
|
||||||
pub use self::MethodError::*;
|
pub use self::MethodError::*;
|
||||||
|
|
||||||
use crate::errors::OpMethodGenericParams;
|
use crate::errors::OpMethodGenericParams;
|
||||||
|
@ -50,6 +50,15 @@
|
|||||||
use std::cmp::{self, Ordering};
|
use std::cmp::{self, Ordering};
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
|
/// After identifying that `full_expr` is a method call, we use this type to keep the expression's
|
||||||
|
/// components readily available to us to point at the right place in diagnostics.
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct MethodCallComponents<'tcx> {
|
||||||
|
pub receiver: &'tcx hir::Expr<'tcx>,
|
||||||
|
pub args: &'tcx [hir::Expr<'tcx>],
|
||||||
|
pub full_expr: &'tcx hir::Expr<'tcx>,
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
fn is_fn_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
|
fn is_fn_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
@ -115,7 +124,7 @@ pub fn report_method_error(
|
|||||||
item_name: Ident,
|
item_name: Ident,
|
||||||
source: SelfSource<'tcx>,
|
source: SelfSource<'tcx>,
|
||||||
error: MethodError<'tcx>,
|
error: MethodError<'tcx>,
|
||||||
args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>,
|
args: Option<MethodCallComponents<'tcx>>,
|
||||||
expected: Expectation<'tcx>,
|
expected: Expectation<'tcx>,
|
||||||
trait_missing_method: bool,
|
trait_missing_method: bool,
|
||||||
) -> Option<DiagnosticBuilder<'_, ErrorGuaranteed>> {
|
) -> Option<DiagnosticBuilder<'_, ErrorGuaranteed>> {
|
||||||
@ -257,18 +266,23 @@ pub fn report_method_error(
|
|||||||
fn suggest_missing_writer(
|
fn suggest_missing_writer(
|
||||||
&self,
|
&self,
|
||||||
rcvr_ty: Ty<'tcx>,
|
rcvr_ty: Ty<'tcx>,
|
||||||
args: (&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>]),
|
args: MethodCallComponents<'tcx>,
|
||||||
) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
|
) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
|
||||||
let (ty_str, _ty_file) = self.tcx.short_ty_string(rcvr_ty);
|
let (ty_str, _ty_file) = self.tcx.short_ty_string(rcvr_ty);
|
||||||
let mut err =
|
let mut err = struct_span_err!(
|
||||||
struct_span_err!(self.tcx.sess, args.0.span, E0599, "cannot write into `{}`", ty_str);
|
self.tcx.sess,
|
||||||
|
args.receiver.span,
|
||||||
|
E0599,
|
||||||
|
"cannot write into `{}`",
|
||||||
|
ty_str
|
||||||
|
);
|
||||||
err.span_note(
|
err.span_note(
|
||||||
args.0.span,
|
args.receiver.span,
|
||||||
"must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method",
|
"must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method",
|
||||||
);
|
);
|
||||||
if let ExprKind::Lit(_) = args.0.kind {
|
if let ExprKind::Lit(_) = args.receiver.kind {
|
||||||
err.span_help(
|
err.span_help(
|
||||||
args.0.span.shrink_to_lo(),
|
args.receiver.span.shrink_to_lo(),
|
||||||
"a writer is needed before this format string",
|
"a writer is needed before this format string",
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -282,7 +296,7 @@ pub fn report_no_match_method_error(
|
|||||||
rcvr_ty: Ty<'tcx>,
|
rcvr_ty: Ty<'tcx>,
|
||||||
item_name: Ident,
|
item_name: Ident,
|
||||||
source: SelfSource<'tcx>,
|
source: SelfSource<'tcx>,
|
||||||
args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>,
|
args: Option<MethodCallComponents<'tcx>>,
|
||||||
sugg_span: Span,
|
sugg_span: Span,
|
||||||
no_match_data: &mut NoMatchData<'tcx>,
|
no_match_data: &mut NoMatchData<'tcx>,
|
||||||
expected: Expectation<'tcx>,
|
expected: Expectation<'tcx>,
|
||||||
@ -953,6 +967,39 @@ trait bound{s}",
|
|||||||
|
|
||||||
unsatisfied_bounds = true;
|
unsatisfied_bounds = true;
|
||||||
}
|
}
|
||||||
|
} else if let ty::Adt(def, targs) = rcvr_ty.kind() && let Some(args) = args {
|
||||||
|
// This is useful for methods on arbitrary self types that might have a simple
|
||||||
|
// mutability difference, like calling a method on `Pin<&mut Self>` that is on
|
||||||
|
// `Pin<&Self>`.
|
||||||
|
if targs.len() == 1 {
|
||||||
|
let mut item_segment = hir::PathSegment::invalid();
|
||||||
|
item_segment.ident = item_name;
|
||||||
|
for t in [Ty::new_mut_ref, Ty::new_imm_ref, |_, _, t| t] {
|
||||||
|
let new_args = tcx.mk_args_from_iter(
|
||||||
|
targs
|
||||||
|
.iter()
|
||||||
|
.map(|arg| match arg.as_type() {
|
||||||
|
Some(ty) => ty::GenericArg::from(
|
||||||
|
t(tcx, tcx.lifetimes.re_erased, ty.peel_refs()),
|
||||||
|
),
|
||||||
|
_ => arg,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
let rcvr_ty = Ty::new_adt(tcx, *def, new_args);
|
||||||
|
if let Ok(method) = self.lookup_method_for_diagnostic(
|
||||||
|
rcvr_ty,
|
||||||
|
&item_segment,
|
||||||
|
span,
|
||||||
|
args.full_expr,
|
||||||
|
args.receiver,
|
||||||
|
) {
|
||||||
|
err.span_note(
|
||||||
|
tcx.def_span(method.def_id),
|
||||||
|
format!("{item_kind} is available for `{rcvr_ty}`"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let label_span_not_found = |err: &mut Diagnostic| {
|
let label_span_not_found = |err: &mut Diagnostic| {
|
||||||
@ -1111,7 +1158,7 @@ trait bound{s}",
|
|||||||
span,
|
span,
|
||||||
rcvr_ty,
|
rcvr_ty,
|
||||||
item_name,
|
item_name,
|
||||||
args.map(|(_, args)| args.len() + 1),
|
args.map(|MethodCallComponents { args, .. }| args.len() + 1),
|
||||||
source,
|
source,
|
||||||
no_match_data.out_of_scope_traits.clone(),
|
no_match_data.out_of_scope_traits.clone(),
|
||||||
&unsatisfied_predicates,
|
&unsatisfied_predicates,
|
||||||
@ -1192,7 +1239,7 @@ fn note_candidates_on_method_error(
|
|||||||
&self,
|
&self,
|
||||||
rcvr_ty: Ty<'tcx>,
|
rcvr_ty: Ty<'tcx>,
|
||||||
item_name: Ident,
|
item_name: Ident,
|
||||||
args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>,
|
args: Option<MethodCallComponents<'tcx>>,
|
||||||
span: Span,
|
span: Span,
|
||||||
err: &mut Diagnostic,
|
err: &mut Diagnostic,
|
||||||
sources: &mut Vec<CandidateSource>,
|
sources: &mut Vec<CandidateSource>,
|
||||||
@ -1343,7 +1390,7 @@ fn suggest_associated_call_syntax(
|
|||||||
rcvr_ty: Ty<'tcx>,
|
rcvr_ty: Ty<'tcx>,
|
||||||
source: SelfSource<'tcx>,
|
source: SelfSource<'tcx>,
|
||||||
item_name: Ident,
|
item_name: Ident,
|
||||||
args: Option<(&hir::Expr<'tcx>, &[hir::Expr<'tcx>])>,
|
args: Option<MethodCallComponents<'tcx>>,
|
||||||
sugg_span: Span,
|
sugg_span: Span,
|
||||||
) {
|
) {
|
||||||
let mut has_unsuggestable_args = false;
|
let mut has_unsuggestable_args = false;
|
||||||
@ -1415,7 +1462,7 @@ fn suggest_associated_call_syntax(
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
let mut applicability = Applicability::MachineApplicable;
|
let mut applicability = Applicability::MachineApplicable;
|
||||||
let args = if let Some((receiver, args)) = args {
|
let args = if let Some(MethodCallComponents { receiver, args, .. }) = args {
|
||||||
// The first arg is the same kind as the receiver
|
// The first arg is the same kind as the receiver
|
||||||
let explicit_args = if first_arg.is_some() {
|
let explicit_args = if first_arg.is_some() {
|
||||||
std::iter::once(receiver).chain(args.iter()).collect::<Vec<_>>()
|
std::iter::once(receiver).chain(args.iter()).collect::<Vec<_>>()
|
||||||
@ -2995,7 +3042,7 @@ pub fn all_traits(tcx: TyCtxt<'_>) -> Vec<TraitInfo> {
|
|||||||
|
|
||||||
fn print_disambiguation_help<'tcx>(
|
fn print_disambiguation_help<'tcx>(
|
||||||
item_name: Ident,
|
item_name: Ident,
|
||||||
args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>,
|
args: Option<MethodCallComponents<'tcx>>,
|
||||||
err: &mut Diagnostic,
|
err: &mut Diagnostic,
|
||||||
trait_name: String,
|
trait_name: String,
|
||||||
rcvr_ty: Ty<'_>,
|
rcvr_ty: Ty<'_>,
|
||||||
@ -3007,7 +3054,11 @@ fn print_disambiguation_help<'tcx>(
|
|||||||
fn_has_self_parameter: bool,
|
fn_has_self_parameter: bool,
|
||||||
) {
|
) {
|
||||||
let mut applicability = Applicability::MachineApplicable;
|
let mut applicability = Applicability::MachineApplicable;
|
||||||
let (span, sugg) = if let (ty::AssocKind::Fn, Some((receiver, args))) = (kind, args) {
|
let (span, sugg) = if let (
|
||||||
|
ty::AssocKind::Fn,
|
||||||
|
Some(MethodCallComponents { receiver, args, .. }),
|
||||||
|
) = (kind, args)
|
||||||
|
{
|
||||||
let args = format!(
|
let args = format!(
|
||||||
"({}{})",
|
"({}{})",
|
||||||
rcvr_ty.ref_mutability().map_or("", |mutbl| mutbl.ref_prefix_str()),
|
rcvr_ty.ref_mutability().map_or("", |mutbl| mutbl.ref_prefix_str()),
|
||||||
|
13
tests/ui/self/arbitrary_self_type_mut_difference.rs
Normal file
13
tests/ui/self/arbitrary_self_type_mut_difference.rs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Related to #57994.
|
||||||
|
use std::pin::Pin;
|
||||||
|
struct S;
|
||||||
|
|
||||||
|
impl S {
|
||||||
|
fn x(self: Pin<&mut Self>) {} //~ NOTE method is available for `Pin<&mut S>`
|
||||||
|
fn y(self: Pin<&Self>) {} //~ NOTE method is available for `Pin<&S>`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
Pin::new(&S).x(); //~ ERROR no method named `x` found for struct `Pin<&S>` in the current scope
|
||||||
|
Pin::new(&mut S).y(); //~ ERROR no method named `y` found for struct `Pin<&mut S>` in the current scope
|
||||||
|
}
|
27
tests/ui/self/arbitrary_self_type_mut_difference.stderr
Normal file
27
tests/ui/self/arbitrary_self_type_mut_difference.stderr
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
error[E0599]: no method named `x` found for struct `Pin<&S>` in the current scope
|
||||||
|
--> $DIR/arbitrary_self_type_mut_difference.rs:11:18
|
||||||
|
|
|
||||||
|
LL | Pin::new(&S).x();
|
||||||
|
| ^ help: there is a method with a similar name: `y`
|
||||||
|
|
|
||||||
|
note: method is available for `Pin<&mut S>`
|
||||||
|
--> $DIR/arbitrary_self_type_mut_difference.rs:6:5
|
||||||
|
|
|
||||||
|
LL | fn x(self: Pin<&mut Self>) {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0599]: no method named `y` found for struct `Pin<&mut S>` in the current scope
|
||||||
|
--> $DIR/arbitrary_self_type_mut_difference.rs:12:22
|
||||||
|
|
|
||||||
|
LL | Pin::new(&mut S).y();
|
||||||
|
| ^ help: there is a method with a similar name: `x`
|
||||||
|
|
|
||||||
|
note: method is available for `Pin<&S>`
|
||||||
|
--> $DIR/arbitrary_self_type_mut_difference.rs:7:5
|
||||||
|
|
|
||||||
|
LL | fn y(self: Pin<&Self>) {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0599`.
|
@ -0,0 +1,17 @@
|
|||||||
|
// run-rustfix
|
||||||
|
#![allow(dead_code)]
|
||||||
|
mod first {
|
||||||
|
trait Foo { fn m(self: Box<Self>); }
|
||||||
|
fn foo<T: Foo>(a: T) {
|
||||||
|
Box::new(a).m(); //~ ERROR no method named `m` found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mod second {
|
||||||
|
use std::sync::Arc;
|
||||||
|
trait Bar { fn m(self: Arc<Self>); }
|
||||||
|
fn bar(b: impl Bar) {
|
||||||
|
Arc::new(b).m(); //~ ERROR no method named `m` found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,17 @@
|
|||||||
|
// run-rustfix
|
||||||
|
#![allow(dead_code)]
|
||||||
|
mod first {
|
||||||
|
trait Foo { fn m(self: Box<Self>); }
|
||||||
|
fn foo<T: Foo>(a: T) {
|
||||||
|
a.m(); //~ ERROR no method named `m` found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mod second {
|
||||||
|
use std::sync::Arc;
|
||||||
|
trait Bar { fn m(self: Arc<Self>); }
|
||||||
|
fn bar(b: impl Bar) {
|
||||||
|
b.m(); //~ ERROR no method named `m` found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,43 @@
|
|||||||
|
error[E0599]: no method named `m` found for type parameter `T` in the current scope
|
||||||
|
--> $DIR/arbitrary_self_types_needing_box_or_arc_wrapping.rs:6:11
|
||||||
|
|
|
||||||
|
LL | trait Foo { fn m(self: Box<Self>); }
|
||||||
|
| - --------- the method might not be found because of this arbitrary self type
|
||||||
|
| |
|
||||||
|
| the method is available for `Box<T>` here
|
||||||
|
LL | fn foo<T: Foo>(a: T) {
|
||||||
|
| - method `m` not found for this type parameter
|
||||||
|
LL | a.m();
|
||||||
|
| ^ method not found in `T`
|
||||||
|
...
|
||||||
|
LL | trait Bar { fn m(self: Arc<Self>); }
|
||||||
|
| --------- the method might not be found because of this arbitrary self type
|
||||||
|
|
|
||||||
|
help: consider wrapping the receiver expression with the appropriate type
|
||||||
|
|
|
||||||
|
LL | Box::new(a).m();
|
||||||
|
| +++++++++ +
|
||||||
|
|
||||||
|
error[E0599]: no method named `m` found for type parameter `impl Bar` in the current scope
|
||||||
|
--> $DIR/arbitrary_self_types_needing_box_or_arc_wrapping.rs:13:11
|
||||||
|
|
|
||||||
|
LL | trait Foo { fn m(self: Box<Self>); }
|
||||||
|
| --------- the method might not be found because of this arbitrary self type
|
||||||
|
...
|
||||||
|
LL | trait Bar { fn m(self: Arc<Self>); }
|
||||||
|
| - --------- the method might not be found because of this arbitrary self type
|
||||||
|
| |
|
||||||
|
| the method is available for `Arc<impl Bar>` here
|
||||||
|
LL | fn bar(b: impl Bar) {
|
||||||
|
| -------- method `m` not found for this type parameter
|
||||||
|
LL | b.m();
|
||||||
|
| ^ method not found in `impl Bar`
|
||||||
|
|
|
||||||
|
help: consider wrapping the receiver expression with the appropriate type
|
||||||
|
|
|
||||||
|
LL | Arc::new(b).m();
|
||||||
|
| +++++++++ +
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0599`.
|
12
tests/ui/self/arbitrary_self_types_needing_mut_pin.fixed
Normal file
12
tests/ui/self/arbitrary_self_types_needing_mut_pin.fixed
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// run-rustfix
|
||||||
|
use std::pin::Pin;
|
||||||
|
struct S;
|
||||||
|
|
||||||
|
impl S {
|
||||||
|
fn x(self: Pin<&mut Self>) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
Pin::new(&mut S).x(); //~ ERROR no method named `x` found
|
||||||
|
}
|
12
tests/ui/self/arbitrary_self_types_needing_mut_pin.rs
Normal file
12
tests/ui/self/arbitrary_self_types_needing_mut_pin.rs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// run-rustfix
|
||||||
|
use std::pin::Pin;
|
||||||
|
struct S;
|
||||||
|
|
||||||
|
impl S {
|
||||||
|
fn x(self: Pin<&mut Self>) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
S.x(); //~ ERROR no method named `x` found
|
||||||
|
}
|
20
tests/ui/self/arbitrary_self_types_needing_mut_pin.stderr
Normal file
20
tests/ui/self/arbitrary_self_types_needing_mut_pin.stderr
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
error[E0599]: no method named `x` found for struct `S` in the current scope
|
||||||
|
--> $DIR/arbitrary_self_types_needing_mut_pin.rs:11:7
|
||||||
|
|
|
||||||
|
LL | struct S;
|
||||||
|
| -------- method `x` not found for this struct
|
||||||
|
...
|
||||||
|
LL | fn x(self: Pin<&mut Self>) {
|
||||||
|
| - the method is available for `Pin<&mut S>` here
|
||||||
|
...
|
||||||
|
LL | S.x();
|
||||||
|
| ^ method not found in `S`
|
||||||
|
|
|
||||||
|
help: consider wrapping the receiver expression with the appropriate type
|
||||||
|
|
|
||||||
|
LL | Pin::new(&mut S).x();
|
||||||
|
| +++++++++++++ +
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0599`.
|
13
tests/ui/self/arbitrary_self_types_pin_needing_borrow.rs
Normal file
13
tests/ui/self/arbitrary_self_types_pin_needing_borrow.rs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
use std::pin::Pin;
|
||||||
|
struct S;
|
||||||
|
|
||||||
|
impl S {
|
||||||
|
fn x(self: Pin<&mut Self>) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
Pin::new(S).x();
|
||||||
|
//~^ ERROR the trait bound `S: Deref` is not satisfied
|
||||||
|
//~| ERROR no method named `x` found for struct `Pin` in the current scope
|
||||||
|
}
|
33
tests/ui/self/arbitrary_self_types_pin_needing_borrow.stderr
Normal file
33
tests/ui/self/arbitrary_self_types_pin_needing_borrow.stderr
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
error[E0277]: the trait bound `S: Deref` is not satisfied
|
||||||
|
--> $DIR/arbitrary_self_types_pin_needing_borrow.rs:10:14
|
||||||
|
|
|
||||||
|
LL | Pin::new(S).x();
|
||||||
|
| -------- ^ the trait `Deref` is not implemented for `S`
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
note: required by a bound in `Pin::<P>::new`
|
||||||
|
--> $SRC_DIR/core/src/pin.rs:LL:COL
|
||||||
|
help: consider borrowing here
|
||||||
|
|
|
||||||
|
LL | Pin::new(&S).x();
|
||||||
|
| +
|
||||||
|
LL | Pin::new(&mut S).x();
|
||||||
|
| ++++
|
||||||
|
|
||||||
|
error[E0599]: no method named `x` found for struct `Pin` in the current scope
|
||||||
|
--> $DIR/arbitrary_self_types_pin_needing_borrow.rs:10:17
|
||||||
|
|
|
||||||
|
LL | Pin::new(S).x();
|
||||||
|
| ^ method not found in `Pin<S>`
|
||||||
|
|
|
||||||
|
note: method is available for `Pin<&mut S>`
|
||||||
|
--> $DIR/arbitrary_self_types_pin_needing_borrow.rs:5:5
|
||||||
|
|
|
||||||
|
LL | fn x(self: Pin<&mut Self>) {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0277, E0599.
|
||||||
|
For more information about an error, try `rustc --explain E0277`.
|
Loading…
Reference in New Issue
Block a user