about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2018-03-06 20:01:12 -0600
committerAlex Crichton <alex@alexcrichton.com>2018-03-07 07:09:52 -0800
commit0e6df533d47baad149f4c0d49c2c60cb79d7a2d7 (patch)
tree65c6f70f103ba8703c022e42dd0da5518ca3149f
parent584a28f0c01025831200d9a3939b859a6837d144 (diff)
parentf5a3efee88b3a2bf2d69b74f2d5a7eb75049f5ef (diff)
downloadrust-0e6df533d47baad149f4c0d49c2c60cb79d7a2d7.tar.gz
rust-0e6df533d47baad149f4c0d49c2c60cb79d7a2d7.zip
Rollup merge of #48778 - sinkuu:rls_crash_tuple_struct, r=nrc
Fix save-analysis generation crash with invalid tuple access

Reproduction:

```rust
fn invalid_tuple_struct_accessing() {
    bar.0;
}
```
```
error[E0425]: cannot find value `bar` in this scope
 --> test.rs:2:5
  |
2 |     bar.0;
  |     ^^^ not found in this scope

error[E0601]: main function not found

error: internal compiler error: librustc_save_analysis/dump_visitor.rs:1678: Expected struct or tuple type, found TyError
 --> test.rs:2:5
  |
2 |     bar.0;
  |     ^^^^^

thread 'rustc' panicked at 'Box<Any>', librustc_errors/lib.rs:482:9
note: Run with `RUST_BACKTRACE=1` for a backtrace.
```

This should fix a crash in RLS when editing such code. cc @nrc
-rw-r--r--src/librustc_save_analysis/dump_visitor.rs22
-rw-r--r--src/test/run-make/save-analysis-fail/foo.rs7
2 files changed, 21 insertions, 8 deletions
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index 6e986041013..d92025a6787 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -1665,17 +1665,23 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
                         if !self.span.filter_generated(sub_span, ex.span) {
                             let span =
                                 self.span_from_span(sub_span.expect("No span found for var ref"));
-                            let ref_id =
-                                ::id_from_def_id(def.non_enum_variant().fields[idx.node].did);
-                            self.dumper.dump_ref(Ref {
-                                kind: RefKind::Variable,
-                                span,
-                                ref_id,
-                            });
+                            if let Some(field) = def.non_enum_variant().fields.get(idx.node) {
+                                let ref_id = ::id_from_def_id(field.did);
+                                self.dumper.dump_ref(Ref {
+                                    kind: RefKind::Variable,
+                                    span,
+                                    ref_id,
+                                });
+                            } else {
+                                return;
+                            }
                         }
                     }
                     ty::TyTuple(..) => {}
-                    _ => span_bug!(ex.span, "Expected struct or tuple type, found {:?}", ty),
+                    _ => {
+                        debug!("Expected struct or tuple type, found {:?}", ty);
+                        return;
+                    }
                 }
             }
             ast::ExprKind::Closure(_, _, ref decl, ref body, _fn_decl_span) => {
diff --git a/src/test/run-make/save-analysis-fail/foo.rs b/src/test/run-make/save-analysis-fail/foo.rs
index 07322d8bbc3..b844f2e49e7 100644
--- a/src/test/run-make/save-analysis-fail/foo.rs
+++ b/src/test/run-make/save-analysis-fail/foo.rs
@@ -459,3 +459,10 @@ struct Rls699 {
 fn new(f: u32) -> Rls699 {
     Rls699 { fs }
 }
+
+fn invalid_tuple_struct_access() {
+    bar.0;
+
+    struct S;
+    S.0;
+}