Skip to content

save-analysis: fix ICE on partially resolved path #37908

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Nov 23, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 26 additions & 5 deletions src/librustc_save_analysis/dump_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
fn lookup_def_id(&self, ref_id: NodeId) -> Option<DefId> {
self.tcx.expect_def_or_none(ref_id).and_then(|def| {
match def {
Def::PrimTy(..) | Def::SelfTy(..) => None,
Def::Label(..) | Def::PrimTy(..) | Def::SelfTy(..) | Def::Err => None,
def => Some(def.def_id()),
}
})
Expand Down Expand Up @@ -357,7 +357,10 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
collector.visit_pat(&arg.pat);
let span_utils = self.span.clone();
for &(id, ref p, ..) in &collector.collected_paths {
let typ = self.tcx.tables().node_types.get(&id).unwrap().to_string();
let typ = match self.tcx.tables().node_types.get(&id) {
Some(s) => s.to_string(),
None => continue,
};
// get the span only for the name of the variable (I hope the path is only ever a
// variable name, but who knows?)
let sub_span = span_utils.span_for_last_ident(p.span);
Expand Down Expand Up @@ -987,7 +990,13 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
match p.node {
PatKind::Struct(ref path, ref fields, _) => {
visit::walk_path(self, path);
let adt = self.tcx.tables().node_id_to_type(p.id).ty_adt_def().unwrap();
let adt = match self.tcx.tables().node_id_to_type_opt(p.id) {
Some(ty) => ty.ty_adt_def().unwrap(),
None => {
visit::walk_pat(self, p);
return;
}
};
let variant = adt.variant_of_def(self.tcx.expect_def(p.id));

for &Spanned { node: ref field, span } in fields {
Expand Down Expand Up @@ -1353,7 +1362,13 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D>
}
ast::ExprKind::Struct(ref path, ref fields, ref base) => {
let hir_expr = self.save_ctxt.tcx.map.expect_expr(ex.id);
let adt = self.tcx.tables().expr_ty(&hir_expr).ty_adt_def().unwrap();
let adt = match self.tcx.tables().expr_ty_opt(&hir_expr) {
Some(ty) => ty.ty_adt_def().unwrap(),
None => {
visit::walk_expr(self, ex);
return;
}
};
let def = self.tcx.expect_def(hir_expr.id);
self.process_struct_lit(ex, path, fields, adt.variant_of_def(def), base)
}
Expand All @@ -1379,7 +1394,13 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D>
return;
}
};
let ty = &self.tcx.tables().expr_ty_adjusted(&hir_node).sty;
let ty = match self.tcx.tables().expr_ty_adjusted_opt(&hir_node) {
Some(ty) => &ty.sty,
None => {
visit::walk_expr(self, ex);
return;
}
};
match *ty {
ty::TyAdt(def, _) => {
let sub_span = self.span.sub_span_after_token(ex.span, token::Dot);
Expand Down
7 changes: 6 additions & 1 deletion src/librustc_save_analysis/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,12 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
}

pub fn get_path_data(&self, id: NodeId, path: &ast::Path) -> Option<Data> {
let def = self.tcx.expect_def(id);
let resolution = self.tcx.expect_resolution(id);
if resolution.depth != 0 {
return None;
}
let def = resolution.base_def;

let sub_span = self.span_utils.span_for_last_ident(path.span);
filter!(self.span_utils, sub_span, path.span, None);
match def {
Expand Down
6 changes: 6 additions & 0 deletions src/test/run-make/save-analysis-fail/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
-include ../tools.mk
all: code
krate2: krate2.rs
$(RUSTC) $<
code: foo.rs krate2
$(RUSTC) foo.rs -Zsave-analysis || exit 0
15 changes: 15 additions & 0 deletions src/test/run-make/save-analysis-fail/SameDir.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// sub-module in the same directory as the main crate file

pub struct SameStruct {
pub name: String
}
13 changes: 13 additions & 0 deletions src/test/run-make/save-analysis-fail/SameDir3.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

pub fn hello(x: isize) {
println!("macro {} :-(", x);
}
37 changes: 37 additions & 0 deletions src/test/run-make/save-analysis-fail/SubDir/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// sub-module in a sub-directory

use sub::sub2 as msalias;
use sub::sub2;

static yy: usize = 25;

mod sub {
pub mod sub2 {
pub mod sub3 {
pub fn hello() {
println!("hello from module 3");
}
}
pub fn hello() {
println!("hello from a module");
}

pub struct nested_struct {
pub field2: u32,
}
}
}

pub struct SubStruct {
pub name: String
}
Loading