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:
Michael Goulet 2022-05-06 20:49:32 -07:00 committed by GitHub
commit 825dc80d1a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 10 deletions

View File

@ -368,16 +368,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if self.is_fn_ty(rcvr_ty, span) {
if let SelfSource::MethodCall(expr) = source {
let suggest = if let ty::FnDef(def_id, _) = rcvr_ty.kind() {
let local_id = def_id.expect_local();
let hir_id = tcx.hir().local_def_id_to_hir_id(local_id);
let node = tcx.hir().get(hir_id);
let fields = node.tuple_fields();
if let Some(fields) = fields
&& let Some(DefKind::Ctor(of, _)) = self.tcx.opt_def_kind(local_id) {
Some((fields, of))
if let Some(local_id) = def_id.as_local() {
let hir_id = tcx.hir().local_def_id_to_hir_id(local_id);
let node = tcx.hir().get(hir_id);
let fields = node.tuple_fields();
if let Some(fields) = fields
&& let Some(DefKind::Ctor(of, _)) = self.tcx.opt_def_kind(local_id) {
Some((fields.len(), of))
} else {
None
}
} 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 {
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 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 {
// General case
err.span_label(

View File

@ -0,0 +1,3 @@
fn main() {
Some.nonexistent_method(); //~ ERROR: no method named `nonexistent_method` found
}

View 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`.