mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 08:44:35 +00:00
Rollup merge of #102288 - mejrs:inner, r=compiler-errors
Suggest unwrapping `???<T>` if a method cannot be found on it but is present on `T`. This suggests various ways to get inside wrapper types if the method cannot be found on the wrapper type, but is present on the wrappee. For this PR, those wrapper types include `Localkey`, `MaybeUninit`, `RefCell`, `RwLock` and `Mutex`.
This commit is contained in:
commit
9436ffc226
@ -2,6 +2,7 @@
|
||||
//! found or is otherwise invalid.
|
||||
|
||||
use crate::check::FnCtxt;
|
||||
use rustc_ast::ast::Mutability;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_errors::{
|
||||
pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
|
||||
@ -30,7 +31,7 @@ use rustc_trait_selection::traits::{
|
||||
use std::cmp::Ordering;
|
||||
use std::iter;
|
||||
|
||||
use super::probe::{IsSuggestion, Mode, ProbeScope};
|
||||
use super::probe::{AutorefOrPtrAdjustment, IsSuggestion, Mode, ProbeScope};
|
||||
use super::{CandidateSource, MethodError, NoMatchData};
|
||||
|
||||
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
@ -983,7 +984,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.check_for_field_method(&mut err, source, span, actual, item_name);
|
||||
}
|
||||
|
||||
self.check_for_unwrap_self(&mut err, source, span, actual, item_name);
|
||||
self.check_for_inner_self(&mut err, source, span, actual, item_name);
|
||||
|
||||
bound_spans.sort();
|
||||
bound_spans.dedup();
|
||||
@ -1395,7 +1396,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_for_unwrap_self(
|
||||
fn check_for_inner_self(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
source: SelfSource<'tcx>,
|
||||
@ -1408,81 +1409,168 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let call_expr = tcx.hir().expect_expr(tcx.hir().get_parent_node(expr.hir_id));
|
||||
|
||||
let ty::Adt(kind, substs) = actual.kind() else { return; };
|
||||
if !kind.is_enum() {
|
||||
return;
|
||||
}
|
||||
match kind.adt_kind() {
|
||||
ty::AdtKind::Enum => {
|
||||
let matching_variants: Vec<_> = kind
|
||||
.variants()
|
||||
.iter()
|
||||
.flat_map(|variant| {
|
||||
let [field] = &variant.fields[..] else { return None; };
|
||||
let field_ty = field.ty(tcx, substs);
|
||||
|
||||
let matching_variants: Vec<_> = kind
|
||||
.variants()
|
||||
.iter()
|
||||
.flat_map(|variant| {
|
||||
let [field] = &variant.fields[..] else { return None; };
|
||||
let field_ty = field.ty(tcx, substs);
|
||||
// Skip `_`, since that'll just lead to ambiguity.
|
||||
if self.resolve_vars_if_possible(field_ty).is_ty_var() {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Skip `_`, since that'll just lead to ambiguity.
|
||||
if self.resolve_vars_if_possible(field_ty).is_ty_var() {
|
||||
return None;
|
||||
}
|
||||
self.lookup_probe(
|
||||
span,
|
||||
item_name,
|
||||
field_ty,
|
||||
call_expr,
|
||||
ProbeScope::TraitsInScope,
|
||||
)
|
||||
.ok()
|
||||
.map(|pick| (variant, field, pick))
|
||||
})
|
||||
.collect();
|
||||
|
||||
self.lookup_probe(span, item_name, field_ty, call_expr, ProbeScope::AllTraits)
|
||||
.ok()
|
||||
.map(|pick| (variant, field, pick))
|
||||
})
|
||||
.collect();
|
||||
|
||||
let ret_ty_matches = |diagnostic_item| {
|
||||
if let Some(ret_ty) = self
|
||||
.ret_coercion
|
||||
.as_ref()
|
||||
.map(|c| self.resolve_vars_if_possible(c.borrow().expected_ty()))
|
||||
&& let ty::Adt(kind, _) = ret_ty.kind()
|
||||
&& tcx.get_diagnostic_item(diagnostic_item) == Some(kind.did())
|
||||
{
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
};
|
||||
|
||||
match &matching_variants[..] {
|
||||
[(_, field, pick)] => {
|
||||
let self_ty = field.ty(tcx, substs);
|
||||
err.span_note(
|
||||
tcx.def_span(pick.item.def_id),
|
||||
&format!("the method `{item_name}` exists on the type `{self_ty}`"),
|
||||
);
|
||||
let (article, kind, variant, question) =
|
||||
if Some(kind.did()) == tcx.get_diagnostic_item(sym::Result) {
|
||||
("a", "Result", "Err", ret_ty_matches(sym::Result))
|
||||
} else if Some(kind.did()) == tcx.get_diagnostic_item(sym::Option) {
|
||||
("an", "Option", "None", ret_ty_matches(sym::Option))
|
||||
let ret_ty_matches = |diagnostic_item| {
|
||||
if let Some(ret_ty) = self
|
||||
.ret_coercion
|
||||
.as_ref()
|
||||
.map(|c| self.resolve_vars_if_possible(c.borrow().expected_ty()))
|
||||
&& let ty::Adt(kind, _) = ret_ty.kind()
|
||||
&& tcx.get_diagnostic_item(diagnostic_item) == Some(kind.did())
|
||||
{
|
||||
true
|
||||
} else {
|
||||
return;
|
||||
false
|
||||
}
|
||||
};
|
||||
|
||||
match &matching_variants[..] {
|
||||
[(_, field, pick)] => {
|
||||
let self_ty = field.ty(tcx, substs);
|
||||
err.span_note(
|
||||
tcx.def_span(pick.item.def_id),
|
||||
&format!("the method `{item_name}` exists on the type `{self_ty}`"),
|
||||
);
|
||||
let (article, kind, variant, question) =
|
||||
if tcx.is_diagnostic_item(sym::Result, kind.did()) {
|
||||
("a", "Result", "Err", ret_ty_matches(sym::Result))
|
||||
} else if tcx.is_diagnostic_item(sym::Option, kind.did()) {
|
||||
("an", "Option", "None", ret_ty_matches(sym::Option))
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
if question {
|
||||
err.span_suggestion_verbose(
|
||||
expr.span.shrink_to_hi(),
|
||||
format!(
|
||||
"use the `?` operator to extract the `{self_ty}` value, propagating \
|
||||
{article} `{kind}::{variant}` value to the caller"
|
||||
),
|
||||
"?",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else {
|
||||
err.span_suggestion_verbose(
|
||||
expr.span.shrink_to_hi(),
|
||||
format!(
|
||||
"consider using `{kind}::expect` to unwrap the `{self_ty}` value, \
|
||||
panicking if the value is {article} `{kind}::{variant}`"
|
||||
),
|
||||
".expect(\"REASON\")",
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
}
|
||||
}
|
||||
// FIXME(compiler-errors): Support suggestions for other matching enum variants
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
// Target wrapper types - types that wrap or pretend to wrap another type,
|
||||
// perhaps this inner type is meant to be called?
|
||||
ty::AdtKind::Struct | ty::AdtKind::Union => {
|
||||
let [first] = ***substs else { return; };
|
||||
let ty::GenericArgKind::Type(ty) = first.unpack() else { return; };
|
||||
let Ok(pick) = self.lookup_probe(
|
||||
span,
|
||||
item_name,
|
||||
ty,
|
||||
call_expr,
|
||||
ProbeScope::TraitsInScope,
|
||||
) else { return; };
|
||||
|
||||
let name = self.ty_to_value_string(actual);
|
||||
let inner_id = kind.did();
|
||||
let mutable = if let Some(AutorefOrPtrAdjustment::Autoref { mutbl, .. }) =
|
||||
pick.autoref_or_ptr_adjustment
|
||||
{
|
||||
Some(mutbl)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if tcx.is_diagnostic_item(sym::LocalKey, inner_id) {
|
||||
err.help("use `with` or `try_with` to access thread local storage");
|
||||
} else if Some(kind.did()) == tcx.lang_items().maybe_uninit() {
|
||||
err.help(format!(
|
||||
"if this `{name}` has been initialized, \
|
||||
use one of the `assume_init` methods to access the inner value"
|
||||
));
|
||||
} else if tcx.is_diagnostic_item(sym::RefCell, inner_id) {
|
||||
let (suggestion, borrow_kind, panic_if) = match mutable {
|
||||
Some(Mutability::Not) => (".borrow()", "borrow", "a mutable borrow exists"),
|
||||
Some(Mutability::Mut) => {
|
||||
(".borrow_mut()", "mutably borrow", "any borrows exist")
|
||||
}
|
||||
None => return,
|
||||
};
|
||||
if question {
|
||||
err.span_suggestion_verbose(
|
||||
expr.span.shrink_to_hi(),
|
||||
format!(
|
||||
"use the `?` operator to extract the `{self_ty}` value, propagating \
|
||||
{article} `{kind}::{variant}` value to the caller"
|
||||
"use `{suggestion}` to {borrow_kind} the `{ty}`, \
|
||||
panicking if {panic_if}"
|
||||
),
|
||||
"?",
|
||||
Applicability::MachineApplicable,
|
||||
suggestion,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else if tcx.is_diagnostic_item(sym::Mutex, inner_id) {
|
||||
err.span_suggestion_verbose(
|
||||
expr.span.shrink_to_hi(),
|
||||
format!(
|
||||
"use `.lock().unwrap()` to borrow the `{ty}`, \
|
||||
blocking the current thread until it can be acquired"
|
||||
),
|
||||
".lock().unwrap()",
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else if tcx.is_diagnostic_item(sym::RwLock, inner_id) {
|
||||
let (suggestion, borrow_kind) = match mutable {
|
||||
Some(Mutability::Not) => (".read().unwrap()", "borrow"),
|
||||
Some(Mutability::Mut) => (".write().unwrap()", "mutably borrow"),
|
||||
None => return,
|
||||
};
|
||||
err.span_suggestion_verbose(
|
||||
expr.span.shrink_to_hi(),
|
||||
format!(
|
||||
"use `{suggestion}` to {borrow_kind} the `{ty}`, \
|
||||
blocking the current thread until it can be acquired"
|
||||
),
|
||||
suggestion,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else {
|
||||
err.span_suggestion_verbose(
|
||||
expr.span.shrink_to_hi(),
|
||||
format!(
|
||||
"consider using `{kind}::expect` to unwrap the `{self_ty}` value, \
|
||||
panicking if the value is {article} `{kind}::{variant}`"
|
||||
),
|
||||
".expect(\"REASON\")",
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
err.span_note(
|
||||
tcx.def_span(pick.item.def_id),
|
||||
&format!("the method `{item_name}` exists on the type `{ty}`"),
|
||||
);
|
||||
}
|
||||
// FIXME(compiler-errors): Support suggestions for other matching enum variants
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -224,6 +224,7 @@ symbols! {
|
||||
Left,
|
||||
LinkedList,
|
||||
LintPass,
|
||||
LocalKey,
|
||||
Mutex,
|
||||
MutexGuard,
|
||||
N,
|
||||
@ -266,6 +267,7 @@ symbols! {
|
||||
Rc,
|
||||
Ready,
|
||||
Receiver,
|
||||
RefCell,
|
||||
Relaxed,
|
||||
Release,
|
||||
Result,
|
||||
@ -274,6 +276,7 @@ symbols! {
|
||||
Rust,
|
||||
RustcDecodable,
|
||||
RustcEncodable,
|
||||
RwLock,
|
||||
RwLockReadGuard,
|
||||
RwLockWriteGuard,
|
||||
Send,
|
||||
|
@ -614,6 +614,7 @@ impl<T, const N: usize> Cell<[T; N]> {
|
||||
/// A mutable memory location with dynamically checked borrow rules
|
||||
///
|
||||
/// See the [module-level documentation](self) for more.
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "RefCell")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct RefCell<T: ?Sized> {
|
||||
borrow: Cell<BorrowFlag>,
|
||||
|
@ -76,6 +76,7 @@ use crate::sys_common::rwlock as sys;
|
||||
///
|
||||
/// [`Mutex`]: super::Mutex
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "RwLock")]
|
||||
pub struct RwLock<T: ?Sized> {
|
||||
inner: sys::MovableRwLock,
|
||||
poison: poison::Flag,
|
||||
|
@ -95,6 +95,7 @@ use crate::fmt;
|
||||
/// [loader lock]: https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-best-practices
|
||||
/// [`JoinHandle::join`]: crate::thread::JoinHandle::join
|
||||
/// [`with`]: LocalKey::with
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "LocalKey")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct LocalKey<T: 'static> {
|
||||
// This outer `LocalKey<T>` type is what's going to be stored in statics,
|
||||
|
40
src/test/ui/suggestions/inner_type.fixed
Normal file
40
src/test/ui/suggestions/inner_type.fixed
Normal file
@ -0,0 +1,40 @@
|
||||
// compile-flags: --edition=2021
|
||||
// run-rustfix
|
||||
|
||||
pub struct Struct<T> {
|
||||
pub p: T,
|
||||
}
|
||||
|
||||
impl<T> Struct<T> {
|
||||
pub fn method(&self) {}
|
||||
|
||||
pub fn some_mutable_method(&mut self) {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let other_item = std::cell::RefCell::new(Struct { p: 42_u32 });
|
||||
|
||||
other_item.borrow().method();
|
||||
//~^ ERROR no method named `method` found for struct `RefCell` in the current scope [E0599]
|
||||
//~| HELP use `.borrow()` to borrow the `Struct<u32>`, panicking if a mutable borrow exists
|
||||
|
||||
other_item.borrow_mut().some_mutable_method();
|
||||
//~^ ERROR no method named `some_mutable_method` found for struct `RefCell` in the current scope [E0599]
|
||||
//~| HELP .borrow_mut()` to mutably borrow the `Struct<u32>`, panicking if any borrows exist
|
||||
|
||||
let another_item = std::sync::Mutex::new(Struct { p: 42_u32 });
|
||||
|
||||
another_item.lock().unwrap().method();
|
||||
//~^ ERROR no method named `method` found for struct `Mutex` in the current scope [E0599]
|
||||
//~| HELP use `.lock().unwrap()` to borrow the `Struct<u32>`, blocking the current thread until it can be acquired
|
||||
|
||||
let another_item = std::sync::RwLock::new(Struct { p: 42_u32 });
|
||||
|
||||
another_item.read().unwrap().method();
|
||||
//~^ ERROR no method named `method` found for struct `RwLock` in the current scope [E0599]
|
||||
//~| HELP use `.read().unwrap()` to borrow the `Struct<u32>`, blocking the current thread until it can be acquired
|
||||
|
||||
another_item.write().unwrap().some_mutable_method();
|
||||
//~^ ERROR no method named `some_mutable_method` found for struct `RwLock` in the current scope [E0599]
|
||||
//~| HELP use `.write().unwrap()` to mutably borrow the `Struct<u32>`, blocking the current thread until it can be acquired
|
||||
}
|
40
src/test/ui/suggestions/inner_type.rs
Normal file
40
src/test/ui/suggestions/inner_type.rs
Normal file
@ -0,0 +1,40 @@
|
||||
// compile-flags: --edition=2021
|
||||
// run-rustfix
|
||||
|
||||
pub struct Struct<T> {
|
||||
pub p: T,
|
||||
}
|
||||
|
||||
impl<T> Struct<T> {
|
||||
pub fn method(&self) {}
|
||||
|
||||
pub fn some_mutable_method(&mut self) {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let other_item = std::cell::RefCell::new(Struct { p: 42_u32 });
|
||||
|
||||
other_item.method();
|
||||
//~^ ERROR no method named `method` found for struct `RefCell` in the current scope [E0599]
|
||||
//~| HELP use `.borrow()` to borrow the `Struct<u32>`, panicking if a mutable borrow exists
|
||||
|
||||
other_item.some_mutable_method();
|
||||
//~^ ERROR no method named `some_mutable_method` found for struct `RefCell` in the current scope [E0599]
|
||||
//~| HELP .borrow_mut()` to mutably borrow the `Struct<u32>`, panicking if any borrows exist
|
||||
|
||||
let another_item = std::sync::Mutex::new(Struct { p: 42_u32 });
|
||||
|
||||
another_item.method();
|
||||
//~^ ERROR no method named `method` found for struct `Mutex` in the current scope [E0599]
|
||||
//~| HELP use `.lock().unwrap()` to borrow the `Struct<u32>`, blocking the current thread until it can be acquired
|
||||
|
||||
let another_item = std::sync::RwLock::new(Struct { p: 42_u32 });
|
||||
|
||||
another_item.method();
|
||||
//~^ ERROR no method named `method` found for struct `RwLock` in the current scope [E0599]
|
||||
//~| HELP use `.read().unwrap()` to borrow the `Struct<u32>`, blocking the current thread until it can be acquired
|
||||
|
||||
another_item.some_mutable_method();
|
||||
//~^ ERROR no method named `some_mutable_method` found for struct `RwLock` in the current scope [E0599]
|
||||
//~| HELP use `.write().unwrap()` to mutably borrow the `Struct<u32>`, blocking the current thread until it can be acquired
|
||||
}
|
83
src/test/ui/suggestions/inner_type.stderr
Normal file
83
src/test/ui/suggestions/inner_type.stderr
Normal file
@ -0,0 +1,83 @@
|
||||
error[E0599]: no method named `method` found for struct `RefCell` in the current scope
|
||||
--> $DIR/inner_type.rs:17:16
|
||||
|
|
||||
LL | other_item.method();
|
||||
| ^^^^^^ method not found in `RefCell<Struct<u32>>`
|
||||
|
|
||||
note: the method `method` exists on the type `Struct<u32>`
|
||||
--> $DIR/inner_type.rs:9:5
|
||||
|
|
||||
LL | pub fn method(&self) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
help: use `.borrow()` to borrow the `Struct<u32>`, panicking if a mutable borrow exists
|
||||
|
|
||||
LL | other_item.borrow().method();
|
||||
| +++++++++
|
||||
|
||||
error[E0599]: no method named `some_mutable_method` found for struct `RefCell` in the current scope
|
||||
--> $DIR/inner_type.rs:21:16
|
||||
|
|
||||
LL | other_item.some_mutable_method();
|
||||
| ^^^^^^^^^^^^^^^^^^^ method not found in `RefCell<Struct<u32>>`
|
||||
|
|
||||
note: the method `some_mutable_method` exists on the type `Struct<u32>`
|
||||
--> $DIR/inner_type.rs:11:5
|
||||
|
|
||||
LL | pub fn some_mutable_method(&mut self) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: use `.borrow_mut()` to mutably borrow the `Struct<u32>`, panicking if any borrows exist
|
||||
|
|
||||
LL | other_item.borrow_mut().some_mutable_method();
|
||||
| +++++++++++++
|
||||
|
||||
error[E0599]: no method named `method` found for struct `Mutex` in the current scope
|
||||
--> $DIR/inner_type.rs:27:18
|
||||
|
|
||||
LL | another_item.method();
|
||||
| ^^^^^^ method not found in `Mutex<Struct<u32>>`
|
||||
|
|
||||
note: the method `method` exists on the type `Struct<u32>`
|
||||
--> $DIR/inner_type.rs:9:5
|
||||
|
|
||||
LL | pub fn method(&self) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
help: use `.lock().unwrap()` to borrow the `Struct<u32>`, blocking the current thread until it can be acquired
|
||||
|
|
||||
LL | another_item.lock().unwrap().method();
|
||||
| ++++++++++++++++
|
||||
|
||||
error[E0599]: no method named `method` found for struct `RwLock` in the current scope
|
||||
--> $DIR/inner_type.rs:33:18
|
||||
|
|
||||
LL | another_item.method();
|
||||
| ^^^^^^ method not found in `RwLock<Struct<u32>>`
|
||||
|
|
||||
note: the method `method` exists on the type `Struct<u32>`
|
||||
--> $DIR/inner_type.rs:9:5
|
||||
|
|
||||
LL | pub fn method(&self) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
help: use `.read().unwrap()` to borrow the `Struct<u32>`, blocking the current thread until it can be acquired
|
||||
|
|
||||
LL | another_item.read().unwrap().method();
|
||||
| ++++++++++++++++
|
||||
|
||||
error[E0599]: no method named `some_mutable_method` found for struct `RwLock` in the current scope
|
||||
--> $DIR/inner_type.rs:37:18
|
||||
|
|
||||
LL | another_item.some_mutable_method();
|
||||
| ^^^^^^^^^^^^^^^^^^^ method not found in `RwLock<Struct<u32>>`
|
||||
|
|
||||
note: the method `some_mutable_method` exists on the type `Struct<u32>`
|
||||
--> $DIR/inner_type.rs:11:5
|
||||
|
|
||||
LL | pub fn some_mutable_method(&mut self) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: use `.write().unwrap()` to mutably borrow the `Struct<u32>`, blocking the current thread until it can be acquired
|
||||
|
|
||||
LL | another_item.write().unwrap().some_mutable_method();
|
||||
| +++++++++++++++++
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
26
src/test/ui/suggestions/inner_type2.rs
Normal file
26
src/test/ui/suggestions/inner_type2.rs
Normal file
@ -0,0 +1,26 @@
|
||||
pub struct Struct<T> {
|
||||
pub p: T,
|
||||
}
|
||||
|
||||
impl<T> Struct<T> {
|
||||
pub fn method(&self) {}
|
||||
|
||||
pub fn some_mutable_method(&mut self) {}
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
static STRUCT: Struct<u32> = Struct {
|
||||
p: 42_u32
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {
|
||||
STRUCT.method();
|
||||
//~^ ERROR no method named `method` found for struct `LocalKey` in the current scope [E0599]
|
||||
//~| HELP use `with` or `try_with` to access thread local storage
|
||||
|
||||
let item = std::mem::MaybeUninit::new(Struct { p: 42_u32 });
|
||||
item.method();
|
||||
//~^ ERROR no method named `method` found for union `MaybeUninit` in the current scope [E0599]
|
||||
//~| HELP if this `MaybeUninit::<Struct<u32>>` has been initialized, use one of the `assume_init` methods to access the inner value
|
||||
}
|
29
src/test/ui/suggestions/inner_type2.stderr
Normal file
29
src/test/ui/suggestions/inner_type2.stderr
Normal file
@ -0,0 +1,29 @@
|
||||
error[E0599]: no method named `method` found for struct `LocalKey` in the current scope
|
||||
--> $DIR/inner_type2.rs:18:12
|
||||
|
|
||||
LL | STRUCT.method();
|
||||
| ^^^^^^ method not found in `LocalKey<Struct<u32>>`
|
||||
|
|
||||
= help: use `with` or `try_with` to access thread local storage
|
||||
note: the method `method` exists on the type `Struct<u32>`
|
||||
--> $DIR/inner_type2.rs:6:5
|
||||
|
|
||||
LL | pub fn method(&self) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0599]: no method named `method` found for union `MaybeUninit` in the current scope
|
||||
--> $DIR/inner_type2.rs:23:10
|
||||
|
|
||||
LL | item.method();
|
||||
| ^^^^^^ method not found in `MaybeUninit<Struct<u32>>`
|
||||
|
|
||||
= help: if this `MaybeUninit::<Struct<u32>>` has been initialized, use one of the `assume_init` methods to access the inner value
|
||||
note: the method `method` exists on the type `Struct<u32>`
|
||||
--> $DIR/inner_type2.rs:6:5
|
||||
|
|
||||
LL | pub fn method(&self) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
Loading…
Reference in New Issue
Block a user