Rollup merge of #96746 - JohnTitor:issue-96738, r=petrochenkov
Fix an ICE on #96738 In the block we don't know if the method actually exists thus `expect_local` panics. Fixes #96738 Fixes #96583
This commit is contained in:
commit
825dc80d1a
@ -368,16 +368,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
if self.is_fn_ty(rcvr_ty, span) {
|
if self.is_fn_ty(rcvr_ty, span) {
|
||||||
if let SelfSource::MethodCall(expr) = source {
|
if let SelfSource::MethodCall(expr) = source {
|
||||||
let suggest = if let ty::FnDef(def_id, _) = rcvr_ty.kind() {
|
let suggest = if let ty::FnDef(def_id, _) = rcvr_ty.kind() {
|
||||||
let local_id = def_id.expect_local();
|
if let Some(local_id) = def_id.as_local() {
|
||||||
let hir_id = tcx.hir().local_def_id_to_hir_id(local_id);
|
let hir_id = tcx.hir().local_def_id_to_hir_id(local_id);
|
||||||
let node = tcx.hir().get(hir_id);
|
let node = tcx.hir().get(hir_id);
|
||||||
let fields = node.tuple_fields();
|
let fields = node.tuple_fields();
|
||||||
|
if let Some(fields) = fields
|
||||||
if let Some(fields) = fields
|
&& let Some(DefKind::Ctor(of, _)) = self.tcx.opt_def_kind(local_id) {
|
||||||
&& let Some(DefKind::Ctor(of, _)) = self.tcx.opt_def_kind(local_id) {
|
Some((fields.len(), of))
|
||||||
Some((fields, of))
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
// The logic here isn't smart but `associated_item_def_ids`
|
||||||
|
// doesn't work nicely on local.
|
||||||
|
if let DefKind::Ctor(of, _) = tcx.def_kind(def_id) {
|
||||||
|
let parent_def_id = tcx.parent(*def_id);
|
||||||
|
Some((tcx.associated_item_def_ids(parent_def_id).len(), of))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -385,7 +394,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
// If the function is a tuple constructor, we recommend that they call it
|
// If the function is a tuple constructor, we recommend that they call it
|
||||||
if let Some((fields, kind)) = suggest {
|
if let Some((fields, kind)) = suggest {
|
||||||
suggest_call_constructor(expr.span, kind, fields.len(), &mut err);
|
suggest_call_constructor(expr.span, kind, fields, &mut err);
|
||||||
} else {
|
} else {
|
||||||
// General case
|
// General case
|
||||||
err.span_label(
|
err.span_label(
|
||||||
|
3
src/test/ui/typeck/issue-96738.rs
Normal file
3
src/test/ui/typeck/issue-96738.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fn main() {
|
||||||
|
Some.nonexistent_method(); //~ ERROR: no method named `nonexistent_method` found
|
||||||
|
}
|
16
src/test/ui/typeck/issue-96738.stderr
Normal file
16
src/test/ui/typeck/issue-96738.stderr
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
error[E0599]: no method named `nonexistent_method` found for fn item `fn(_) -> Option<_> {Option::<_>::Some}` in the current scope
|
||||||
|
--> $DIR/issue-96738.rs:2:10
|
||||||
|
|
|
||||||
|
LL | Some.nonexistent_method();
|
||||||
|
| ---- ^^^^^^^^^^^^^^^^^^ method not found in `fn(_) -> Option<_> {Option::<_>::Some}`
|
||||||
|
| |
|
||||||
|
| this is the constructor of an enum variant
|
||||||
|
|
|
||||||
|
help: call the constructor
|
||||||
|
|
|
||||||
|
LL | (Some)(_).nonexistent_method();
|
||||||
|
| + ++++
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0599`.
|
Loading…
x
Reference in New Issue
Block a user