Skip to content

Commit 825dc80

Browse files
authoredMay 7, 2022
Rollup merge of rust-lang#96746 - JohnTitor:issue-96738, r=petrochenkov
Fix an ICE on rust-lang#96738 In the block we don't know if the method actually exists thus `expect_local` panics. Fixes rust-lang#96738 Fixes rust-lang#96583
2 parents 102bbc9 + 35d77c1 commit 825dc80

File tree

3 files changed

+38
-10
lines changed

3 files changed

+38
-10
lines changed
 

‎compiler/rustc_typeck/src/check/method/suggest.rs

+19-10
Original file line numberDiff line numberDiff line change
@@ -368,24 +368,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
368368
if self.is_fn_ty(rcvr_ty, span) {
369369
if let SelfSource::MethodCall(expr) = source {
370370
let suggest = if let ty::FnDef(def_id, _) = rcvr_ty.kind() {
371-
let local_id = def_id.expect_local();
372-
let hir_id = tcx.hir().local_def_id_to_hir_id(local_id);
373-
let node = tcx.hir().get(hir_id);
374-
let fields = node.tuple_fields();
375-
376-
if let Some(fields) = fields
377-
&& let Some(DefKind::Ctor(of, _)) = self.tcx.opt_def_kind(local_id) {
378-
Some((fields, of))
371+
if let Some(local_id) = def_id.as_local() {
372+
let hir_id = tcx.hir().local_def_id_to_hir_id(local_id);
373+
let node = tcx.hir().get(hir_id);
374+
let fields = node.tuple_fields();
375+
if let Some(fields) = fields
376+
&& let Some(DefKind::Ctor(of, _)) = self.tcx.opt_def_kind(local_id) {
377+
Some((fields.len(), of))
378+
} else {
379+
None
380+
}
379381
} else {
380-
None
382+
// The logic here isn't smart but `associated_item_def_ids`
383+
// doesn't work nicely on local.
384+
if let DefKind::Ctor(of, _) = tcx.def_kind(def_id) {
385+
let parent_def_id = tcx.parent(*def_id);
386+
Some((tcx.associated_item_def_ids(parent_def_id).len(), of))
387+
} else {
388+
None
389+
}
381390
}
382391
} else {
383392
None
384393
};
385394

386395
// If the function is a tuple constructor, we recommend that they call it
387396
if let Some((fields, kind)) = suggest {
388-
suggest_call_constructor(expr.span, kind, fields.len(), &mut err);
397+
suggest_call_constructor(expr.span, kind, fields, &mut err);
389398
} else {
390399
// General case
391400
err.span_label(

‎src/test/ui/typeck/issue-96738.rs

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

‎src/test/ui/typeck/issue-96738.stderr

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error[E0599]: no method named `nonexistent_method` found for fn item `fn(_) -> Option<_> {Option::<_>::Some}` in the current scope
2+
--> $DIR/issue-96738.rs:2:10
3+
|
4+
LL | Some.nonexistent_method();
5+
| ---- ^^^^^^^^^^^^^^^^^^ method not found in `fn(_) -> Option<_> {Option::<_>::Some}`
6+
| |
7+
| this is the constructor of an enum variant
8+
|
9+
help: call the constructor
10+
|
11+
LL | (Some)(_).nonexistent_method();
12+
| + ++++
13+
14+
error: aborting due to previous error
15+
16+
For more information about this error, try `rustc --explain E0599`.

0 commit comments

Comments
 (0)
Please sign in to comment.