diff --git a/compiler/rustc_save_analysis/src/sig.rs b/compiler/rustc_save_analysis/src/sig.rs
new file mode 100644
index 0000000..747e198
--- /dev/null
+++ b/compiler/rustc_save_analysis/src/sig.rs
@@ -0,0 +1,930 @@
+// A signature is a string representation of an item's type signature, excluding
+// any body. It also includes ids for any defs or refs in the signature. For
+// example:
+//
+// ```
+// fn foo(x: String) {
+//     println!("{}", x);
+// }
+// ```
+// The signature string is something like "fn foo(x: String) {}" and the signature
+// will have defs for `foo` and `x` and a ref for `String`.
+//
+// All signature text should parse in the correct context (i.e., in a module or
+// impl, etc.). Clients may want to trim trailing `{}` or `;`. The text of a
+// signature is not guaranteed to be stable (it may improve or change as the
+// syntax changes, or whitespace or punctuation may change). It is also likely
+// not to be pretty - no attempt is made to prettify the text. It is recommended
+// that clients run the text through Rustfmt.
+//
+// This module generates Signatures for items by walking the AST and looking up
+// references.
+//
+// Signatures do not include visibility info. I'm not sure if this is a feature
+// or an ommission (FIXME).
+//
+// FIXME where clauses need implementing, defs/refs in generics are mostly missing.
+
+use crate::{id_from_def_id, id_from_hir_id, SaveContext};
+
+use rls_data::{SigElement, Signature};
+
+use rustc_ast::Mutability;
+use rustc_hir as hir;
+use rustc_hir::def::{DefKind, Res};
+use rustc_hir_pretty::id_to_string;
+use rustc_hir_pretty::{bounds_to_string, path_segment_to_string, path_to_string, ty_to_string};
+use rustc_span::symbol::{Ident, Symbol};
+
+pub fn item_signature(item: &hir::Item<'_>, scx: &SaveContext<'_>) -> Option<Signature> {
+    if !scx.config.signatures {
+        return None;
+    }
+    item.make(0, None, scx).ok()
+}
+
+pub fn foreign_item_signature(
+    item: &hir::ForeignItem<'_>,
+    scx: &SaveContext<'_>,
+) -> Option<Signature> {
+    if !scx.config.signatures {
+        return None;
+    }
+    item.make(0, None, scx).ok()
+}
+
+/// Signature for a struct or tuple field declaration.
+/// Does not include a trailing comma.
+pub fn field_signature(field: &hir::StructField<'_>, scx: &SaveContext<'_>) -> Option<Signature> {
+    if !scx.config.signatures {
+        return None;
+    }
+    field.make(0, None, scx).ok()
+}
+
+/// Does not include a trailing comma.
+pub fn variant_signature(variant: &hir::Variant<'_>, scx: &SaveContext<'_>) -> Option<Signature> {
+    if !scx.config.signatures {
+        return None;
+    }
+    variant.make(0, None, scx).ok()
+}
+
+pub fn method_signature(
+    id: hir::HirId,
+    ident: Ident,
+    generics: &hir::Generics<'_>,
+    m: &hir::FnSig<'_>,
+    scx: &SaveContext<'_>,
+) -> Option<Signature> {
+    if !scx.config.signatures {
+        return None;
+    }
+    make_method_signature(id, ident, generics, m, scx).ok()
+}
+
+pub fn assoc_const_signature(
+    id: hir::HirId,
+    ident: Symbol,
+    ty: &hir::Ty<'_>,
+    default: Option<&hir::Expr<'_>>,
+    scx: &SaveContext<'_>,
+) -> Option<Signature> {
+    if !scx.config.signatures {
+        return None;
+    }
+    make_assoc_const_signature(id, ident, ty, default, scx).ok()
+}
+
+pub fn assoc_type_signature(
+    id: hir::HirId,
+    ident: Ident,
+    bounds: Option<hir::GenericBounds<'_>>,
+    default: Option<&hir::Ty<'_>>,
+    scx: &SaveContext<'_>,
+) -> Option<Signature> {
+    if !scx.config.signatures {
+        return None;
+    }
+    make_assoc_type_signature(id, ident, bounds, default, scx).ok()
+}
+
+type Result = std::result::Result<Signature, &'static str>;
+
+trait Sig {
+    fn make(&self, offset: usize, id: Option<hir::HirId>, scx: &SaveContext<'_>) -> Result;
+}
+
+fn extend_sig(
+    mut sig: Signature,
+    text: String,
+    defs: Vec<SigElement>,
+    refs: Vec<SigElement>,
+) -> Signature {
+    sig.text = text;
+    sig.defs.extend(defs.into_iter());
+    sig.refs.extend(refs.into_iter());
+    sig
+}
+
+fn replace_text(mut sig: Signature, text: String) -> Signature {
+    sig.text = text;
+    sig
+}
+
+fn merge_sigs(text: String, sigs: Vec<Signature>) -> Signature {
+    let mut result = Signature { text, defs: vec![], refs: vec![] };
+
+    let (defs, refs): (Vec<_>, Vec<_>) = sigs.into_iter().map(|s| (s.defs, s.refs)).unzip();
+
+    result.defs.extend(defs.into_iter().flat_map(|ds| ds.into_iter()));
+    result.refs.extend(refs.into_iter().flat_map(|rs| rs.into_iter()));
+
+    result
+}
+
+fn text_sig(text: String) -> Signature {
+    Signature { text, defs: vec![], refs: vec![] }
+}
+
+impl<'hir> Sig for hir::Ty<'hir> {
+    fn make(&self, offset: usize, _parent_id: Option<hir::HirId>, scx: &SaveContext<'_>) -> Result {
+        let id = Some(self.hir_id);
+        match self.kind {
+            hir::TyKind::Slice(ref ty) => {
+                let nested = ty.make(offset + 1, id, scx)?;
+                let text = format!("[{}]", nested.text);
+                Ok(replace_text(nested, text))
+            }
+            hir::TyKind::Ptr(ref mt) => {
+                let prefix = match mt.mutbl {
+                    hir::Mutability::Mut => "*mut ",
+                    hir::Mutability::Not => "*const ",
+                };
+                let nested = mt.ty.make(offset + prefix.len(), id, scx)?;
+                let text = format!("{}{}", prefix, nested.text);
+                Ok(replace_text(nested, text))
+            }
+            hir::TyKind::Rptr(ref lifetime, ref mt) => {
+                let mut prefix = "&".to_owned();
+                prefix.push_str(&lifetime.name.ident().to_string());
+                prefix.push(' ');
+                if let hir::Mutability::Mut = mt.mutbl {
+                    prefix.push_str("mut ");
+                };
+
+                let nested = mt.ty.make(offset + prefix.len(), id, scx)?;
+                let text = format!("{}{}", prefix, nested.text);
+                Ok(replace_text(nested, text))
+            }
+            hir::TyKind::Never => Ok(text_sig("!".to_owned())),
+            hir::TyKind::Tup(ts) => {
+                let mut text = "(".to_owned();
+                let mut defs = vec![];
+                let mut refs = vec![];
+                for t in ts {
+                    let nested = t.make(offset + text.len(), id, scx)?;
+                    text.push_str(&nested.text);
+                    text.push(',');
+                    defs.extend(nested.defs.into_iter());
+                    refs.extend(nested.refs.into_iter());
+                }
+                text.push(')');
+                Ok(Signature { text, defs, refs })
+            }
+            hir::TyKind::BareFn(ref f) => {
+                let mut text = String::new();
+                if !f.generic_params.is_empty() {
+                    // FIXME defs, bounds on lifetimes
+                    text.push_str("for<");
+                    text.push_str(
+                        &f.generic_params
+                            .iter()
+                            .filter_map(|param| match param.kind {
+                                hir::GenericParamKind::Lifetime { .. } => {
+                                    Some(param.name.ident().to_string())
+                                }
+                                _ => None,
+                            })
+                            .collect::<Vec<_>>()
+                            .join(", "),
+                    );
+                    text.push('>');
+                }
+
+                if let hir::Unsafety::Unsafe = f.unsafety {
+                    text.push_str("unsafe ");
+                }
+                text.push_str("fn(");
+
+                let mut defs = vec![];
+                let mut refs = vec![];
+                for i in f.decl.inputs {
+                    let nested = i.make(offset + text.len(), Some(i.hir_id), scx)?;
+                    text.push_str(&nested.text);
+                    text.push(',');
+                    defs.extend(nested.defs.into_iter());
+                    refs.extend(nested.refs.into_iter());
+                }
+                text.push(')');
+                if let hir::FnRetTy::Return(ref t) = f.decl.output {
+                    text.push_str(" -> ");
+                    let nested = t.make(offset + text.len(), None, scx)?;
+                    text.push_str(&nested.text);
+                    text.push(',');
+                    defs.extend(nested.defs.into_iter());
+                    refs.extend(nested.refs.into_iter());
+                }
+
+                Ok(Signature { text, defs, refs })
+            }
+            hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) => path.make(offset, id, scx),
+            hir::TyKind::Path(hir::QPath::Resolved(Some(ref qself), ref path)) => {
+                let nested_ty = qself.make(offset + 1, id, scx)?;
+                let prefix = format!(
+                    "<{} as {}>::",
+                    nested_ty.text,
+                    path_segment_to_string(&path.segments[0])
+                );
+
+                let name = path_segment_to_string(path.segments.last().ok_or("Bad path")?);
+                let res = scx.get_path_res(id.ok_or("Missing id for Path")?);
+                let id = id_from_def_id(res.def_id());
+                if path.segments.len() == 2 {
+                    let start = offset + prefix.len();
+                    let end = start + name.len();
+
+                    Ok(Signature {
+                        text: prefix + &name,
+                        defs: vec![],
+                        refs: vec![SigElement { id, start, end }],
+                    })
+                } else {
+                    let start = offset + prefix.len() + 5;
+                    let end = start + name.len();
+                    // FIXME should put the proper path in there, not elipses.
+                    Ok(Signature {
+                        text: prefix + "...::" + &name,
+                        defs: vec![],
+                        refs: vec![SigElement { id, start, end }],
+                    })
+                }
+            }
+            hir::TyKind::Path(hir::QPath::TypeRelative(ty, segment)) => {
+                let nested_ty = ty.make(offset + 1, id, scx)?;
+                let prefix = format!("<{}>::", nested_ty.text,);
+
+                let name = path_segment_to_string(segment);
+                let res = scx.get_path_res(id.ok_or("Missing id for Path")?);
+                let id = id_from_def_id(res.def_id());
+
+                let start = offset + prefix.len();
+                let end = start + name.len();
+                Ok(Signature {
+                    text: prefix + &name,
+                    defs: vec![],
+                    refs: vec![SigElement { id, start, end }],
+                })
+            }
+            hir::TyKind::Path(hir::QPath::LangItem(lang_item, _)) => {
+                Ok(text_sig(format!("#[lang = \"{}\"]", lang_item.name())))
+            }
+            hir::TyKind::TraitObject(bounds, ..) => {
+                // FIXME recurse into bounds
+                let bounds: Vec<hir::GenericBound<'_>> = bounds
+                    .iter()
+                    .map(|hir::PolyTraitRef { bound_generic_params, trait_ref, span }| {
+                        hir::GenericBound::Trait(
+                            hir::PolyTraitRef {
+                                bound_generic_params,
+                                trait_ref: hir::TraitRef {
+                                    path: trait_ref.path,
+                                    hir_ref_id: trait_ref.hir_ref_id,
+                                },
+                                span: *span,
+                            },
+                            hir::TraitBoundModifier::None,
+                        )
+                    })
+                    .collect();
+                let nested = bounds_to_string(&bounds);
+                Ok(text_sig(nested))
+            }
+            hir::TyKind::Array(ref ty, ref anon_const) => {
+                let nested_ty = ty.make(offset + 1, id, scx)?;
+                let expr = id_to_string(&scx.tcx.hir(), anon_const.body.hir_id).replace('\n', " ");
+                let text = format!("[{}; {}]", nested_ty.text, expr);
+                Ok(replace_text(nested_ty, text))
+            }
+            hir::TyKind::OpaqueDef(item_id, _) => {
+                let item = scx.tcx.hir().item(item_id.id);
+                item.make(offset, Some(item_id.id), scx)
+            }
+            hir::TyKind::Typeof(_) | hir::TyKind::Infer | hir::TyKind::Err => Err("Ty"),
+        }
+    }
+}
+
+impl<'hir> Sig for hir::Item<'hir> {
+    fn make(&self, offset: usize, _parent_id: Option<hir::HirId>, scx: &SaveContext<'_>) -> Result {
+        let id = Some(self.hir_id);
+
+        match self.kind {
+            hir::ItemKind::Static(ref ty, m, ref body) => {
+                let mut text = "static ".to_owned();
+                if m == hir::Mutability::Mut {
+                    text.push_str("mut ");
+                }
+                let name = self.ident.to_string();
+                let defs = vec![SigElement {
+                    id: id_from_hir_id(self.hir_id, scx),
+                    start: offset + text.len(),
+                    end: offset + text.len() + name.len(),
+                }];
+                text.push_str(&name);
+                text.push_str(": ");
+
+                let ty = ty.make(offset + text.len(), id, scx)?;
+                text.push_str(&ty.text);
+
+                text.push_str(" = ");
+                let expr = id_to_string(&scx.tcx.hir(), body.hir_id).replace('\n', " ");
+                text.push_str(&expr);
+
+                text.push(';');
+
+                Ok(extend_sig(ty, text, defs, vec![]))
+            }
+            hir::ItemKind::Const(ref ty, ref body) => {
+                let mut text = "const ".to_owned();
+                let name = self.ident.to_string();
+                let defs = vec![SigElement {
+                    id: id_from_hir_id(self.hir_id, scx),
+                    start: offset + text.len(),
+                    end: offset + text.len() + name.len(),
+                }];
+                text.push_str(&name);
+                text.push_str(": ");
+
+                let ty = ty.make(offset + text.len(), id, scx)?;
+                text.push_str(&ty.text);
+
+                text.push_str(" = ");
+                let expr = id_to_string(&scx.tcx.hir(), body.hir_id).replace('\n', " ");
+                text.push_str(&expr);
+
+                text.push(';');
+
+                Ok(extend_sig(ty, text, defs, vec![]))
+            }
+            hir::ItemKind::Fn(hir::FnSig { ref decl, header, span: _ }, ref generics, _) => {
+                let mut text = String::new();
+                if let hir::Constness::Const = header.constness {
+                    text.push_str("const ");
+                }
+                if hir::IsAsync::Async == header.asyncness {
+                    text.push_str("async ");
+                }
+                if let hir::Unsafety::Unsafe = header.unsafety {
+                    text.push_str("unsafe ");
+                }
+                text.push_str("fn ");
+
+                let mut sig =
+                    name_and_generics(text, offset, generics, self.hir_id, self.ident, scx)?;
+
+                sig.text.push('(');
+                for i in decl.inputs {
+                    // FIXME should descend into patterns to add defs.
+                    sig.text.push_str(": ");
+                    let nested = i.make(offset + sig.text.len(), Some(i.hir_id), scx)?;
+                    sig.text.push_str(&nested.text);
+                    sig.text.push(',');
+                    sig.defs.extend(nested.defs.into_iter());
+                    sig.refs.extend(nested.refs.into_iter());
+                }
+                sig.text.push(')');
+
+                if let hir::FnRetTy::Return(ref t) = decl.output {
+                    sig.text.push_str(" -> ");
+                    let nested = t.make(offset + sig.text.len(), None, scx)?;
+                    sig.text.push_str(&nested.text);
+                    sig.defs.extend(nested.defs.into_iter());
+                    sig.refs.extend(nested.refs.into_iter());
+                }
+                sig.text.push_str(" {}");
+
+                Ok(sig)
+            }
+            hir::ItemKind::Mod(ref _mod) => {
+                let mut text = "mod ".to_owned();
+                let name = self.ident.to_string();
+                let defs = vec![SigElement {
+                    id: id_from_hir_id(self.hir_id, scx),
+                    start: offset + text.len(),
+                    end: offset + text.len() + name.len(),
+                }];
+                text.push_str(&name);
+                // Could be either `mod foo;` or `mod foo { ... }`, but we'll just pick one.
+                text.push(';');
+
+                Ok(Signature { text, defs, refs: vec![] })
+            }
+            hir::ItemKind::TyAlias(ref ty, ref generics) => {
+                let text = "type ".to_owned();
+                let mut sig =
+                    name_and_generics(text, offset, generics, self.hir_id, self.ident, scx)?;
+
+                sig.text.push_str(" = ");
+                let ty = ty.make(offset + sig.text.len(), id, scx)?;
+                sig.text.push_str(&ty.text);
+                sig.text.push(';');
+
+                Ok(merge_sigs(sig.text.clone(), vec![sig, ty]))
+            }
+            hir::ItemKind::Enum(_, ref generics) => {
+                let text = "enum ".to_owned();
+                let mut sig =
+                    name_and_generics(text, offset, generics, self.hir_id, self.ident, scx)?;
+                sig.text.push_str(" {}");
+                Ok(sig)
+            }
+            hir::ItemKind::Struct(_, ref generics) => {
+                let text = "struct ".to_owned();
+                let mut sig =
+                    name_and_generics(text, offset, generics, self.hir_id, self.ident, scx)?;
+                sig.text.push_str(" {}");
+                Ok(sig)
+            }
+            hir::ItemKind::Union(_, ref generics) => {
+                let text = "union ".to_owned();
+                let mut sig =
+                    name_and_generics(text, offset, generics, self.hir_id, self.ident, scx)?;
+                sig.text.push_str(" {}");
+                Ok(sig)
+            }
+            hir::ItemKind::Trait(is_auto, unsafety, ref generics, bounds, _) => {
+                let mut text = String::new();
+
+                if is_auto == hir::IsAuto::Yes {
+                    text.push_str("auto ");
+                }
+
+                if let hir::Unsafety::Unsafe = unsafety {
+                    text.push_str("unsafe ");
+                }
+                text.push_str("trait ");
+                let mut sig =
+                    name_and_generics(text, offset, generics, self.hir_id, self.ident, scx)?;
+
+                if !bounds.is_empty() {
+                    sig.text.push_str(": ");
+                    sig.text.push_str(&bounds_to_string(bounds));
+                }
+                // FIXME where clause
+                sig.text.push_str(" {}");
+
+                Ok(sig)
+            }
+            hir::ItemKind::TraitAlias(ref generics, bounds) => {
+                let mut text = String::new();
+                text.push_str("trait ");
+                let mut sig =
+                    name_and_generics(text, offset, generics, self.hir_id, self.ident, scx)?;
+
+                if !bounds.is_empty() {
+                    sig.text.push_str(" = ");
+                    sig.text.push_str(&bounds_to_string(bounds));
+                }
+                // FIXME where clause
+                sig.text.push(';');
+
+                Ok(sig)
+            }
+            hir::ItemKind::Impl {
+                unsafety,
+                polarity,
+                defaultness,
+                defaultness_span: _,
+                constness,
+                ref generics,
+                ref of_trait,
+                ref self_ty,
+                items: _,
+            } => {
+                let mut text = String::new();
+                if let hir::Defaultness::Default { .. } = defaultness {
+                    text.push_str("default ");
+                }
+                if let hir::Unsafety::Unsafe = unsafety {
+                    text.push_str("unsafe ");
+                }
+                text.push_str("impl");
+                if let hir::Constness::Const = constness {
+                    text.push_str(" const");
+                }
+
+                let generics_sig = generics.make(offset + text.len(), id, scx)?;
+                text.push_str(&generics_sig.text);
+
+                text.push(' ');
+
+                let trait_sig = if let Some(ref t) = *of_trait {
+                    if let hir::ImplPolarity::Negative(_) = polarity {
+                        text.push('!');
+                    }
+                    let trait_sig = t.path.make(offset + text.len(), id, scx)?;
+                    text.push_str(&trait_sig.text);
+                    text.push_str(" for ");
+                    trait_sig
+                } else {
+                    text_sig(String::new())
+                };
+
+                let ty_sig = self_ty.make(offset + text.len(), id, scx)?;
+                text.push_str(&ty_sig.text);
+
+                text.push_str(" {}");
+
+                Ok(merge_sigs(text, vec![generics_sig, trait_sig, ty_sig]))
+
+                // FIXME where clause
+            }
+            hir::ItemKind::ForeignMod(_) => Err("extern mod"),
+            hir::ItemKind::GlobalAsm(_) => Err("glboal asm"),
+            hir::ItemKind::ExternCrate(_) => Err("extern crate"),
+            hir::ItemKind::OpaqueTy(..) => Err("opaque type"),
+            // FIXME should implement this (e.g., pub use).
+            hir::ItemKind::Use(..) => Err("import"),
+        }
+    }
+}
+
+impl<'hir> Sig for hir::Path<'hir> {
+    fn make(&self, offset: usize, id: Option<hir::HirId>, scx: &SaveContext<'_>) -> Result {
+        let res = scx.get_path_res(id.ok_or("Missing id for Path")?);
+
+        let (name, start, end) = match res {
+            Res::PrimTy(..) | Res::SelfTy(..) | Res::Err => {
+                return Ok(Signature { text: path_to_string(self), defs: vec![], refs: vec![] });
+            }
+            Res::Def(DefKind::AssocConst | DefKind::Variant | DefKind::Ctor(..), _) => {
+                let len = self.segments.len();
+                if len < 2 {
+                    return Err("Bad path");
+                }
+                // FIXME: really we should descend into the generics here and add SigElements for
+                // them.
+                // FIXME: would be nice to have a def for the first path segment.
+                let seg1 = path_segment_to_string(&self.segments[len - 2]);
+                let seg2 = path_segment_to_string(&self.segments[len - 1]);
+                let start = offset + seg1.len() + 2;
+                (format!("{}::{}", seg1, seg2), start, start + seg2.len())
+            }
+            _ => {
+                let name = path_segment_to_string(self.segments.last().ok_or("Bad path")?);
+                let end = offset + name.len();
+                (name, offset, end)
+            }
+        };
+
+        let id = id_from_def_id(res.def_id());
+        Ok(Signature { text: name, defs: vec![], refs: vec![SigElement { id, start, end }] })
+    }
+}
+
+// This does not cover the where clause, which must be processed separately.
+impl<'hir> Sig for hir::Generics<'hir> {
+    fn make(&self, offset: usize, _parent_id: Option<hir::HirId>, scx: &SaveContext<'_>) -> Result {
+        if self.params.is_empty() {
+            return Ok(text_sig(String::new()));
+        }
+
+        let mut text = "<".to_owned();
+
+        let mut defs = Vec::with_capacity(self.params.len());
+        for param in self.params {
+            let mut param_text = String::new();
+            if let hir::GenericParamKind::Const { .. } = param.kind {
+                param_text.push_str("const ");
+            }
+            param_text.push_str(&param.name.ident().as_str());
+            defs.push(SigElement {
+                id: id_from_hir_id(param.hir_id, scx),
+                start: offset + text.len(),
+                end: offset + text.len() + param_text.as_str().len(),
+            });
+            if let hir::GenericParamKind::Const { ref ty } = param.kind {
+                param_text.push_str(": ");
+                param_text.push_str(&ty_to_string(&ty));
+            }
+            if !param.bounds.is_empty() {
+                param_text.push_str(": ");
+                match param.kind {
+                    hir::GenericParamKind::Lifetime { .. } => {
+                        let bounds = param
+                            .bounds
+                            .iter()
+                            .map(|bound| match bound {
+                                hir::GenericBound::Outlives(lt) => lt.name.ident().to_string(),
+                                _ => panic!(),
+                            })
+                            .collect::<Vec<_>>()
+                            .join(" + ");
+                        param_text.push_str(&bounds);
+                        // FIXME add lifetime bounds refs.
+                    }
+                    hir::GenericParamKind::Type { .. } => {
+                        param_text.push_str(&bounds_to_string(param.bounds));
+                        // FIXME descend properly into bounds.
+                    }
+                    hir::GenericParamKind::Const { .. } => {
+                        // Const generics cannot contain bounds.
+                    }
+                }
+            }
+            text.push_str(&param_text);
+            text.push(',');
+        }
+
+        text.push('>');
+        Ok(Signature { text, defs, refs: vec![] })
+    }
+}
+
+impl<'hir> Sig for hir::StructField<'hir> {
+    fn make(&self, offset: usize, _parent_id: Option<hir::HirId>, scx: &SaveContext<'_>) -> Result {
+        let mut text = String::new();
+
+        text.push_str(&self.ident.to_string());
+        let defs = Some(SigElement {
+            id: id_from_hir_id(self.hir_id, scx),
+            start: offset,
+            end: offset + text.len(),
+        });
+        text.push_str(": ");
+
+        let mut ty_sig = self.ty.make(offset + text.len(), Some(self.hir_id), scx)?;
+        text.push_str(&ty_sig.text);
+        ty_sig.text = text;
+        ty_sig.defs.extend(defs.into_iter());
+        Ok(ty_sig)
+    }
+}
+
+impl<'hir> Sig for hir::Variant<'hir> {
+    fn make(&self, offset: usize, parent_id: Option<hir::HirId>, scx: &SaveContext<'_>) -> Result {
+        let mut text = self.ident.to_string();
+        match self.data {
+            hir::VariantData::Struct(fields, r) => {
+                let id = parent_id.unwrap();
+                let name_def = SigElement {
+                    id: id_from_hir_id(id, scx),
+                    start: offset,
+                    end: offset + text.len(),
+                };
+                text.push_str(" { ");
+                let mut defs = vec![name_def];
+                let mut refs = vec![];
+                if r {
+                    text.push_str("/* parse error */ ");
+                } else {
+                    for f in fields {
+                        let field_sig = f.make(offset + text.len(), Some(id), scx)?;
+                        text.push_str(&field_sig.text);
+                        text.push_str(", ");
+                        defs.extend(field_sig.defs.into_iter());
+                        refs.extend(field_sig.refs.into_iter());
+                    }
+                }
+                text.push('}');
+                Ok(Signature { text, defs, refs })
+            }
+            hir::VariantData::Tuple(fields, id) => {
+                let name_def = SigElement {
+                    id: id_from_hir_id(id, scx),
+                    start: offset,
+                    end: offset + text.len(),
+                };
+                text.push('(');
+                let mut defs = vec![name_def];
+                let mut refs = vec![];
+                for f in fields {
+                    let field_sig = f.make(offset + text.len(), Some(id), scx)?;
+                    text.push_str(&field_sig.text);
+                    text.push_str(", ");
+                    defs.extend(field_sig.defs.into_iter());
+                    refs.extend(field_sig.refs.into_iter());
+                }
+                text.push(')');
+                Ok(Signature { text, defs, refs })
+            }
+            hir::VariantData::Unit(id) => {
+                let name_def = SigElement {
+                    id: id_from_hir_id(id, scx),
+                    start: offset,
+                    end: offset + text.len(),
+                };
+                Ok(Signature { text, defs: vec![name_def], refs: vec![] })
+            }
+        }
+    }
+}
+
+impl<'hir> Sig for hir::ForeignItem<'hir> {
+    fn make(&self, offset: usize, _parent_id: Option<hir::HirId>, scx: &SaveContext<'_>) -> Result {
+        let id = Some(self.hir_id);
+        match self.kind {
+            hir::ForeignItemKind::Fn(decl, _, ref generics) => {
+                let mut text = String::new();
+                text.push_str("fn ");
+
+                let mut sig =
+                    name_and_generics(text, offset, generics, self.hir_id, self.ident, scx)?;
+
+                sig.text.push('(');
+                for i in decl.inputs {
+                    sig.text.push_str(": ");
+                    let nested = i.make(offset + sig.text.len(), Some(i.hir_id), scx)?;
+                    sig.text.push_str(&nested.text);
+                    sig.text.push(',');
+                    sig.defs.extend(nested.defs.into_iter());
+                    sig.refs.extend(nested.refs.into_iter());
+                }
+                sig.text.push(')');
+
+                if let hir::FnRetTy::Return(ref t) = decl.output {
+                    sig.text.push_str(" -> ");
+                    let nested = t.make(offset + sig.text.len(), None, scx)?;
+                    sig.text.push_str(&nested.text);
+                    sig.defs.extend(nested.defs.into_iter());
+                    sig.refs.extend(nested.refs.into_iter());
+                }
+                sig.text.push(';');
+
+                Ok(sig)
+            }
+            hir::ForeignItemKind::Static(ref ty, m) => {
+                let mut text = "static ".to_owned();
+                if m == Mutability::Mut {
+                    text.push_str("mut ");
+                }
+                let name = self.ident.to_string();
+                let defs = vec![SigElement {
+                    id: id_from_hir_id(self.hir_id, scx),
+                    start: offset + text.len(),
+                    end: offset + text.len() + name.len(),
+                }];
+                text.push_str(&name);
+                text.push_str(": ");
+
+                let ty_sig = ty.make(offset + text.len(), id, scx)?;
+                text.push(';');
+
+                Ok(extend_sig(ty_sig, text, defs, vec![]))
+            }
+            hir::ForeignItemKind::Type => {
+                let mut text = "type ".to_owned();
+                let name = self.ident.to_string();
+                let defs = vec![SigElement {
+                    id: id_from_hir_id(self.hir_id, scx),
+                    start: offset + text.len(),
+                    end: offset + text.len() + name.len(),
+                }];
+                text.push_str(&name);
+                text.push(';');
+
+                Ok(Signature { text, defs, refs: vec![] })
+            }
+        }
+    }
+}
+
+fn name_and_generics(
+    mut text: String,
+    offset: usize,
+    generics: &hir::Generics<'_>,
+    id: hir::HirId,
+    name: Ident,
+    scx: &SaveContext<'_>,
+) -> Result {
+    let name = name.to_string();
+    let def = SigElement {
+        id: id_from_hir_id(id, scx),
+        start: offset + text.len(),
+        end: offset + text.len() + name.len(),
+    };
+    text.push_str(&name);
+    let generics: Signature = generics.make(offset + text.len(), Some(id), scx)?;
+    // FIXME where clause
+    let text = format!("{}{}", text, generics.text);
+    Ok(extend_sig(generics, text, vec![def], vec![]))
+}
+
+fn make_assoc_type_signature(
+    id: hir::HirId,
+    ident: Ident,
+    bounds: Option<hir::GenericBounds<'_>>,
+    default: Option<&hir::Ty<'_>>,
+    scx: &SaveContext<'_>,
+) -> Result {
+    let mut text = "type ".to_owned();
+    let name = ident.to_string();
+    let mut defs = vec![SigElement {
+        id: id_from_hir_id(id, scx),
+        start: text.len(),
+        end: text.len() + name.len(),
+    }];
+    let mut refs = vec![];
+    text.push_str(&name);
+    if let Some(bounds) = bounds {
+        text.push_str(": ");
+        // FIXME should descend into bounds
+        text.push_str(&bounds_to_string(bounds));
+    }
+    if let Some(default) = default {
+        text.push_str(" = ");
+        let ty_sig = default.make(text.len(), Some(id), scx)?;
+        text.push_str(&ty_sig.text);
+        defs.extend(ty_sig.defs.into_iter());
+        refs.extend(ty_sig.refs.into_iter());
+    }
+    text.push(';');
+    Ok(Signature { text, defs, refs })
+}
+
+fn make_assoc_const_signature(
+    id: hir::HirId,
+    ident: Symbol,
+    ty: &hir::Ty<'_>,
+    default: Option<&hir::Expr<'_>>,
+    scx: &SaveContext<'_>,
+) -> Result {
+    let mut text = "const ".to_owned();
+    let name = ident.to_string();
+    let mut defs = vec![SigElement {
+        id: id_from_hir_id(id, scx),
+        start: text.len(),
+        end: text.len() + name.len(),
+    }];
+    let mut refs = vec![];
+    text.push_str(&name);
+    text.push_str(": ");
+
+    let ty_sig = ty.make(text.len(), Some(id), scx)?;
+    text.push_str(&ty_sig.text);
+    defs.extend(ty_sig.defs.into_iter());
+    refs.extend(ty_sig.refs.into_iter());
+
+    if let Some(default) = default {
+        text.push_str(" = ");
+        text.push_str(&id_to_string(&scx.tcx.hir(), default.hir_id));
+    }
+    text.push(';');
+    Ok(Signature { text, defs, refs })
+}
+
+fn make_method_signature(
+    id: hir::HirId,
+    ident: Ident,
+    generics: &hir::Generics<'_>,
+    m: &hir::FnSig<'_>,
+    scx: &SaveContext<'_>,
+) -> Result {
+    // FIXME code dup with function signature
+    let mut text = String::new();
+    if let hir::Constness::Const = m.header.constness {
+        text.push_str("const ");
+    }
+    if hir::IsAsync::Async == m.header.asyncness {
+        text.push_str("async ");
+    }
+    if let hir::Unsafety::Unsafe = m.header.unsafety {
+        text.push_str("unsafe ");
+    }
+    text.push_str("fn ");
+
+    let mut sig = name_and_generics(text, 0, generics, id, ident, scx)?;
+
+    sig.text.push('(');
+    for i in m.decl.inputs {
+        sig.text.push_str(": ");
+        let nested = i.make(sig.text.len(), Some(i.hir_id), scx)?;
+        sig.text.push_str(&nested.text);
+        sig.text.push(',');
+        sig.defs.extend(nested.defs.into_iter());
+        sig.refs.extend(nested.refs.into_iter());
+    }
+    sig.text.push(')');
+
+    if let hir::FnRetTy::Return(ref t) = m.decl.output {
+        sig.text.push_str(" -> ");
+        let nested = t.make(sig.text.len(), None, scx)?;
+        sig.text.push_str(&nested.text);
+        sig.defs.extend(nested.defs.into_iter());
+        sig.refs.extend(nested.refs.into_iter());
+    }
+    sig.text.push_str(" {}");
+
+    Ok(sig)
+}
