Auto merge of #45798 - nrc:rls-bugs-3, r=eddyb
A couple more save-analysis fixes r? @eddyb
This commit is contained in:
commit
19402f11e1
3 changed files with 48 additions and 83 deletions
|
@ -521,39 +521,41 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
|
|||
item: &'l ast::Item,
|
||||
def: &'l ast::VariantData,
|
||||
ty_params: &'l ast::Generics) {
|
||||
debug!("process_struct {:?} {:?}", item, item.span);
|
||||
let name = item.ident.to_string();
|
||||
let qualname = format!("::{}", self.tcx.node_path_str(item.id));
|
||||
|
||||
let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Struct);
|
||||
let (value, fields) =
|
||||
if let ast::ItemKind::Struct(ast::VariantData::Struct(ref fields, _), _) = item.node
|
||||
{
|
||||
let include_priv_fields = !self.save_ctxt.config.pub_only;
|
||||
let fields_str = fields
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(i, f)| {
|
||||
if include_priv_fields || f.vis == ast::Visibility::Public {
|
||||
f.ident.map(|i| i.to_string()).or_else(|| Some(i.to_string()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
let value = format!("{} {{ {} }}", name, fields_str);
|
||||
(value, fields.iter().map(|f| ::id_from_node_id(f.id, &self.save_ctxt)).collect())
|
||||
} else {
|
||||
(String::new(), vec![])
|
||||
let (kind, keyword) = match item.node {
|
||||
ast::ItemKind::Struct(_, _) => (DefKind::Struct, keywords::Struct),
|
||||
ast::ItemKind::Union(_, _) => (DefKind::Union, keywords::Union),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let sub_span = self.span.sub_span_after_keyword(item.span, keyword);
|
||||
let (value, fields) = match item.node {
|
||||
ast::ItemKind::Struct(ast::VariantData::Struct(ref fields, _), _) |
|
||||
ast::ItemKind::Union(ast::VariantData::Struct(ref fields, _), _) => {
|
||||
let include_priv_fields = !self.save_ctxt.config.pub_only;
|
||||
let fields_str = fields
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(i, f)| {
|
||||
if include_priv_fields || f.vis == ast::Visibility::Public {
|
||||
f.ident.map(|i| i.to_string()).or_else(|| Some(i.to_string()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
let value = format!("{} {{ {} }}", name, fields_str);
|
||||
(value, fields.iter().map(|f| ::id_from_node_id(f.id, &self.save_ctxt)).collect())
|
||||
}
|
||||
_ => (String::new(), vec![])
|
||||
};
|
||||
|
||||
if !self.span.filter_generated(sub_span, item.span) {
|
||||
let span = self.span_from_span(sub_span.expect("No span found for struct"));
|
||||
let kind = match item.node {
|
||||
ast::ItemKind::Struct(_, _) => DefKind::Struct,
|
||||
ast::ItemKind::Union(_, _) => DefKind::Union,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
self.dumper.dump_def(item.vis == ast::Visibility::Public, Def {
|
||||
kind,
|
||||
id: ::id_from_node_id(item.id, &self.save_ctxt),
|
||||
|
@ -876,6 +878,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
|
|||
ex: &'l ast::Expr,
|
||||
seg: &'l ast::PathSegment,
|
||||
args: &'l [P<ast::Expr>]) {
|
||||
debug!("process_method_call {:?} {:?}", ex, ex.span);
|
||||
if let Some(mcd) = self.save_ctxt.get_expr_data(ex) {
|
||||
down_cast_data!(mcd, RefData, ex.span);
|
||||
if !generated_code(ex.span) {
|
||||
|
|
|
@ -546,16 +546,16 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
|||
}
|
||||
}
|
||||
}
|
||||
ast::ExprKind::MethodCall(..) => {
|
||||
ast::ExprKind::MethodCall(ref seg, ..) => {
|
||||
let expr_hir_id = self.tcx.hir.definitions().node_to_hir_id(expr.id);
|
||||
let method_id = self.tables.type_dependent_defs()[expr_hir_id].def_id();
|
||||
let (def_id, decl_id) = match self.tcx.associated_item(method_id).container {
|
||||
ty::ImplContainer(_) => (Some(method_id), None),
|
||||
ty::TraitContainer(_) => (None, Some(method_id)),
|
||||
};
|
||||
let sub_span = self.span_utils.sub_span_for_meth_name(expr.span);
|
||||
filter!(self.span_utils, sub_span, expr.span, None);
|
||||
let span = self.span_from_span(sub_span.unwrap());
|
||||
let sub_span = seg.span;
|
||||
filter!(self.span_utils, Some(sub_span), expr.span, None);
|
||||
let span = self.span_from_span(sub_span);
|
||||
Some(Data::RefData(Ref {
|
||||
kind: RefKind::Function,
|
||||
span,
|
||||
|
@ -627,13 +627,18 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
|||
false
|
||||
}
|
||||
|
||||
if path.segments.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let def = self.get_path_def(id);
|
||||
let sub_span = self.span_utils.span_for_last_ident(path.span);
|
||||
filter!(self.span_utils, sub_span, path.span, None);
|
||||
let last_seg = &path.segments[path.segments.len() - 1];
|
||||
let sub_span = last_seg.span;
|
||||
filter!(self.span_utils, Some(sub_span), path.span, None);
|
||||
match def {
|
||||
HirDef::Upvar(id, ..) |
|
||||
HirDef::Local(id) => {
|
||||
let span = self.span_from_span(sub_span.unwrap());
|
||||
let span = self.span_from_span(sub_span);
|
||||
Some(Ref {
|
||||
kind: RefKind::Variable,
|
||||
span,
|
||||
|
@ -644,7 +649,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
|||
HirDef::Const(..) |
|
||||
HirDef::AssociatedConst(..) |
|
||||
HirDef::VariantCtor(..) => {
|
||||
let span = self.span_from_span(sub_span.unwrap());
|
||||
let span = self.span_from_span(sub_span);
|
||||
Some(Ref {
|
||||
kind: RefKind::Variable,
|
||||
span,
|
||||
|
@ -670,7 +675,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
|||
HirDef::AssociatedTy(def_id) |
|
||||
HirDef::Trait(def_id) |
|
||||
HirDef::TyParam(def_id) => {
|
||||
let span = self.span_from_span(sub_span.unwrap());
|
||||
let span = self.span_from_span(sub_span);
|
||||
Some(Ref {
|
||||
kind: RefKind::Type,
|
||||
span,
|
||||
|
@ -681,7 +686,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
|||
// This is a reference to a tuple struct where the def_id points
|
||||
// to an invisible constructor function. That is not a very useful
|
||||
// def, so adjust to point to the tuple struct itself.
|
||||
let span = self.span_from_span(sub_span.unwrap());
|
||||
let span = self.span_from_span(sub_span);
|
||||
let parent_def_id = self.tcx.parent_def_id(def_id).unwrap();
|
||||
Some(Ref {
|
||||
kind: RefKind::Type,
|
||||
|
@ -690,8 +695,6 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
|||
})
|
||||
}
|
||||
HirDef::Method(decl_id) => {
|
||||
let sub_span = self.span_utils.sub_span_for_meth_name(path.span);
|
||||
filter!(self.span_utils, sub_span, path.span, None);
|
||||
let def_id = if decl_id.is_local() {
|
||||
let ti = self.tcx.associated_item(decl_id);
|
||||
self.tcx.associated_items(ti.container.id())
|
||||
|
@ -700,7 +703,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
|||
} else {
|
||||
None
|
||||
};
|
||||
let span = self.span_from_span(sub_span.unwrap());
|
||||
let span = self.span_from_span(sub_span);
|
||||
Some(Ref {
|
||||
kind: RefKind::Function,
|
||||
span,
|
||||
|
@ -708,7 +711,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
|||
})
|
||||
}
|
||||
HirDef::Fn(def_id) => {
|
||||
let span = self.span_from_span(sub_span.unwrap());
|
||||
let span = self.span_from_span(sub_span);
|
||||
Some(Ref {
|
||||
kind: RefKind::Function,
|
||||
span,
|
||||
|
@ -716,7 +719,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
|||
})
|
||||
}
|
||||
HirDef::Mod(def_id) => {
|
||||
let span = self.span_from_span(sub_span.unwrap());
|
||||
let span = self.span_from_span(sub_span);
|
||||
Some(Ref {
|
||||
kind: RefKind::Mod,
|
||||
span,
|
||||
|
|
|
@ -103,47 +103,6 @@ impl<'a> SpanUtils<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
// Return the span for the last ident before a `(` or `<` or '::<' and outside any
|
||||
// any brackets, or the last span.
|
||||
pub fn sub_span_for_meth_name(&self, span: Span) -> Option<Span> {
|
||||
let mut toks = self.retokenise_span(span);
|
||||
let mut prev = toks.real_token();
|
||||
let mut result = None;
|
||||
let mut bracket_count = 0;
|
||||
let mut prev_span = None;
|
||||
while prev.tok != token::Eof {
|
||||
prev_span = None;
|
||||
let mut next = toks.real_token();
|
||||
|
||||
if (next.tok == token::OpenDelim(token::Paren) || next.tok == token::Lt) &&
|
||||
bracket_count == 0 && prev.tok.is_ident() {
|
||||
result = Some(prev.sp);
|
||||
}
|
||||
|
||||
if bracket_count == 0 && next.tok == token::ModSep {
|
||||
let old = prev;
|
||||
prev = next;
|
||||
next = toks.real_token();
|
||||
if next.tok == token::Lt && old.tok.is_ident() {
|
||||
result = Some(old.sp);
|
||||
}
|
||||
}
|
||||
|
||||
bracket_count += match prev.tok {
|
||||
token::OpenDelim(token::Paren) | token::Lt => 1,
|
||||
token::CloseDelim(token::Paren) | token::Gt => -1,
|
||||
token::BinOp(token::Shr) => -2,
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
if prev.tok.is_ident() && bracket_count == 0 {
|
||||
prev_span = Some(prev.sp);
|
||||
}
|
||||
prev = next;
|
||||
}
|
||||
result.or(prev_span)
|
||||
}
|
||||
|
||||
// Return the span for the last ident before a `<` and outside any
|
||||
// angle brackets, or the last span.
|
||||
pub fn sub_span_for_type_name(&self, span: Span) -> Option<Span> {
|
||||
|
@ -330,7 +289,7 @@ impl<'a> SpanUtils<'a> {
|
|||
}
|
||||
|
||||
macro_rules! filter {
|
||||
($util: expr, $span: ident, $parent: expr, None) => {
|
||||
($util: expr, $span: expr, $parent: expr, None) => {
|
||||
if $util.filter_generated($span, $parent) {
|
||||
return None;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue