Auto merge of #33523 - Manishearth:rollup, r=Manishearth
Rollup of 10 pull requests - Successful merges: #33129, #33224, #33370, #33383, #33431, #33474, #33480, #33496, #33509, #33514 - Failed merges:
This commit is contained in:
commit
e0fd34bba0
32 changed files with 1104 additions and 923 deletions
|
@ -1573,8 +1573,9 @@ detail on Getopts, but there is [some good documentation][15]
|
|||
describing it. The short story is that Getopts generates an argument
|
||||
parser and a help message from a vector of options (The fact that it
|
||||
is a vector is hidden behind a struct and a set of methods). Once the
|
||||
parsing is done, we can decode the program arguments into a Rust
|
||||
struct. From there, we can get information about the flags, for
|
||||
parsing is done, the parser returns a struct that records matches
|
||||
for defined options, and remaining "free" arguments.
|
||||
From there, we can get information about the flags, for
|
||||
instance, whether they were passed in, and what arguments they
|
||||
had. Here's our program with the appropriate `extern crate`
|
||||
statements, and the basic argument setup for Getopts:
|
||||
|
@ -1605,8 +1606,8 @@ fn main() {
|
|||
print_usage(&program, opts);
|
||||
return;
|
||||
}
|
||||
let data_path = &args[1];
|
||||
let city = &args[2];
|
||||
let data_path = &matches.free[0];
|
||||
let city: &str = &matches.free[1];
|
||||
|
||||
// Do stuff with information
|
||||
}
|
||||
|
@ -1680,8 +1681,8 @@ fn main() {
|
|||
return;
|
||||
}
|
||||
|
||||
let data_path = &args[1];
|
||||
let city: &str = &args[2];
|
||||
let data_path = &matches.free[0];
|
||||
let city: &str = &matches.free[1];
|
||||
|
||||
let file = File::open(data_path).unwrap();
|
||||
let mut rdr = csv::Reader::from_reader(file);
|
||||
|
@ -1792,13 +1793,15 @@ fn main() {
|
|||
Ok(m) => { m }
|
||||
Err(e) => { panic!(e.to_string()) }
|
||||
};
|
||||
|
||||
if matches.opt_present("h") {
|
||||
print_usage(&program, opts);
|
||||
return;
|
||||
}
|
||||
|
||||
let data_path = &args[1];
|
||||
let city = &args[2];
|
||||
let data_path = &matches.free[0];
|
||||
let city: &str = &matches.free[1];
|
||||
|
||||
for pop in search(data_path, city) {
|
||||
println!("{}, {}: {:?}", pop.city, pop.country, pop.count);
|
||||
}
|
||||
|
@ -1876,14 +1879,14 @@ when calling `search`:
|
|||
|
||||
```rust,ignore
|
||||
...
|
||||
match search(&data_file, &city) {
|
||||
Ok(pops) => {
|
||||
for pop in pops {
|
||||
println!("{}, {}: {:?}", pop.city, pop.country, pop.count);
|
||||
match search(data_path, city) {
|
||||
Ok(pops) => {
|
||||
for pop in pops {
|
||||
println!("{}, {}: {:?}", pop.city, pop.country, pop.count);
|
||||
}
|
||||
}
|
||||
Err(err) => println!("{}", err)
|
||||
}
|
||||
Err(err) => println!("{}", err)
|
||||
}
|
||||
...
|
||||
```
|
||||
|
||||
|
@ -1914,43 +1917,37 @@ fn print_usage(program: &str, opts: Options) {
|
|||
println!("{}", opts.usage(&format!("Usage: {} [options] <city>", program)));
|
||||
}
|
||||
```
|
||||
The next part is going to be only a little harder:
|
||||
Of course we need to adapt the argument handling code:
|
||||
|
||||
```rust,ignore
|
||||
...
|
||||
let mut opts = Options::new();
|
||||
opts.optopt("f", "file", "Choose an input file, instead of using STDIN.", "NAME");
|
||||
opts.optflag("h", "help", "Show this usage message.");
|
||||
...
|
||||
let file = matches.opt_str("f");
|
||||
let data_file = &file.as_ref().map(Path::new);
|
||||
let mut opts = Options::new();
|
||||
opts.optopt("f", "file", "Choose an input file, instead of using STDIN.", "NAME");
|
||||
opts.optflag("h", "help", "Show this usage message.");
|
||||
...
|
||||
let data_path = matches.opt_str("f");
|
||||
|
||||
let city = if !matches.free.is_empty() {
|
||||
&matches.free[0]
|
||||
} else {
|
||||
print_usage(&program, opts);
|
||||
return;
|
||||
};
|
||||
let city = if !matches.free.is_empty() {
|
||||
&matches.free[0]
|
||||
} else {
|
||||
print_usage(&program, opts);
|
||||
return;
|
||||
};
|
||||
|
||||
match search(data_file, city) {
|
||||
Ok(pops) => {
|
||||
for pop in pops {
|
||||
println!("{}, {}: {:?}", pop.city, pop.country, pop.count);
|
||||
match search(&data_path, city) {
|
||||
Ok(pops) => {
|
||||
for pop in pops {
|
||||
println!("{}, {}: {:?}", pop.city, pop.country, pop.count);
|
||||
}
|
||||
}
|
||||
Err(err) => println!("{}", err)
|
||||
}
|
||||
Err(err) => println!("{}", err)
|
||||
}
|
||||
...
|
||||
```
|
||||
|
||||
In this piece of code, we take `file` (which has the type
|
||||
`Option<String>`), and convert it to a type that `search` can use, in
|
||||
this case, `&Option<AsRef<Path>>`. To do this, we take a reference of
|
||||
file, and map `Path::new` onto it. In this case, `as_ref()` converts
|
||||
the `Option<String>` into an `Option<&str>`, and from there, we can
|
||||
execute `Path::new` to the content of the optional, and return the
|
||||
optional of the new value. Once we have that, it is a simple matter of
|
||||
getting the `city` argument and executing `search`.
|
||||
We've made the user experience a bit nicer by showing the usage message,
|
||||
instead of a panic from an out-of-bounds index, when `city`, the
|
||||
remaining free argument, is not present.
|
||||
|
||||
Modifying `search` is slightly trickier. The `csv` crate can build a
|
||||
parser out of
|
||||
|
@ -2000,6 +1997,8 @@ enum CliError {
|
|||
And now for impls on `Display` and `Error`:
|
||||
|
||||
```rust,ignore
|
||||
use std::fmt;
|
||||
|
||||
impl fmt::Display for CliError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
|
@ -2020,13 +2019,13 @@ impl Error for CliError {
|
|||
}
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&error::Error> {
|
||||
match *self {
|
||||
fn cause(&self) -> Option<&Error> {
|
||||
match *self {
|
||||
CliError::Io(ref err) => Some(err),
|
||||
CliError::Parse(ref err) => Some(err),
|
||||
// Our custom error doesn't have an underlying cause, but we could
|
||||
// modify it so that it does.
|
||||
CliError::NotFound() => None,
|
||||
CliError::Csv(ref err) => Some(err),
|
||||
// Our custom error doesn't have an underlying cause,
|
||||
// but we could modify it so that it does.
|
||||
CliError::NotFound => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2122,10 +2121,10 @@ string and add a flag to the Option variable. Once we've done that, Getopts does
|
|||
|
||||
```rust,ignore
|
||||
...
|
||||
let mut opts = Options::new();
|
||||
opts.optopt("f", "file", "Choose an input file, instead of using STDIN.", "NAME");
|
||||
opts.optflag("h", "help", "Show this usage message.");
|
||||
opts.optflag("q", "quiet", "Silences errors and warnings.");
|
||||
let mut opts = Options::new();
|
||||
opts.optopt("f", "file", "Choose an input file, instead of using STDIN.", "NAME");
|
||||
opts.optflag("h", "help", "Show this usage message.");
|
||||
opts.optflag("q", "quiet", "Silences errors and warnings.");
|
||||
...
|
||||
```
|
||||
|
||||
|
@ -2133,13 +2132,16 @@ Now we only need to implement our “quiet” functionality. This requires us to
|
|||
tweak the case analysis in `main`:
|
||||
|
||||
```rust,ignore
|
||||
match search(&args.arg_data_path, &args.arg_city) {
|
||||
Err(CliError::NotFound) if args.flag_quiet => process::exit(1),
|
||||
Err(err) => panic!("{}", err),
|
||||
Ok(pops) => for pop in pops {
|
||||
println!("{}, {}: {:?}", pop.city, pop.country, pop.count);
|
||||
use std::process;
|
||||
...
|
||||
match search(&data_path, city) {
|
||||
Err(CliError::NotFound) if matches.opt_present("q") => process::exit(1),
|
||||
Err(err) => panic!("{}", err),
|
||||
Ok(pops) => for pop in pops {
|
||||
println!("{}, {}: {:?}", pop.city, pop.country, pop.count);
|
||||
}
|
||||
}
|
||||
}
|
||||
...
|
||||
```
|
||||
|
||||
Certainly, we don't want to be quiet if there was an IO error or if the data
|
||||
|
|
|
@ -52,7 +52,7 @@ fn test_from_utf8() {
|
|||
String::from("ศไทย中华Việt Nam"));
|
||||
|
||||
let xs = b"hello\xFF".to_vec();
|
||||
let err = String::from_utf8(xs).err().unwrap();
|
||||
let err = String::from_utf8(xs).unwrap_err();
|
||||
assert_eq!(err.into_bytes(), b"hello\xff".to_vec());
|
||||
}
|
||||
|
||||
|
|
|
@ -735,7 +735,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
infer::Reborrow(span) => {
|
||||
let mut err = struct_span_err!(self.tcx.sess, span, E0312,
|
||||
"lifetime of reference outlines \
|
||||
"lifetime of reference outlives \
|
||||
lifetime of borrowed content...");
|
||||
self.tcx.note_and_explain_region(&mut err,
|
||||
"...the reference is valid for ",
|
||||
|
|
|
@ -653,6 +653,101 @@ You can find more information about borrowing in the rust-book:
|
|||
http://doc.rust-lang.org/stable/book/references-and-borrowing.html
|
||||
"##,
|
||||
|
||||
E0509: r##"
|
||||
This error occurs when an attempt is made to move out of a value whose type
|
||||
implements the `Drop` trait.
|
||||
|
||||
Example of erroneous code:
|
||||
|
||||
```compile_fail
|
||||
struct FancyNum {
|
||||
num: usize
|
||||
}
|
||||
|
||||
struct DropStruct {
|
||||
fancy: FancyNum
|
||||
}
|
||||
|
||||
impl Drop for DropStruct {
|
||||
fn drop(&mut self) {
|
||||
// Destruct DropStruct, possibly using FancyNum
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let drop_struct = DropStruct{fancy: FancyNum{num: 5}};
|
||||
let fancy_field = drop_struct.fancy; // Error E0509
|
||||
println!("Fancy: {}", fancy_field.num);
|
||||
// implicit call to `drop_struct.drop()` as drop_struct goes out of scope
|
||||
}
|
||||
```
|
||||
|
||||
Here, we tried to move a field out of a struct of type `DropStruct` which
|
||||
implements the `Drop` trait. However, a struct cannot be dropped if one or
|
||||
more of its fields have been moved.
|
||||
|
||||
Structs implementing the `Drop` trait have an implicit destructor that gets
|
||||
called when they go out of scope. This destructor may use the fields of the
|
||||
struct, so moving out of the struct could make it impossible to run the
|
||||
destructor. Therefore, we must think of all values whose type implements the
|
||||
`Drop` trait as single units whose fields cannot be moved.
|
||||
|
||||
This error can be fixed by creating a reference to the fields of a struct,
|
||||
enum, or tuple using the `ref` keyword:
|
||||
|
||||
```
|
||||
struct FancyNum {
|
||||
num: usize
|
||||
}
|
||||
|
||||
struct DropStruct {
|
||||
fancy: FancyNum
|
||||
}
|
||||
|
||||
impl Drop for DropStruct {
|
||||
fn drop(&mut self) {
|
||||
// Destruct DropStruct, possibly using FancyNum
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let drop_struct = DropStruct{fancy: FancyNum{num: 5}};
|
||||
let ref fancy_field = drop_struct.fancy; // No more errors!
|
||||
println!("Fancy: {}", fancy_field.num);
|
||||
// implicit call to `drop_struct.drop()` as drop_struct goes out of scope
|
||||
}
|
||||
```
|
||||
|
||||
Note that this technique can also be used in the arms of a match expression:
|
||||
|
||||
```
|
||||
struct FancyNum {
|
||||
num: usize
|
||||
}
|
||||
|
||||
enum DropEnum {
|
||||
Fancy(FancyNum)
|
||||
}
|
||||
|
||||
impl Drop for DropEnum {
|
||||
fn drop(&mut self) {
|
||||
// Destruct DropEnum, possibly using FancyNum
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Creates and enum of type `DropEnum`, which implements `Drop`
|
||||
let drop_enum = DropEnum::Fancy(FancyNum{num: 10});
|
||||
match drop_enum {
|
||||
// Creates a reference to the inside of `DropEnum::Fancy`
|
||||
DropEnum::Fancy(ref fancy_field) => // No error!
|
||||
println!("It was fancy-- {}!", fancy_field.num),
|
||||
}
|
||||
// implicit call to `drop_enum.drop()` as drop_enum goes out of scope
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
}
|
||||
|
||||
register_diagnostics! {
|
||||
|
@ -664,6 +759,5 @@ register_diagnostics! {
|
|||
E0504, // cannot move `..` into closure because it is borrowed
|
||||
E0505, // cannot move out of `..` because it is borrowed
|
||||
E0508, // cannot move out of type `..`, a non-copy fixed-size array
|
||||
E0509, // cannot move out of type `..`, which defines the `Drop` trait
|
||||
E0524, // two closures require unique access to `..` at the same time
|
||||
}
|
||||
|
|
|
@ -497,6 +497,91 @@ impl Bar {
|
|||
```
|
||||
"##,
|
||||
|
||||
E0408: r##"
|
||||
An "or" pattern was used where the variable bindings are not consistently bound
|
||||
across patterns.
|
||||
|
||||
Example of erroneous code:
|
||||
|
||||
```compile_fail
|
||||
match x {
|
||||
Some(y) | None => { /* use y */ } // error: variable `y` from pattern #1 is
|
||||
// not bound in pattern #2
|
||||
_ => ()
|
||||
}
|
||||
```
|
||||
|
||||
Here, `y` is bound to the contents of the `Some` and can be used within the
|
||||
block corresponding to the match arm. However, in case `x` is `None`, we have
|
||||
not specified what `y` is, and the block will use a nonexistent variable.
|
||||
|
||||
To fix this error, either split into multiple match arms:
|
||||
|
||||
```
|
||||
let x = Some(1);
|
||||
match x {
|
||||
Some(y) => { /* use y */ }
|
||||
None => { /* ... */ }
|
||||
}
|
||||
```
|
||||
|
||||
or, bind the variable to a field of the same type in all sub-patterns of the
|
||||
or pattern:
|
||||
|
||||
```
|
||||
let x = (0, 2);
|
||||
match x {
|
||||
(0, y) | (y, 0) => { /* use y */}
|
||||
_ => {}
|
||||
}
|
||||
```
|
||||
|
||||
In this example, if `x` matches the pattern `(0, _)`, the second field is set
|
||||
to `y`. If it matches `(_, 0)`, the first field is set to `y`; so in all
|
||||
cases `y` is set to some value.
|
||||
"##,
|
||||
|
||||
E0409: r##"
|
||||
An "or" pattern was used where the variable bindings are not consistently bound
|
||||
across patterns.
|
||||
|
||||
Example of erroneous code:
|
||||
|
||||
```compile_fail
|
||||
let x = (0, 2);
|
||||
match x {
|
||||
(0, ref y) | (y, 0) => { /* use y */} // error: variable `y` is bound with
|
||||
// different mode in pattern #2
|
||||
// than in pattern #1
|
||||
_ => ()
|
||||
}
|
||||
```
|
||||
|
||||
Here, `y` is bound by-value in one case and by-reference in the other.
|
||||
|
||||
To fix this error, just use the same mode in both cases.
|
||||
Generally using `ref` or `ref mut` where not already used will fix this:
|
||||
|
||||
```ignore
|
||||
let x = (0, 2);
|
||||
match x {
|
||||
(0, ref y) | (ref y, 0) => { /* use y */}
|
||||
_ => ()
|
||||
}
|
||||
```
|
||||
|
||||
Alternatively, split the pattern:
|
||||
|
||||
```
|
||||
let x = (0, 2);
|
||||
match x {
|
||||
(y, 0) => { /* use y */ }
|
||||
(0, ref y) => { /* use y */}
|
||||
_ => ()
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0411: r##"
|
||||
The `Self` keyword was used outside an impl or a trait. Erroneous code example:
|
||||
|
||||
|
@ -1145,10 +1230,7 @@ register_diagnostics! {
|
|||
// E0258,
|
||||
E0402, // cannot use an outer type parameter in this context
|
||||
E0406, // undeclared associated type
|
||||
E0408, // variable from pattern #1 is not bound in pattern #
|
||||
E0409, // variable is bound with different mode in pattern # than in
|
||||
// pattern #1
|
||||
E0410, // variable from pattern is not bound in pattern 1
|
||||
// E0410, merged into 408
|
||||
E0418, // is not an enum variant, struct or const
|
||||
E0420, // is not an associated const
|
||||
E0421, // unresolved associated const
|
||||
|
|
|
@ -126,12 +126,10 @@ enum ResolutionError<'a> {
|
|||
TypeNotMemberOfTrait(Name, &'a str),
|
||||
/// error E0438: const is not a member of trait
|
||||
ConstNotMemberOfTrait(Name, &'a str),
|
||||
/// error E0408: variable `{}` from pattern #1 is not bound in pattern
|
||||
VariableNotBoundInPattern(Name, usize),
|
||||
/// error E0408: variable `{}` from pattern #{} is not bound in pattern #{}
|
||||
VariableNotBoundInPattern(Name, usize, usize),
|
||||
/// error E0409: variable is bound with different mode in pattern #{} than in pattern #1
|
||||
VariableBoundWithDifferentMode(Name, usize),
|
||||
/// error E0410: variable from pattern is not bound in pattern #1
|
||||
VariableNotBoundInParentPattern(Name, usize),
|
||||
/// error E0411: use of `Self` outside of an impl or trait
|
||||
SelfUsedOutsideImplOrTrait,
|
||||
/// error E0412: use of undeclared
|
||||
|
@ -272,13 +270,14 @@ fn resolve_struct_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
|
|||
const_,
|
||||
trait_)
|
||||
}
|
||||
ResolutionError::VariableNotBoundInPattern(variable_name, pattern_number) => {
|
||||
ResolutionError::VariableNotBoundInPattern(variable_name, from, to) => {
|
||||
struct_span_err!(resolver.session,
|
||||
span,
|
||||
E0408,
|
||||
"variable `{}` from pattern #1 is not bound in pattern #{}",
|
||||
"variable `{}` from pattern #{} is not bound in pattern #{}",
|
||||
variable_name,
|
||||
pattern_number)
|
||||
from,
|
||||
to)
|
||||
}
|
||||
ResolutionError::VariableBoundWithDifferentMode(variable_name, pattern_number) => {
|
||||
struct_span_err!(resolver.session,
|
||||
|
@ -289,14 +288,6 @@ fn resolve_struct_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
|
|||
variable_name,
|
||||
pattern_number)
|
||||
}
|
||||
ResolutionError::VariableNotBoundInParentPattern(variable_name, pattern_number) => {
|
||||
struct_span_err!(resolver.session,
|
||||
span,
|
||||
E0410,
|
||||
"variable `{}` from pattern #{} is not bound in pattern #1",
|
||||
variable_name,
|
||||
pattern_number)
|
||||
}
|
||||
ResolutionError::SelfUsedOutsideImplOrTrait => {
|
||||
struct_span_err!(resolver.session,
|
||||
span,
|
||||
|
@ -2038,7 +2029,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
None => {
|
||||
resolve_error(self,
|
||||
p.span,
|
||||
ResolutionError::VariableNotBoundInPattern(key, i + 1));
|
||||
ResolutionError::VariableNotBoundInPattern(key, 1, i + 1));
|
||||
}
|
||||
Some(binding_i) => {
|
||||
if binding_0.binding_mode != binding_i.binding_mode {
|
||||
|
@ -2055,7 +2046,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
if !map_0.contains_key(&key) {
|
||||
resolve_error(self,
|
||||
binding.span,
|
||||
ResolutionError::VariableNotBoundInParentPattern(key, i + 1));
|
||||
ResolutionError::VariableNotBoundInPattern(key, i + 1, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,25 +10,20 @@
|
|||
|
||||
use std::io::Write;
|
||||
|
||||
use rustc::hir::def_id::{DefId, DefIndex};
|
||||
use syntax::codemap::Span;
|
||||
|
||||
use super::data::*;
|
||||
use super::external_data::*;
|
||||
use super::dump::Dump;
|
||||
use super::span_utils::SpanUtils;
|
||||
|
||||
pub struct CsvDumper<'tcx, 'b, W: 'b> {
|
||||
output: &'b mut W,
|
||||
span: SpanUtils<'tcx>
|
||||
pub struct CsvDumper<'b, W: 'b> {
|
||||
output: &'b mut W
|
||||
}
|
||||
|
||||
impl<'a, 'b, W: Write> CsvDumper<'a, 'b, W> {
|
||||
pub fn new(writer: &'b mut W, span: SpanUtils<'a>) -> CsvDumper<'a, 'b, W> {
|
||||
CsvDumper { output: writer, span: span }
|
||||
impl<'b, W: Write> CsvDumper<'b, W> {
|
||||
pub fn new(writer: &'b mut W) -> CsvDumper<'b, W> {
|
||||
CsvDumper { output: writer }
|
||||
}
|
||||
|
||||
fn record(&mut self, kind: &str, span: Span, values: String) {
|
||||
let span_str = self.span.extent_str(span);
|
||||
fn record(&mut self, kind: &str, span: SpanData, values: String) {
|
||||
let span_str = span_extent_str(span);
|
||||
if let Err(_) = write!(self.output, "{},{}{}\n", kind, span_str, values) {
|
||||
error!("Error writing output");
|
||||
}
|
||||
|
@ -41,7 +36,7 @@ impl<'a, 'b, W: Write> CsvDumper<'a, 'b, W> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
|
||||
impl<'b, W: Write + 'b> Dump for CsvDumper<'b, W> {
|
||||
fn crate_prelude(&mut self, data: CratePreludeData) {
|
||||
let values = make_values_str(&[
|
||||
("name", &data.crate_name),
|
||||
|
@ -65,8 +60,8 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
|
|||
}
|
||||
|
||||
fn enum_data(&mut self, data: EnumData) {
|
||||
let id = data.id.to_string();
|
||||
let scope = data.scope.to_string();
|
||||
let id = data.id.index.as_u32().to_string();
|
||||
let scope = data.scope.index.as_u32().to_string();
|
||||
let values = make_values_str(&[
|
||||
("id", &id),
|
||||
("qualname", &data.qualname),
|
||||
|
@ -78,9 +73,9 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
|
|||
}
|
||||
|
||||
fn extern_crate(&mut self, data: ExternCrateData) {
|
||||
let id = data.id.to_string();
|
||||
let id = data.id.index.as_u32().to_string();
|
||||
let crate_num = data.crate_num.to_string();
|
||||
let scope = data.scope.to_string();
|
||||
let scope = data.scope.index.as_u32().to_string();
|
||||
let values = make_values_str(&[
|
||||
("id", &id),
|
||||
("name", &data.name),
|
||||
|
@ -96,12 +91,12 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
|
|||
let self_ref = data.self_ref.unwrap_or(null_def_id());
|
||||
let trait_ref = data.trait_ref.unwrap_or(null_def_id());
|
||||
|
||||
let id = data.id.to_string();
|
||||
let id = data.id.index.as_u32().to_string();
|
||||
let ref_id = self_ref.index.as_usize().to_string();
|
||||
let ref_id_crate = self_ref.krate.to_string();
|
||||
let trait_id = trait_ref.index.as_usize().to_string();
|
||||
let trait_id_crate = trait_ref.krate.to_string();
|
||||
let scope = data.scope.to_string();
|
||||
let scope = data.scope.index.as_u32().to_string();
|
||||
let values = make_values_str(&[
|
||||
("id", &id),
|
||||
("refid", &ref_id),
|
||||
|
@ -117,8 +112,8 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
|
|||
fn inheritance(&mut self, data: InheritanceData) {
|
||||
let base_id = data.base_id.index.as_usize().to_string();
|
||||
let base_crate = data.base_id.krate.to_string();
|
||||
let deriv_id = data.deriv_id.to_string();
|
||||
let deriv_crate = 0.to_string();
|
||||
let deriv_id = data.deriv_id.index.as_u32().to_string();
|
||||
let deriv_crate = data.deriv_id.krate.to_string();
|
||||
let values = make_values_str(&[
|
||||
("base", &base_id),
|
||||
("basecrate", &base_crate),
|
||||
|
@ -135,8 +130,8 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
|
|||
None => (String::new(), String::new())
|
||||
};
|
||||
|
||||
let id = data.id.to_string();
|
||||
let scope = data.scope.to_string();
|
||||
let id = data.id.index.as_u32().to_string();
|
||||
let scope = data.scope.index.as_u32().to_string();
|
||||
let values = make_values_str(&[
|
||||
("id", &id),
|
||||
("qualname", &data.qualname),
|
||||
|
@ -151,7 +146,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
|
|||
fn function_ref(&mut self, data: FunctionRefData) {
|
||||
let ref_id = data.ref_id.index.as_usize().to_string();
|
||||
let ref_crate = data.ref_id.krate.to_string();
|
||||
let scope = data.scope.to_string();
|
||||
let scope = data.scope.index.as_u32().to_string();
|
||||
let values = make_values_str(&[
|
||||
("refid", &ref_id),
|
||||
("refidcrate", &ref_crate),
|
||||
|
@ -166,7 +161,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
|
|||
let ref_id = data.ref_id.index.as_usize().to_string();
|
||||
let ref_crate = data.ref_id.krate.to_string();
|
||||
let qualname = String::new();
|
||||
let scope = data.scope.to_string();
|
||||
let scope = data.scope.index.as_u32().to_string();
|
||||
let values = make_values_str(&[
|
||||
("refid", &ref_id),
|
||||
("refidcrate", &ref_crate),
|
||||
|
@ -178,8 +173,8 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
|
|||
}
|
||||
|
||||
fn method(&mut self, data: MethodData) {
|
||||
let id = data.id.to_string();
|
||||
let scope = data.scope.to_string();
|
||||
let id = data.id.index.as_u32().to_string();
|
||||
let scope = data.scope.index.as_u32().to_string();
|
||||
let values = make_values_str(&[
|
||||
("id", &id),
|
||||
("qualname", &data.qualname),
|
||||
|
@ -199,7 +194,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
|
|||
|
||||
let def_id = ref_id.index.as_usize().to_string();
|
||||
let def_crate = ref_id.krate.to_string();
|
||||
let scope = data.scope.to_string();
|
||||
let scope = data.scope.index.as_u32().to_string();
|
||||
let values = make_values_str(&[
|
||||
("refid", &def_id),
|
||||
("refidcrate", &def_crate),
|
||||
|
@ -221,7 +216,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
|
|||
}
|
||||
|
||||
fn macro_use(&mut self, data: MacroUseData) {
|
||||
let scope = data.scope.to_string();
|
||||
let scope = data.scope.index.as_u32().to_string();
|
||||
let values = make_values_str(&[
|
||||
("callee_name", &data.name),
|
||||
("qualname", &data.qualname),
|
||||
|
@ -232,8 +227,8 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
|
|||
}
|
||||
|
||||
fn mod_data(&mut self, data: ModData) {
|
||||
let id = data.id.to_string();
|
||||
let scope = data.scope.to_string();
|
||||
let id = data.id.index.as_u32().to_string();
|
||||
let scope = data.scope.index.as_u32().to_string();
|
||||
let values = make_values_str(&[
|
||||
("id", &id),
|
||||
("qualname", &data.qualname),
|
||||
|
@ -250,7 +245,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
|
|||
None => (0.to_string(), 0.to_string())
|
||||
};
|
||||
|
||||
let scope = data.scope.to_string();
|
||||
let scope = data.scope.index.as_u32().to_string();
|
||||
let values = make_values_str(&[
|
||||
("refid", &ref_id),
|
||||
("refidcrate", &ref_crate),
|
||||
|
@ -262,9 +257,9 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
|
|||
}
|
||||
|
||||
fn struct_data(&mut self, data: StructData) {
|
||||
let id = data.id.to_string();
|
||||
let ctor_id = data.ctor_id.to_string();
|
||||
let scope = data.scope.to_string();
|
||||
let id = data.id.index.as_u32().to_string();
|
||||
let ctor_id = data.ctor_id.index.as_u32().to_string();
|
||||
let scope = data.scope.index.as_u32().to_string();
|
||||
let values = make_values_str(&[
|
||||
("id", &id),
|
||||
("ctor_id", &ctor_id),
|
||||
|
@ -277,8 +272,8 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
|
|||
}
|
||||
|
||||
fn struct_variant(&mut self, data: StructVariantData) {
|
||||
let id = data.id.to_string();
|
||||
let scope = data.scope.to_string();
|
||||
let id = data.id.index.as_u32().to_string();
|
||||
let scope = data.scope.index.as_u32().to_string();
|
||||
let values = make_values_str(&[
|
||||
("id", &id),
|
||||
("ctor_id", &id),
|
||||
|
@ -292,8 +287,8 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
|
|||
}
|
||||
|
||||
fn trait_data(&mut self, data: TraitData) {
|
||||
let id = data.id.to_string();
|
||||
let scope = data.scope.to_string();
|
||||
let id = data.id.index.as_u32().to_string();
|
||||
let scope = data.scope.index.as_u32().to_string();
|
||||
let values = make_values_str(&[
|
||||
("id", &id),
|
||||
("qualname", &data.qualname),
|
||||
|
@ -305,8 +300,8 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
|
|||
}
|
||||
|
||||
fn tuple_variant(&mut self, data: TupleVariantData) {
|
||||
let id = data.id.to_string();
|
||||
let scope = data.scope.to_string();
|
||||
let id = data.id.index.as_u32().to_string();
|
||||
let scope = data.scope.index.as_u32().to_string();
|
||||
let values = make_values_str(&[
|
||||
("id", &id),
|
||||
("name", &data.name),
|
||||
|
@ -325,7 +320,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
|
|||
None => (0.to_string(), 0.to_string())
|
||||
};
|
||||
|
||||
let scope = data.scope.to_string();
|
||||
let scope = data.scope.index.as_u32().to_string();
|
||||
let values = make_values_str(&[
|
||||
("refid", &ref_id),
|
||||
("refidcrate", &ref_crate),
|
||||
|
@ -337,7 +332,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
|
|||
}
|
||||
|
||||
fn typedef(&mut self, data: TypedefData) {
|
||||
let id = data.id.to_string();
|
||||
let id = data.id.index.as_u32().to_string();
|
||||
let values = make_values_str(&[
|
||||
("id", &id),
|
||||
("qualname", &data.qualname),
|
||||
|
@ -350,10 +345,10 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
|
|||
fn use_data(&mut self, data: UseData) {
|
||||
let mod_id = data.mod_id.unwrap_or(null_def_id());
|
||||
|
||||
let id = data.id.to_string();
|
||||
let id = data.id.index.as_u32().to_string();
|
||||
let ref_id = mod_id.index.as_usize().to_string();
|
||||
let ref_crate = mod_id.krate.to_string();
|
||||
let scope = data.scope.to_string();
|
||||
let scope = data.scope.index.as_u32().to_string();
|
||||
let values = make_values_str(&[
|
||||
("id", &id),
|
||||
("refid", &ref_id),
|
||||
|
@ -368,8 +363,8 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
|
|||
fn use_glob(&mut self, data: UseGlobData) {
|
||||
let names = data.names.join(", ");
|
||||
|
||||
let id = data.id.to_string();
|
||||
let scope = data.scope.to_string();
|
||||
let id = data.id.index.as_u32().to_string();
|
||||
let scope = data.scope.index.as_u32().to_string();
|
||||
let values = make_values_str(&[
|
||||
("id", &id),
|
||||
("value", &names),
|
||||
|
@ -380,8 +375,8 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
|
|||
}
|
||||
|
||||
fn variable(&mut self, data: VariableData) {
|
||||
let id = data.id.to_string();
|
||||
let scope = data.scope.to_string();
|
||||
let id = data.id.index.as_u32().to_string();
|
||||
let scope = data.scope.index.as_u32().to_string();
|
||||
let values = make_values_str(&[
|
||||
("id", &id),
|
||||
("name", &data.name),
|
||||
|
@ -397,7 +392,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
|
|||
fn variable_ref(&mut self, data: VariableRefData) {
|
||||
let ref_id = data.ref_id.index.as_usize().to_string();
|
||||
let ref_crate = data.ref_id.krate.to_string();
|
||||
let scope = data.scope.to_string();
|
||||
let scope = data.scope.index.as_u32().to_string();
|
||||
let values = make_values_str(&[
|
||||
("refid", &ref_id),
|
||||
("refidcrate", &ref_crate),
|
||||
|
@ -431,9 +426,9 @@ fn make_values_str(pairs: &[(&'static str, &str)]) -> String {
|
|||
})
|
||||
}
|
||||
|
||||
fn null_def_id() -> DefId {
|
||||
DefId {
|
||||
krate: 0,
|
||||
index: DefIndex::new(0),
|
||||
}
|
||||
fn span_extent_str(span: SpanData) -> String {
|
||||
format!("file_name,\"{}\",file_line,{},file_col,{},byte_start,{}\
|
||||
file_line_end,{},file_col_end,{},byte_end,{}",
|
||||
span.file_name, span.line_start, span.column_start, span.byte_start,
|
||||
span.line_end, span.column_end, span.byte_end)
|
||||
}
|
||||
|
|
|
@ -14,39 +14,8 @@
|
|||
//! retrieve the data from a crate.
|
||||
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::ty;
|
||||
use syntax::ast::{CrateNum, NodeId};
|
||||
use syntax::codemap::{Span, CodeMap};
|
||||
|
||||
#[derive(Debug, Clone, RustcEncodable)]
|
||||
pub struct SpanData {
|
||||
file_name: String,
|
||||
byte_start: u32,
|
||||
byte_end: u32,
|
||||
/// 1-based.
|
||||
line_start: usize,
|
||||
line_end: usize,
|
||||
/// 1-based, character offset.
|
||||
column_start: usize,
|
||||
column_end: usize,
|
||||
}
|
||||
|
||||
impl SpanData {
|
||||
pub fn from_span(span: Span, cm: &CodeMap) -> SpanData {
|
||||
let start = cm.lookup_char_pos(span.lo);
|
||||
let end = cm.lookup_char_pos(span.hi);
|
||||
|
||||
SpanData {
|
||||
file_name: start.file.name.clone(),
|
||||
byte_start: span.lo.0,
|
||||
byte_end: span.hi.0,
|
||||
line_start: start.line,
|
||||
line_end: end.line,
|
||||
column_start: start.col.0 + 1,
|
||||
column_end: end.col.0 + 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
use syntax::codemap::Span;
|
||||
|
||||
pub struct CrateData {
|
||||
pub name: String,
|
||||
|
@ -357,58 +326,3 @@ pub struct VariableRefData {
|
|||
pub scope: NodeId,
|
||||
pub ref_id: DefId,
|
||||
}
|
||||
|
||||
// Emitted ids are used to cross-reference items across crates. DefIds and
|
||||
// NodeIds do not usually correspond in any way. The strategy is to use the
|
||||
// index from the DefId as a crate-local id. However, within a crate, DefId
|
||||
// indices and NodeIds can overlap. So, we must adjust the NodeIds. If an
|
||||
// item can be identified by a DefId as well as a NodeId, then we use the
|
||||
// DefId index as the id. If it can't, then we have to use the NodeId, but
|
||||
// need to adjust it so it will not clash with any possible DefId index.
|
||||
pub fn normalize_node_id<'a>(tcx: &ty::TyCtxt<'a>, id: NodeId) -> usize {
|
||||
match tcx.map.opt_local_def_id(id) {
|
||||
Some(id) => id.index.as_usize(),
|
||||
None => id as usize + tcx.map.num_local_def_ids()
|
||||
}
|
||||
}
|
||||
|
||||
// Macro to implement a normalize() function (see below for usage)
|
||||
macro_rules! impl_normalize {
|
||||
($($t:ty => $($field:ident),*);*) => {
|
||||
$(
|
||||
impl $t {
|
||||
pub fn normalize<'a>(mut self, tcx: &ty::TyCtxt<'a>) -> $t {
|
||||
$(
|
||||
self.$field = normalize_node_id(tcx, self.$field) as u32;
|
||||
)*
|
||||
self
|
||||
}
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
impl_normalize! {
|
||||
EnumData => id, scope;
|
||||
ExternCrateData => id, scope;
|
||||
FunctionCallData => scope;
|
||||
FunctionData => id, scope;
|
||||
FunctionRefData => scope;
|
||||
ImplData => id, scope;
|
||||
InheritanceData => deriv_id;
|
||||
MacroUseData => scope;
|
||||
MethodCallData => scope;
|
||||
MethodData => id, scope;
|
||||
ModData => id, scope;
|
||||
ModRefData => scope;
|
||||
StructData => ctor_id, id, scope;
|
||||
StructVariantData => id, scope;
|
||||
TupleVariantData => id, scope;
|
||||
TraitData => id, scope;
|
||||
TypedefData => id;
|
||||
TypeRefData => scope;
|
||||
UseData => id, scope;
|
||||
UseGlobData => id, scope;
|
||||
VariableData => id;
|
||||
VariableRefData => scope
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use super::data::*;
|
||||
use super::external_data::*;
|
||||
|
||||
pub trait Dump {
|
||||
fn crate_prelude(&mut self, CratePreludeData) {}
|
||||
|
|
|
@ -45,6 +45,7 @@ use syntax::ptr::P;
|
|||
use super::{escape, generated_code, SaveContext, PathCollector};
|
||||
use super::data::*;
|
||||
use super::dump::Dump;
|
||||
use super::external_data::Lower;
|
||||
use super::span_utils::SpanUtils;
|
||||
use super::recorder;
|
||||
|
||||
|
@ -133,7 +134,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
span: krate.span,
|
||||
};
|
||||
|
||||
self.dumper.crate_prelude(data);
|
||||
self.dumper.crate_prelude(data.lower(self.tcx));
|
||||
}
|
||||
|
||||
// Return all non-empty prefixes of a path.
|
||||
|
@ -203,7 +204,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
qualname: qualname,
|
||||
scope: self.cur_scope,
|
||||
ref_id: None
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -228,7 +229,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
qualname: qualname,
|
||||
scope: self.cur_scope,
|
||||
ref_id: None
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -249,7 +250,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
span: *span,
|
||||
qualname: qualname.to_owned(),
|
||||
scope: 0
|
||||
});
|
||||
}.lower(self.tcx));
|
||||
|
||||
// write the other sub-paths
|
||||
if len <= 2 {
|
||||
|
@ -262,7 +263,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
qualname: qualname.to_owned(),
|
||||
scope: self.cur_scope,
|
||||
ref_id: None
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -304,7 +305,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
ref_id: Some(def_id),
|
||||
scope: scope,
|
||||
qualname: String::new()
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
Def::Struct(..) |
|
||||
Def::Enum(..) |
|
||||
|
@ -316,7 +317,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
ref_id: Some(def_id),
|
||||
scope: scope,
|
||||
qualname: String::new()
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
Def::Static(_, _) |
|
||||
Def::Const(_) |
|
||||
|
@ -329,14 +330,14 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
ref_id: def_id,
|
||||
scope: scope,
|
||||
name: String::new()
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
Def::Fn(..) => {
|
||||
self.dumper.function_ref(FunctionRefData {
|
||||
span: sub_span.expect("No span found for fn ref"),
|
||||
ref_id: def_id,
|
||||
scope: scope
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
Def::SelfTy(..) |
|
||||
Def::Label(_) |
|
||||
|
@ -371,7 +372,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
type_value: typ,
|
||||
value: String::new(),
|
||||
scope: 0
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -389,7 +390,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
|
||||
if body.is_some() {
|
||||
if !self.span.filter_generated(Some(method_data.span), span) {
|
||||
self.dumper.function(method_data.clone().normalize(&self.tcx));
|
||||
self.dumper.function(method_data.clone().lower(self.tcx));
|
||||
}
|
||||
self.process_formals(&sig.decl.inputs, &method_data.qualname);
|
||||
} else {
|
||||
|
@ -399,7 +400,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
span: method_data.span,
|
||||
scope: method_data.scope,
|
||||
qualname: method_data.qualname.clone(),
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
self.process_generic_params(&sig.generics, span, &method_data.qualname, id);
|
||||
|
@ -424,7 +425,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
let trait_ref_data = self.save_ctxt.get_trait_ref_data(trait_ref, self.cur_scope);
|
||||
if let Some(trait_ref_data) = trait_ref_data {
|
||||
if !self.span.filter_generated(Some(trait_ref_data.span), trait_ref.path.span) {
|
||||
self.dumper.type_ref(trait_ref_data.normalize(&self.tcx));
|
||||
self.dumper.type_ref(trait_ref_data.lower(self.tcx));
|
||||
}
|
||||
|
||||
visit::walk_path(self, &trait_ref.path);
|
||||
|
@ -435,9 +436,8 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
let field_data = self.save_ctxt.get_field_data(field, parent_id);
|
||||
if let Some(mut field_data) = field_data {
|
||||
if !self.span.filter_generated(Some(field_data.span), field.span) {
|
||||
field_data.scope = normalize_node_id(&self.tcx, field_data.scope) as u32;
|
||||
field_data.value = String::new();
|
||||
self.dumper.variable(field_data.normalize(&self.tcx));
|
||||
self.dumper.variable(field_data.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -466,7 +466,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
id: param.id,
|
||||
qualname: name,
|
||||
value: String::new()
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
self.visit_generics(generics);
|
||||
|
@ -480,7 +480,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
if let Some(fn_data) = self.save_ctxt.get_item_data(item) {
|
||||
down_cast_data!(fn_data, FunctionData, item.span);
|
||||
if !self.span.filter_generated(Some(fn_data.span), item.span) {
|
||||
self.dumper.function(fn_data.clone().normalize(&self.tcx));
|
||||
self.dumper.function(fn_data.clone().lower(self.tcx));
|
||||
}
|
||||
|
||||
self.process_formals(&decl.inputs, &fn_data.qualname);
|
||||
|
@ -502,9 +502,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
if let Some(var_data) = self.save_ctxt.get_item_data(item) {
|
||||
down_cast_data!(var_data, VariableData, item.span);
|
||||
if !self.span.filter_generated(Some(var_data.span), item.span) {
|
||||
let mut var_data = var_data;
|
||||
var_data.scope = normalize_node_id(&self.tcx, var_data.scope) as u32;
|
||||
self.dumper.variable(var_data.normalize(&self.tcx));
|
||||
self.dumper.variable(var_data.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
self.visit_ty(&typ);
|
||||
|
@ -529,8 +527,8 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
qualname: qualname,
|
||||
value: self.span.snippet(expr.span),
|
||||
type_value: ty_to_string(&typ),
|
||||
scope: normalize_node_id(&self.tcx, self.cur_scope) as u32
|
||||
}.normalize(&self.tcx));
|
||||
scope: self.cur_scope
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
|
||||
// walk type and init value
|
||||
|
@ -554,7 +552,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
qualname: qualname.clone(),
|
||||
scope: self.cur_scope,
|
||||
value: val
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
|
||||
|
||||
|
@ -577,9 +575,8 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
Some(data) => data,
|
||||
};
|
||||
down_cast_data!(enum_data, EnumData, item.span);
|
||||
let normalized = enum_data.clone().normalize(&self.tcx);
|
||||
if !self.span.filter_generated(Some(normalized.span), item.span) {
|
||||
self.dumper.enum_data(normalized);
|
||||
if !self.span.filter_generated(Some(enum_data.span), item.span) {
|
||||
self.dumper.enum_data(enum_data.clone().lower(self.tcx));
|
||||
}
|
||||
|
||||
for variant in &enum_definition.variants {
|
||||
|
@ -600,7 +597,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
type_value: enum_data.qualname.clone(),
|
||||
value: val,
|
||||
scope: enum_data.scope
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
|
@ -614,7 +611,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
type_value: enum_data.qualname.clone(),
|
||||
value: val,
|
||||
scope: enum_data.scope
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -640,12 +637,12 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
if let Some(ref self_ref) = impl_data.self_ref {
|
||||
has_self_ref = true;
|
||||
if !self.span.filter_generated(Some(self_ref.span), item.span) {
|
||||
self.dumper.type_ref(self_ref.clone().normalize(&self.tcx));
|
||||
self.dumper.type_ref(self_ref.clone().lower(self.tcx));
|
||||
}
|
||||
}
|
||||
if let Some(ref trait_ref_data) = impl_data.trait_ref {
|
||||
if !self.span.filter_generated(Some(trait_ref_data.span), item.span) {
|
||||
self.dumper.type_ref(trait_ref_data.clone().normalize(&self.tcx));
|
||||
self.dumper.type_ref(trait_ref_data.clone().lower(self.tcx));
|
||||
}
|
||||
|
||||
visit::walk_path(self, &trait_ref.as_ref().unwrap().path);
|
||||
|
@ -658,7 +655,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
scope: impl_data.scope,
|
||||
trait_ref: impl_data.trait_ref.map(|d| d.ref_id.unwrap()),
|
||||
self_ref: impl_data.self_ref.map(|d| d.ref_id.unwrap())
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
if !has_self_ref {
|
||||
|
@ -685,7 +682,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
qualname: qualname.clone(),
|
||||
scope: self.cur_scope,
|
||||
value: val
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
|
||||
// super-traits
|
||||
|
@ -708,7 +705,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
ref_id: Some(id),
|
||||
scope: self.cur_scope,
|
||||
qualname: String::new()
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
|
||||
if !self.span.filter_generated(sub_span, trait_ref.path.span) {
|
||||
|
@ -717,7 +714,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
span: sub_span,
|
||||
base_id: id,
|
||||
deriv_id: item.id
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -734,7 +731,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
if let Some(mod_data) = self.save_ctxt.get_item_data(item) {
|
||||
down_cast_data!(mod_data, ModData, item.span);
|
||||
if !self.span.filter_generated(Some(mod_data.span), item.span) {
|
||||
self.dumper.mod_data(mod_data.normalize(&self.tcx));
|
||||
self.dumper.mod_data(mod_data.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -765,14 +762,14 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
ref_id: Some(vrd.ref_id),
|
||||
scope: vrd.scope,
|
||||
qualname: String::new()
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
Some(recorder::FnRef) => {
|
||||
self.dumper.function_ref(FunctionRefData {
|
||||
span: vrd.span,
|
||||
ref_id: vrd.ref_id,
|
||||
scope: vrd.scope
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
Some(recorder::ModRef) => {
|
||||
self.dumper.mod_ref( ModRefData {
|
||||
|
@ -780,27 +777,27 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
ref_id: Some(vrd.ref_id),
|
||||
scope: vrd.scope,
|
||||
qualname: String::new()
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
Some(recorder::VarRef) | None
|
||||
=> self.dumper.variable_ref(vrd.normalize(&self.tcx))
|
||||
=> self.dumper.variable_ref(vrd.lower(self.tcx))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Data::TypeRefData(trd) => {
|
||||
if !self.span.filter_generated(Some(trd.span), path.span) {
|
||||
self.dumper.type_ref(trd.normalize(&self.tcx));
|
||||
self.dumper.type_ref(trd.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
Data::MethodCallData(mcd) => {
|
||||
if !self.span.filter_generated(Some(mcd.span), path.span) {
|
||||
self.dumper.method_call(mcd.normalize(&self.tcx));
|
||||
self.dumper.method_call(mcd.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
Data::FunctionCallData(fcd) => {
|
||||
if !self.span.filter_generated(Some(fcd.span), path.span) {
|
||||
self.dumper.function_call(fcd.normalize(&self.tcx));
|
||||
self.dumper.function_call(fcd.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
|
@ -842,7 +839,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
if let Some(struct_lit_data) = self.save_ctxt.get_expr_data(ex) {
|
||||
down_cast_data!(struct_lit_data, TypeRefData, ex.span);
|
||||
if !self.span.filter_generated(Some(struct_lit_data.span), ex.span) {
|
||||
self.dumper.type_ref(struct_lit_data.normalize(&self.tcx));
|
||||
self.dumper.type_ref(struct_lit_data.lower(self.tcx));
|
||||
}
|
||||
|
||||
let scope = self.save_ctxt.enclosing_scope(ex.id);
|
||||
|
@ -852,7 +849,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
.get_field_ref_data(field, variant, scope) {
|
||||
|
||||
if !self.span.filter_generated(Some(field_data.span), field.ident.span) {
|
||||
self.dumper.variable_ref(field_data.normalize(&self.tcx));
|
||||
self.dumper.variable_ref(field_data.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -867,7 +864,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
if let Some(mcd) = self.save_ctxt.get_expr_data(ex) {
|
||||
down_cast_data!(mcd, MethodCallData, ex.span);
|
||||
if !self.span.filter_generated(Some(mcd.span), ex.span) {
|
||||
self.dumper.method_call(mcd.normalize(&self.tcx));
|
||||
self.dumper.method_call(mcd.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -892,7 +889,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
ref_id: f.did,
|
||||
scope: self.cur_scope,
|
||||
name: String::new()
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
self.visit_pat(&field.pat);
|
||||
|
@ -931,7 +928,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
value: value,
|
||||
type_value: typ,
|
||||
scope: 0
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -961,7 +958,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
span: sub_span,
|
||||
name: data.name.clone(),
|
||||
qualname: qualname.clone()
|
||||
});
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
if !self.mac_uses.contains(&data.span) {
|
||||
|
@ -974,7 +971,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
|||
scope: data.scope,
|
||||
callee_span: data.callee_span,
|
||||
imported: data.imported
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1014,7 +1011,7 @@ impl<'v, 'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'v> for DumpVisitor<'l, 'tcx,
|
|||
mod_id: mod_id,
|
||||
name: ident.to_string(),
|
||||
scope: self.cur_scope
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
self.write_sub_paths_truncated(path, true);
|
||||
}
|
||||
|
@ -1037,7 +1034,7 @@ impl<'v, 'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'v> for DumpVisitor<'l, 'tcx,
|
|||
id: item.id,
|
||||
names: names,
|
||||
scope: self.cur_scope
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
self.write_sub_paths(path, true);
|
||||
}
|
||||
|
@ -1081,7 +1078,7 @@ impl<'v, 'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'v> for DumpVisitor<'l, 'tcx,
|
|||
location: location,
|
||||
span: alias_span.expect("No span found for extern crate"),
|
||||
scope: self.cur_scope,
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
Fn(ref decl, _, _, _, ref ty_params, ref body) =>
|
||||
|
@ -1115,7 +1112,7 @@ impl<'v, 'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'v> for DumpVisitor<'l, 'tcx,
|
|||
id: item.id,
|
||||
qualname: qualname.clone(),
|
||||
value: value
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
|
||||
self.visit_ty(&ty);
|
||||
|
@ -1195,7 +1192,7 @@ impl<'v, 'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'v> for DumpVisitor<'l, 'tcx,
|
|||
ref_id: Some(id),
|
||||
scope: self.cur_scope,
|
||||
qualname: String::new()
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1232,7 +1229,7 @@ impl<'v, 'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'v> for DumpVisitor<'l, 'tcx,
|
|||
if let Some(field_data) = self.save_ctxt.get_expr_data(ex) {
|
||||
down_cast_data!(field_data, VariableRefData, ex.span);
|
||||
if !self.span.filter_generated(Some(field_data.span), ex.span) {
|
||||
self.dumper.variable_ref(field_data.normalize(&self.tcx));
|
||||
self.dumper.variable_ref(field_data.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1250,7 +1247,7 @@ impl<'v, 'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'v> for DumpVisitor<'l, 'tcx,
|
|||
ref_id: def.struct_variant().fields[idx.node].did,
|
||||
scope: self.cur_scope,
|
||||
name: String::new()
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
ty::TyTuple(_) => {}
|
||||
|
@ -1343,7 +1340,7 @@ impl<'v, 'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'v> for DumpVisitor<'l, 'tcx,
|
|||
value: value,
|
||||
type_value: String::new(),
|
||||
scope: 0
|
||||
}.normalize(&self.tcx));
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
Def::Variant(..) | Def::Enum(..) |
|
||||
|
|
618
src/librustc_save_analysis/external_data.rs
Normal file
618
src/librustc_save_analysis/external_data.rs
Normal file
|
@ -0,0 +1,618 @@
|
|||
// Copyright 2016 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.
|
||||
|
||||
use rustc::hir::def_id::{DefId, DefIndex};
|
||||
use rustc::hir::map::Map;
|
||||
use rustc::ty::TyCtxt;
|
||||
use syntax::ast::{CrateNum, NodeId};
|
||||
use syntax::codemap::{Span, CodeMap};
|
||||
|
||||
use super::data;
|
||||
|
||||
// FIXME: this should be pub(crate), but the current snapshot doesn't allow it yet
|
||||
pub trait Lower {
|
||||
type Target;
|
||||
fn lower(self, tcx: &TyCtxt) -> Self::Target;
|
||||
}
|
||||
|
||||
fn make_def_id(id: NodeId, map: &Map) -> DefId {
|
||||
map.opt_local_def_id(id).unwrap_or(null_def_id())
|
||||
}
|
||||
|
||||
pub fn null_def_id() -> DefId {
|
||||
DefId { krate: u32::max_value(), index: DefIndex::from_u32(u32::max_value()) }
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, RustcEncodable)]
|
||||
pub struct SpanData {
|
||||
pub file_name: String,
|
||||
pub byte_start: u32,
|
||||
pub byte_end: u32,
|
||||
/// 1-based.
|
||||
pub line_start: usize,
|
||||
pub line_end: usize,
|
||||
/// 1-based, character offset.
|
||||
pub column_start: usize,
|
||||
pub column_end: usize,
|
||||
}
|
||||
|
||||
impl SpanData {
|
||||
pub fn from_span(span: Span, cm: &CodeMap) -> SpanData {
|
||||
let start = cm.lookup_char_pos(span.lo);
|
||||
let end = cm.lookup_char_pos(span.hi);
|
||||
|
||||
SpanData {
|
||||
file_name: start.file.name.clone(),
|
||||
byte_start: span.lo.0,
|
||||
byte_end: span.hi.0,
|
||||
line_start: start.line,
|
||||
line_end: end.line,
|
||||
column_start: start.col.0 + 1,
|
||||
column_end: end.col.0 + 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct CratePreludeData {
|
||||
pub crate_name: String,
|
||||
pub crate_root: String,
|
||||
pub external_crates: Vec<data::ExternalCrateData>,
|
||||
pub span: SpanData,
|
||||
}
|
||||
|
||||
impl Lower for data::CratePreludeData {
|
||||
type Target = CratePreludeData;
|
||||
|
||||
fn lower(self, tcx: &TyCtxt) -> CratePreludeData {
|
||||
CratePreludeData {
|
||||
crate_name: self.crate_name,
|
||||
crate_root: self.crate_root,
|
||||
external_crates: self.external_crates,
|
||||
span: SpanData::from_span(self.span, tcx.sess.codemap()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data for enum declarations.
|
||||
#[derive(Clone, Debug, RustcEncodable)]
|
||||
pub struct EnumData {
|
||||
pub id: DefId,
|
||||
pub value: String,
|
||||
pub qualname: String,
|
||||
pub span: SpanData,
|
||||
pub scope: DefId,
|
||||
}
|
||||
|
||||
impl Lower for data::EnumData {
|
||||
type Target = EnumData;
|
||||
|
||||
fn lower(self, tcx: &TyCtxt) -> EnumData {
|
||||
EnumData {
|
||||
id: make_def_id(self.id, &tcx.map),
|
||||
value: self.value,
|
||||
qualname: self.qualname,
|
||||
span: SpanData::from_span(self.span, tcx.sess.codemap()),
|
||||
scope: make_def_id(self.scope, &tcx.map),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data for extern crates.
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct ExternCrateData {
|
||||
pub id: DefId,
|
||||
pub name: String,
|
||||
pub crate_num: CrateNum,
|
||||
pub location: String,
|
||||
pub span: SpanData,
|
||||
pub scope: DefId,
|
||||
}
|
||||
|
||||
impl Lower for data::ExternCrateData {
|
||||
type Target = ExternCrateData;
|
||||
|
||||
fn lower(self, tcx: &TyCtxt) -> ExternCrateData {
|
||||
ExternCrateData {
|
||||
id: make_def_id(self.id, &tcx.map),
|
||||
name: self.name,
|
||||
crate_num: self.crate_num,
|
||||
location: self.location,
|
||||
span: SpanData::from_span(self.span, tcx.sess.codemap()),
|
||||
scope: make_def_id(self.scope, &tcx.map),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data about a function call.
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct FunctionCallData {
|
||||
pub span: SpanData,
|
||||
pub scope: DefId,
|
||||
pub ref_id: DefId,
|
||||
}
|
||||
|
||||
impl Lower for data::FunctionCallData {
|
||||
type Target = FunctionCallData;
|
||||
|
||||
fn lower(self, tcx: &TyCtxt) -> FunctionCallData {
|
||||
FunctionCallData {
|
||||
span: SpanData::from_span(self.span, tcx.sess.codemap()),
|
||||
scope: make_def_id(self.scope, &tcx.map),
|
||||
ref_id: self.ref_id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data for all kinds of functions and methods.
|
||||
#[derive(Clone, Debug, RustcEncodable)]
|
||||
pub struct FunctionData {
|
||||
pub id: DefId,
|
||||
pub name: String,
|
||||
pub qualname: String,
|
||||
pub declaration: Option<DefId>,
|
||||
pub span: SpanData,
|
||||
pub scope: DefId,
|
||||
}
|
||||
|
||||
impl Lower for data::FunctionData {
|
||||
type Target = FunctionData;
|
||||
|
||||
fn lower(self, tcx: &TyCtxt) -> FunctionData {
|
||||
FunctionData {
|
||||
id: make_def_id(self.id, &tcx.map),
|
||||
name: self.name,
|
||||
qualname: self.qualname,
|
||||
declaration: self.declaration,
|
||||
span: SpanData::from_span(self.span, tcx.sess.codemap()),
|
||||
scope: make_def_id(self.scope, &tcx.map),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data about a function call.
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct FunctionRefData {
|
||||
pub span: SpanData,
|
||||
pub scope: DefId,
|
||||
pub ref_id: DefId,
|
||||
}
|
||||
|
||||
impl Lower for data::FunctionRefData {
|
||||
type Target = FunctionRefData;
|
||||
|
||||
fn lower(self, tcx: &TyCtxt) -> FunctionRefData {
|
||||
FunctionRefData {
|
||||
span: SpanData::from_span(self.span, tcx.sess.codemap()),
|
||||
scope: make_def_id(self.scope, &tcx.map),
|
||||
ref_id: self.ref_id,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct ImplData {
|
||||
pub id: DefId,
|
||||
pub span: SpanData,
|
||||
pub scope: DefId,
|
||||
pub trait_ref: Option<DefId>,
|
||||
pub self_ref: Option<DefId>,
|
||||
}
|
||||
|
||||
impl Lower for data::ImplData {
|
||||
type Target = ImplData;
|
||||
|
||||
fn lower(self, tcx: &TyCtxt) -> ImplData {
|
||||
ImplData {
|
||||
id: make_def_id(self.id, &tcx.map),
|
||||
span: SpanData::from_span(self.span, tcx.sess.codemap()),
|
||||
scope: make_def_id(self.scope, &tcx.map),
|
||||
trait_ref: self.trait_ref,
|
||||
self_ref: self.self_ref,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct InheritanceData {
|
||||
pub span: SpanData,
|
||||
pub base_id: DefId,
|
||||
pub deriv_id: DefId
|
||||
}
|
||||
|
||||
impl Lower for data::InheritanceData {
|
||||
type Target = InheritanceData;
|
||||
|
||||
fn lower(self, tcx: &TyCtxt) -> InheritanceData {
|
||||
InheritanceData {
|
||||
span: SpanData::from_span(self.span, tcx.sess.codemap()),
|
||||
base_id: self.base_id,
|
||||
deriv_id: make_def_id(self.deriv_id, &tcx.map)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data about a macro declaration.
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct MacroData {
|
||||
pub span: SpanData,
|
||||
pub name: String,
|
||||
pub qualname: String,
|
||||
}
|
||||
|
||||
impl Lower for data::MacroData {
|
||||
type Target = MacroData;
|
||||
|
||||
fn lower(self, tcx: &TyCtxt) -> MacroData {
|
||||
MacroData {
|
||||
span: SpanData::from_span(self.span, tcx.sess.codemap()),
|
||||
name: self.name,
|
||||
qualname: self.qualname,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data about a macro use.
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct MacroUseData {
|
||||
pub span: SpanData,
|
||||
pub name: String,
|
||||
pub qualname: String,
|
||||
// Because macro expansion happens before ref-ids are determined,
|
||||
// we use the callee span to reference the associated macro definition.
|
||||
pub callee_span: SpanData,
|
||||
pub scope: DefId,
|
||||
pub imported: bool,
|
||||
}
|
||||
|
||||
impl Lower for data::MacroUseData {
|
||||
type Target = MacroUseData;
|
||||
|
||||
fn lower(self, tcx: &TyCtxt) -> MacroUseData {
|
||||
MacroUseData {
|
||||
span: SpanData::from_span(self.span, tcx.sess.codemap()),
|
||||
name: self.name,
|
||||
qualname: self.qualname,
|
||||
callee_span: SpanData::from_span(self.callee_span, tcx.sess.codemap()),
|
||||
scope: make_def_id(self.scope, &tcx.map),
|
||||
imported: self.imported,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data about a method call.
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct MethodCallData {
|
||||
pub span: SpanData,
|
||||
pub scope: DefId,
|
||||
pub ref_id: Option<DefId>,
|
||||
pub decl_id: Option<DefId>,
|
||||
}
|
||||
|
||||
impl Lower for data::MethodCallData {
|
||||
type Target = MethodCallData;
|
||||
|
||||
fn lower(self, tcx: &TyCtxt) -> MethodCallData {
|
||||
MethodCallData {
|
||||
span: SpanData::from_span(self.span, tcx.sess.codemap()),
|
||||
scope: make_def_id(self.scope, &tcx.map),
|
||||
ref_id: self.ref_id,
|
||||
decl_id: self.decl_id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data for method declarations (methods with a body are treated as functions).
|
||||
#[derive(Clone, Debug, RustcEncodable)]
|
||||
pub struct MethodData {
|
||||
pub id: DefId,
|
||||
pub qualname: String,
|
||||
pub span: SpanData,
|
||||
pub scope: DefId,
|
||||
}
|
||||
|
||||
impl Lower for data::MethodData {
|
||||
type Target = MethodData;
|
||||
|
||||
fn lower(self, tcx: &TyCtxt) -> MethodData {
|
||||
MethodData {
|
||||
span: SpanData::from_span(self.span, tcx.sess.codemap()),
|
||||
scope: make_def_id(self.scope, &tcx.map),
|
||||
id: make_def_id(self.id, &tcx.map),
|
||||
qualname: self.qualname,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data for modules.
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct ModData {
|
||||
pub id: DefId,
|
||||
pub name: String,
|
||||
pub qualname: String,
|
||||
pub span: SpanData,
|
||||
pub scope: DefId,
|
||||
pub filename: String,
|
||||
}
|
||||
|
||||
impl Lower for data::ModData {
|
||||
type Target = ModData;
|
||||
|
||||
fn lower(self, tcx: &TyCtxt) -> ModData {
|
||||
ModData {
|
||||
id: make_def_id(self.id, &tcx.map),
|
||||
name: self.name,
|
||||
qualname: self.qualname,
|
||||
span: SpanData::from_span(self.span, tcx.sess.codemap()),
|
||||
scope: make_def_id(self.scope, &tcx.map),
|
||||
filename: self.filename,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data for a reference to a module.
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct ModRefData {
|
||||
pub span: SpanData,
|
||||
pub scope: DefId,
|
||||
pub ref_id: Option<DefId>,
|
||||
pub qualname: String
|
||||
}
|
||||
|
||||
impl Lower for data::ModRefData {
|
||||
type Target = ModRefData;
|
||||
|
||||
fn lower(self, tcx: &TyCtxt) -> ModRefData {
|
||||
ModRefData {
|
||||
span: SpanData::from_span(self.span, tcx.sess.codemap()),
|
||||
scope: make_def_id(self.scope, &tcx.map),
|
||||
ref_id: self.ref_id,
|
||||
qualname: self.qualname,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct StructData {
|
||||
pub span: SpanData,
|
||||
pub id: DefId,
|
||||
pub ctor_id: DefId,
|
||||
pub qualname: String,
|
||||
pub scope: DefId,
|
||||
pub value: String
|
||||
}
|
||||
|
||||
impl Lower for data::StructData {
|
||||
type Target = StructData;
|
||||
|
||||
fn lower(self, tcx: &TyCtxt) -> StructData {
|
||||
StructData {
|
||||
span: SpanData::from_span(self.span, tcx.sess.codemap()),
|
||||
id: make_def_id(self.id, &tcx.map),
|
||||
ctor_id: make_def_id(self.ctor_id, &tcx.map),
|
||||
qualname: self.qualname,
|
||||
scope: make_def_id(self.scope, &tcx.map),
|
||||
value: self.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct StructVariantData {
|
||||
pub span: SpanData,
|
||||
pub id: DefId,
|
||||
pub qualname: String,
|
||||
pub type_value: String,
|
||||
pub value: String,
|
||||
pub scope: DefId
|
||||
}
|
||||
|
||||
impl Lower for data::StructVariantData {
|
||||
type Target = StructVariantData;
|
||||
|
||||
fn lower(self, tcx: &TyCtxt) -> StructVariantData {
|
||||
StructVariantData {
|
||||
span: SpanData::from_span(self.span, tcx.sess.codemap()),
|
||||
id: make_def_id(self.id, &tcx.map),
|
||||
qualname: self.qualname,
|
||||
type_value: self.type_value,
|
||||
value: self.value,
|
||||
scope: make_def_id(self.scope, &tcx.map),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct TraitData {
|
||||
pub span: SpanData,
|
||||
pub id: DefId,
|
||||
pub qualname: String,
|
||||
pub scope: DefId,
|
||||
pub value: String
|
||||
}
|
||||
|
||||
impl Lower for data::TraitData {
|
||||
type Target = TraitData;
|
||||
|
||||
fn lower(self, tcx: &TyCtxt) -> TraitData {
|
||||
TraitData {
|
||||
span: SpanData::from_span(self.span, tcx.sess.codemap()),
|
||||
id: make_def_id(self.id, &tcx.map),
|
||||
qualname: self.qualname,
|
||||
scope: make_def_id(self.scope, &tcx.map),
|
||||
value: self.value,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct TupleVariantData {
|
||||
pub span: SpanData,
|
||||
pub id: DefId,
|
||||
pub name: String,
|
||||
pub qualname: String,
|
||||
pub type_value: String,
|
||||
pub value: String,
|
||||
pub scope: DefId,
|
||||
}
|
||||
|
||||
impl Lower for data::TupleVariantData {
|
||||
type Target = TupleVariantData;
|
||||
|
||||
fn lower(self, tcx: &TyCtxt) -> TupleVariantData {
|
||||
TupleVariantData {
|
||||
span: SpanData::from_span(self.span, tcx.sess.codemap()),
|
||||
id: make_def_id(self.id, &tcx.map),
|
||||
name: self.name,
|
||||
qualname: self.qualname,
|
||||
type_value: self.type_value,
|
||||
value: self.value,
|
||||
scope: make_def_id(self.scope, &tcx.map),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data for a typedef.
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct TypedefData {
|
||||
pub id: DefId,
|
||||
pub span: SpanData,
|
||||
pub qualname: String,
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
impl Lower for data::TypedefData {
|
||||
type Target = TypedefData;
|
||||
|
||||
fn lower(self, tcx: &TyCtxt) -> TypedefData {
|
||||
TypedefData {
|
||||
id: make_def_id(self.id, &tcx.map),
|
||||
span: SpanData::from_span(self.span, tcx.sess.codemap()),
|
||||
qualname: self.qualname,
|
||||
value: self.value,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data for a reference to a type or trait.
|
||||
#[derive(Clone, Debug, RustcEncodable)]
|
||||
pub struct TypeRefData {
|
||||
pub span: SpanData,
|
||||
pub scope: DefId,
|
||||
pub ref_id: Option<DefId>,
|
||||
pub qualname: String,
|
||||
}
|
||||
|
||||
impl Lower for data::TypeRefData {
|
||||
type Target = TypeRefData;
|
||||
|
||||
fn lower(self, tcx: &TyCtxt) -> TypeRefData {
|
||||
TypeRefData {
|
||||
span: SpanData::from_span(self.span, tcx.sess.codemap()),
|
||||
scope: make_def_id(self.scope, &tcx.map),
|
||||
ref_id: self.ref_id,
|
||||
qualname: self.qualname,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct UseData {
|
||||
pub id: DefId,
|
||||
pub span: SpanData,
|
||||
pub name: String,
|
||||
pub mod_id: Option<DefId>,
|
||||
pub scope: DefId
|
||||
}
|
||||
|
||||
impl Lower for data::UseData {
|
||||
type Target = UseData;
|
||||
|
||||
fn lower(self, tcx: &TyCtxt) -> UseData {
|
||||
UseData {
|
||||
id: make_def_id(self.id, &tcx.map),
|
||||
span: SpanData::from_span(self.span, tcx.sess.codemap()),
|
||||
name: self.name,
|
||||
mod_id: self.mod_id,
|
||||
scope: make_def_id(self.scope, &tcx.map),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct UseGlobData {
|
||||
pub id: DefId,
|
||||
pub span: SpanData,
|
||||
pub names: Vec<String>,
|
||||
pub scope: DefId
|
||||
}
|
||||
|
||||
impl Lower for data::UseGlobData {
|
||||
type Target = UseGlobData;
|
||||
|
||||
fn lower(self, tcx: &TyCtxt) -> UseGlobData {
|
||||
UseGlobData {
|
||||
id: make_def_id(self.id, &tcx.map),
|
||||
span: SpanData::from_span(self.span, tcx.sess.codemap()),
|
||||
names: self.names,
|
||||
scope: make_def_id(self.scope, &tcx.map),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data for local and global variables (consts and statics).
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct VariableData {
|
||||
pub id: DefId,
|
||||
pub name: String,
|
||||
pub qualname: String,
|
||||
pub span: SpanData,
|
||||
pub scope: DefId,
|
||||
pub value: String,
|
||||
pub type_value: String,
|
||||
}
|
||||
|
||||
impl Lower for data::VariableData {
|
||||
type Target = VariableData;
|
||||
|
||||
fn lower(self, tcx: &TyCtxt) -> VariableData {
|
||||
VariableData {
|
||||
id: make_def_id(self.id, &tcx.map),
|
||||
name: self.name,
|
||||
qualname: self.qualname,
|
||||
span: SpanData::from_span(self.span, tcx.sess.codemap()),
|
||||
scope: make_def_id(self.scope, &tcx.map),
|
||||
value: self.value,
|
||||
type_value: self.type_value,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data for the use of some item (e.g., the use of a local variable, which
|
||||
/// will refer to that variables declaration (by ref_id)).
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct VariableRefData {
|
||||
pub name: String,
|
||||
pub span: SpanData,
|
||||
pub scope: DefId,
|
||||
pub ref_id: DefId,
|
||||
}
|
||||
|
||||
impl Lower for data::VariableRefData {
|
||||
type Target = VariableRefData;
|
||||
|
||||
fn lower(self, tcx: &TyCtxt) -> VariableRefData {
|
||||
VariableRefData {
|
||||
name: self.name,
|
||||
span: SpanData::from_span(self.span, tcx.sess.codemap()),
|
||||
scope: make_def_id(self.scope, &tcx.map),
|
||||
ref_id: self.ref_id,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,29 +11,25 @@
|
|||
use std::io::Write;
|
||||
|
||||
use rustc_serialize::json::as_json;
|
||||
use syntax::codemap::CodeMap;
|
||||
|
||||
use syntax::ast::CrateNum;
|
||||
|
||||
use super::data::{self, SpanData};
|
||||
use super::external_data::*;
|
||||
use super::dump::Dump;
|
||||
|
||||
pub struct JsonDumper<'a, 'b, W: Write + 'b> {
|
||||
pub struct JsonDumper<'b, W: Write + 'b> {
|
||||
output: &'b mut W,
|
||||
codemap: &'a CodeMap,
|
||||
first: bool,
|
||||
}
|
||||
|
||||
impl<'a, 'b, W: Write> JsonDumper<'a, 'b, W> {
|
||||
pub fn new(writer: &'b mut W, codemap: &'a CodeMap) -> JsonDumper<'a, 'b, W> {
|
||||
impl<'b, W: Write> JsonDumper<'b, W> {
|
||||
pub fn new(writer: &'b mut W) -> JsonDumper<'b, W> {
|
||||
if let Err(_) = write!(writer, "[") {
|
||||
error!("Error writing output");
|
||||
}
|
||||
JsonDumper { output: writer, codemap:codemap, first: true }
|
||||
JsonDumper { output: writer, first: true }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, W: Write> Drop for JsonDumper<'a, 'b, W> {
|
||||
impl<'b, W: Write> Drop for JsonDumper<'b, W> {
|
||||
fn drop(&mut self) {
|
||||
if let Err(_) = write!(self.output, "]") {
|
||||
error!("Error writing output");
|
||||
|
@ -43,7 +39,7 @@ impl<'a, 'b, W: Write> Drop for JsonDumper<'a, 'b, W> {
|
|||
|
||||
macro_rules! impl_fn {
|
||||
($fn_name: ident, $data_type: ident) => {
|
||||
fn $fn_name(&mut self, data: data::$data_type) {
|
||||
fn $fn_name(&mut self, data: $data_type) {
|
||||
if self.first {
|
||||
self.first = false;
|
||||
} else {
|
||||
|
@ -51,7 +47,6 @@ macro_rules! impl_fn {
|
|||
error!("Error writing output");
|
||||
}
|
||||
}
|
||||
let data = data.lower(self.codemap);
|
||||
if let Err(_) = write!(self.output, "{}", as_json(&data)) {
|
||||
error!("Error writing output '{}'", as_json(&data));
|
||||
}
|
||||
|
@ -59,7 +54,7 @@ macro_rules! impl_fn {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, W: Write + 'b> Dump for JsonDumper<'a, 'b, W> {
|
||||
impl<'b, W: Write + 'b> Dump for JsonDumper<'b, W> {
|
||||
impl_fn!(crate_prelude, CratePreludeData);
|
||||
impl_fn!(enum_data, EnumData);
|
||||
impl_fn!(extern_crate, ExternCrateData);
|
||||
|
@ -85,567 +80,3 @@ impl<'a, 'b, W: Write + 'b> Dump for JsonDumper<'a, 'b, W> {
|
|||
impl_fn!(variable, VariableData);
|
||||
impl_fn!(variable_ref, VariableRefData);
|
||||
}
|
||||
|
||||
trait Lower {
|
||||
type Target;
|
||||
fn lower(self, cm: &CodeMap) -> Self::Target;
|
||||
}
|
||||
|
||||
pub type Id = u32;
|
||||
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct CratePreludeData {
|
||||
pub crate_name: String,
|
||||
pub crate_root: String,
|
||||
pub external_crates: Vec<data::ExternalCrateData>,
|
||||
pub span: SpanData,
|
||||
}
|
||||
|
||||
impl Lower for data::CratePreludeData {
|
||||
type Target = CratePreludeData;
|
||||
|
||||
fn lower(self, cm: &CodeMap) -> CratePreludeData {
|
||||
CratePreludeData {
|
||||
crate_name: self.crate_name,
|
||||
crate_root: self.crate_root,
|
||||
external_crates: self.external_crates,
|
||||
span: SpanData::from_span(self.span, cm),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data for enum declarations.
|
||||
#[derive(Clone, Debug, RustcEncodable)]
|
||||
pub struct EnumData {
|
||||
pub id: Id,
|
||||
pub value: String,
|
||||
pub qualname: String,
|
||||
pub span: SpanData,
|
||||
pub scope: Id,
|
||||
}
|
||||
|
||||
impl Lower for data::EnumData {
|
||||
type Target = EnumData;
|
||||
|
||||
fn lower(self, cm: &CodeMap) -> EnumData {
|
||||
EnumData {
|
||||
id: self.id,
|
||||
value: self.value,
|
||||
qualname: self.qualname,
|
||||
span: SpanData::from_span(self.span, cm),
|
||||
scope: self.scope,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data for extern crates.
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct ExternCrateData {
|
||||
pub id: Id,
|
||||
pub name: String,
|
||||
pub crate_num: CrateNum,
|
||||
pub location: String,
|
||||
pub span: SpanData,
|
||||
pub scope: Id,
|
||||
}
|
||||
|
||||
impl Lower for data::ExternCrateData {
|
||||
type Target = ExternCrateData;
|
||||
|
||||
fn lower(self, cm: &CodeMap) -> ExternCrateData {
|
||||
ExternCrateData {
|
||||
id: self.id,
|
||||
name: self.name,
|
||||
crate_num: self.crate_num,
|
||||
location: self.location,
|
||||
span: SpanData::from_span(self.span, cm),
|
||||
scope: self.scope,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data about a function call.
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct FunctionCallData {
|
||||
pub span: SpanData,
|
||||
pub scope: Id,
|
||||
pub ref_id: Id,
|
||||
}
|
||||
|
||||
impl Lower for data::FunctionCallData {
|
||||
type Target = FunctionCallData;
|
||||
|
||||
fn lower(self, cm: &CodeMap) -> FunctionCallData {
|
||||
FunctionCallData {
|
||||
span: SpanData::from_span(self.span, cm),
|
||||
scope: self.scope,
|
||||
ref_id: self.ref_id.index.as_u32(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data for all kinds of functions and methods.
|
||||
#[derive(Clone, Debug, RustcEncodable)]
|
||||
pub struct FunctionData {
|
||||
pub id: Id,
|
||||
pub name: String,
|
||||
pub qualname: String,
|
||||
pub declaration: Option<Id>,
|
||||
pub span: SpanData,
|
||||
pub scope: Id,
|
||||
}
|
||||
|
||||
impl Lower for data::FunctionData {
|
||||
type Target = FunctionData;
|
||||
|
||||
fn lower(self, cm: &CodeMap) -> FunctionData {
|
||||
FunctionData {
|
||||
id: self.id,
|
||||
name: self.name,
|
||||
qualname: self.qualname,
|
||||
declaration: self.declaration.map(|id| id.index.as_u32()),
|
||||
span: SpanData::from_span(self.span, cm),
|
||||
scope: self.scope,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data about a function call.
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct FunctionRefData {
|
||||
pub span: SpanData,
|
||||
pub scope: Id,
|
||||
pub ref_id: Id,
|
||||
}
|
||||
|
||||
impl Lower for data::FunctionRefData {
|
||||
type Target = FunctionRefData;
|
||||
|
||||
fn lower(self, cm: &CodeMap) -> FunctionRefData {
|
||||
FunctionRefData {
|
||||
span: SpanData::from_span(self.span, cm),
|
||||
scope: self.scope,
|
||||
ref_id: self.ref_id.index.as_u32(),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct ImplData {
|
||||
pub id: Id,
|
||||
pub span: SpanData,
|
||||
pub scope: Id,
|
||||
pub trait_ref: Option<Id>,
|
||||
pub self_ref: Option<Id>,
|
||||
}
|
||||
|
||||
impl Lower for data::ImplData {
|
||||
type Target = ImplData;
|
||||
|
||||
fn lower(self, cm: &CodeMap) -> ImplData {
|
||||
ImplData {
|
||||
id: self.id,
|
||||
span: SpanData::from_span(self.span, cm),
|
||||
scope: self.scope,
|
||||
trait_ref: self.trait_ref.map(|id| id.index.as_u32()),
|
||||
self_ref: self.self_ref.map(|id| id.index.as_u32()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct InheritanceData {
|
||||
pub span: SpanData,
|
||||
pub base_id: Id,
|
||||
pub deriv_id: Id
|
||||
}
|
||||
|
||||
impl Lower for data::InheritanceData {
|
||||
type Target = InheritanceData;
|
||||
|
||||
fn lower(self, cm: &CodeMap) -> InheritanceData {
|
||||
InheritanceData {
|
||||
span: SpanData::from_span(self.span, cm),
|
||||
base_id: self.base_id.index.as_u32(),
|
||||
deriv_id: self.deriv_id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data about a macro declaration.
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct MacroData {
|
||||
pub span: SpanData,
|
||||
pub name: String,
|
||||
pub qualname: String,
|
||||
}
|
||||
|
||||
impl Lower for data::MacroData {
|
||||
type Target = MacroData;
|
||||
|
||||
fn lower(self, cm: &CodeMap) -> MacroData {
|
||||
MacroData {
|
||||
span: SpanData::from_span(self.span, cm),
|
||||
name: self.name,
|
||||
qualname: self.qualname,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data about a macro use.
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct MacroUseData {
|
||||
pub span: SpanData,
|
||||
pub name: String,
|
||||
pub qualname: String,
|
||||
// Because macro expansion happens before ref-ids are determined,
|
||||
// we use the callee span to reference the associated macro definition.
|
||||
pub callee_span: SpanData,
|
||||
pub scope: Id,
|
||||
pub imported: bool,
|
||||
}
|
||||
|
||||
impl Lower for data::MacroUseData {
|
||||
type Target = MacroUseData;
|
||||
|
||||
fn lower(self, cm: &CodeMap) -> MacroUseData {
|
||||
MacroUseData {
|
||||
span: SpanData::from_span(self.span, cm),
|
||||
name: self.name,
|
||||
qualname: self.qualname,
|
||||
callee_span: SpanData::from_span(self.callee_span, cm),
|
||||
scope: self.scope,
|
||||
imported: self.imported,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data about a method call.
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct MethodCallData {
|
||||
pub span: SpanData,
|
||||
pub scope: Id,
|
||||
pub ref_id: Option<Id>,
|
||||
pub decl_id: Option<Id>,
|
||||
}
|
||||
|
||||
impl Lower for data::MethodCallData {
|
||||
type Target = MethodCallData;
|
||||
|
||||
fn lower(self, cm: &CodeMap) -> MethodCallData {
|
||||
MethodCallData {
|
||||
span: SpanData::from_span(self.span, cm),
|
||||
scope: self.scope,
|
||||
ref_id: self.ref_id.map(|id| id.index.as_u32()),
|
||||
decl_id: self.decl_id.map(|id| id.index.as_u32()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data for method declarations (methods with a body are treated as functions).
|
||||
#[derive(Clone, Debug, RustcEncodable)]
|
||||
pub struct MethodData {
|
||||
pub id: Id,
|
||||
pub qualname: String,
|
||||
pub span: SpanData,
|
||||
pub scope: Id,
|
||||
}
|
||||
|
||||
impl Lower for data::MethodData {
|
||||
type Target = MethodData;
|
||||
|
||||
fn lower(self, cm: &CodeMap) -> MethodData {
|
||||
MethodData {
|
||||
span: SpanData::from_span(self.span, cm),
|
||||
scope: self.scope,
|
||||
id: self.id,
|
||||
qualname: self.qualname,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data for modules.
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct ModData {
|
||||
pub id: Id,
|
||||
pub name: String,
|
||||
pub qualname: String,
|
||||
pub span: SpanData,
|
||||
pub scope: Id,
|
||||
pub filename: String,
|
||||
}
|
||||
|
||||
impl Lower for data::ModData {
|
||||
type Target = ModData;
|
||||
|
||||
fn lower(self, cm: &CodeMap) -> ModData {
|
||||
ModData {
|
||||
id: self.id,
|
||||
name: self.name,
|
||||
qualname: self.qualname,
|
||||
span: SpanData::from_span(self.span, cm),
|
||||
scope: self.scope,
|
||||
filename: self.filename,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data for a reference to a module.
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct ModRefData {
|
||||
pub span: SpanData,
|
||||
pub scope: Id,
|
||||
pub ref_id: Option<Id>,
|
||||
pub qualname: String
|
||||
}
|
||||
|
||||
impl Lower for data::ModRefData {
|
||||
type Target = ModRefData;
|
||||
|
||||
fn lower(self, cm: &CodeMap) -> ModRefData {
|
||||
ModRefData {
|
||||
span: SpanData::from_span(self.span, cm),
|
||||
scope: self.scope,
|
||||
ref_id: self.ref_id.map(|id| id.index.as_u32()),
|
||||
qualname: self.qualname,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct StructData {
|
||||
pub span: SpanData,
|
||||
pub id: Id,
|
||||
pub ctor_id: Id,
|
||||
pub qualname: String,
|
||||
pub scope: Id,
|
||||
pub value: String
|
||||
}
|
||||
|
||||
impl Lower for data::StructData {
|
||||
type Target = StructData;
|
||||
|
||||
fn lower(self, cm: &CodeMap) -> StructData {
|
||||
StructData {
|
||||
span: SpanData::from_span(self.span, cm),
|
||||
id: self.id,
|
||||
ctor_id: self.ctor_id,
|
||||
qualname: self.qualname,
|
||||
scope: self.scope,
|
||||
value: self.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct StructVariantData {
|
||||
pub span: SpanData,
|
||||
pub id: Id,
|
||||
pub qualname: String,
|
||||
pub type_value: String,
|
||||
pub value: String,
|
||||
pub scope: Id
|
||||
}
|
||||
|
||||
impl Lower for data::StructVariantData {
|
||||
type Target = StructVariantData;
|
||||
|
||||
fn lower(self, cm: &CodeMap) -> StructVariantData {
|
||||
StructVariantData {
|
||||
span: SpanData::from_span(self.span, cm),
|
||||
id: self.id,
|
||||
qualname: self.qualname,
|
||||
type_value: self.type_value,
|
||||
value: self.value,
|
||||
scope: self.scope,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct TraitData {
|
||||
pub span: SpanData,
|
||||
pub id: Id,
|
||||
pub qualname: String,
|
||||
pub scope: Id,
|
||||
pub value: String
|
||||
}
|
||||
|
||||
impl Lower for data::TraitData {
|
||||
type Target = TraitData;
|
||||
|
||||
fn lower(self, cm: &CodeMap) -> TraitData {
|
||||
TraitData {
|
||||
span: SpanData::from_span(self.span, cm),
|
||||
id: self.id,
|
||||
qualname: self.qualname,
|
||||
scope: self.scope,
|
||||
value: self.value,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct TupleVariantData {
|
||||
pub span: SpanData,
|
||||
pub id: Id,
|
||||
pub name: String,
|
||||
pub qualname: String,
|
||||
pub type_value: String,
|
||||
pub value: String,
|
||||
pub scope: Id,
|
||||
}
|
||||
|
||||
impl Lower for data::TupleVariantData {
|
||||
type Target = TupleVariantData;
|
||||
|
||||
fn lower(self, cm: &CodeMap) -> TupleVariantData {
|
||||
TupleVariantData {
|
||||
span: SpanData::from_span(self.span, cm),
|
||||
id: self.id,
|
||||
name: self.name,
|
||||
qualname: self.qualname,
|
||||
type_value: self.type_value,
|
||||
value: self.value,
|
||||
scope: self.scope,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data for a typedef.
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct TypedefData {
|
||||
pub id: Id,
|
||||
pub span: SpanData,
|
||||
pub qualname: String,
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
impl Lower for data::TypedefData {
|
||||
type Target = TypedefData;
|
||||
|
||||
fn lower(self, cm: &CodeMap) -> TypedefData {
|
||||
TypedefData {
|
||||
id: self.id,
|
||||
span: SpanData::from_span(self.span, cm),
|
||||
qualname: self.qualname,
|
||||
value: self.value,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data for a reference to a type or trait.
|
||||
#[derive(Clone, Debug, RustcEncodable)]
|
||||
pub struct TypeRefData {
|
||||
pub span: SpanData,
|
||||
pub scope: Id,
|
||||
pub ref_id: Option<Id>,
|
||||
pub qualname: String,
|
||||
}
|
||||
|
||||
impl Lower for data::TypeRefData {
|
||||
type Target = TypeRefData;
|
||||
|
||||
fn lower(self, cm: &CodeMap) -> TypeRefData {
|
||||
TypeRefData {
|
||||
span: SpanData::from_span(self.span, cm),
|
||||
scope: self.scope,
|
||||
ref_id: self.ref_id.map(|id| id.index.as_u32()),
|
||||
qualname: self.qualname,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct UseData {
|
||||
pub id: Id,
|
||||
pub span: SpanData,
|
||||
pub name: String,
|
||||
pub mod_id: Option<Id>,
|
||||
pub scope: Id
|
||||
}
|
||||
|
||||
impl Lower for data::UseData {
|
||||
type Target = UseData;
|
||||
|
||||
fn lower(self, cm: &CodeMap) -> UseData {
|
||||
UseData {
|
||||
id: self.id,
|
||||
span: SpanData::from_span(self.span, cm),
|
||||
name: self.name,
|
||||
mod_id: self.mod_id.map(|id| id.index.as_u32()),
|
||||
scope: self.scope,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct UseGlobData {
|
||||
pub id: Id,
|
||||
pub span: SpanData,
|
||||
pub names: Vec<String>,
|
||||
pub scope: Id
|
||||
}
|
||||
|
||||
impl Lower for data::UseGlobData {
|
||||
type Target = UseGlobData;
|
||||
|
||||
fn lower(self, cm: &CodeMap) -> UseGlobData {
|
||||
UseGlobData {
|
||||
id: self.id,
|
||||
span: SpanData::from_span(self.span, cm),
|
||||
names: self.names,
|
||||
scope: self.scope,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data for local and global variables (consts and statics).
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct VariableData {
|
||||
pub id: Id,
|
||||
pub name: String,
|
||||
pub qualname: String,
|
||||
pub span: SpanData,
|
||||
pub scope: Id,
|
||||
pub value: String,
|
||||
pub type_value: String,
|
||||
}
|
||||
|
||||
impl Lower for data::VariableData {
|
||||
type Target = VariableData;
|
||||
|
||||
fn lower(self, cm: &CodeMap) -> VariableData {
|
||||
VariableData {
|
||||
id: self.id,
|
||||
name: self.name,
|
||||
qualname: self.qualname,
|
||||
span: SpanData::from_span(self.span, cm),
|
||||
scope: self.scope,
|
||||
value: self.value,
|
||||
type_value: self.type_value,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data for the use of some item (e.g., the use of a local variable, which
|
||||
/// will refer to that variables declaration (by ref_id)).
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct VariableRefData {
|
||||
pub name: String,
|
||||
pub span: SpanData,
|
||||
pub scope: Id,
|
||||
pub ref_id: Id,
|
||||
}
|
||||
|
||||
impl Lower for data::VariableRefData {
|
||||
type Target = VariableRefData;
|
||||
|
||||
fn lower(self, cm: &CodeMap) -> VariableRefData {
|
||||
VariableRefData {
|
||||
name: self.name,
|
||||
span: SpanData::from_span(self.span, cm),
|
||||
scope: self.scope,
|
||||
ref_id: self.ref_id.index.as_u32(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,15 @@
|
|||
#[macro_use] extern crate syntax;
|
||||
extern crate serialize as rustc_serialize;
|
||||
|
||||
mod csv_dumper;
|
||||
mod json_dumper;
|
||||
mod data;
|
||||
mod dump;
|
||||
mod dump_visitor;
|
||||
pub mod external_data;
|
||||
#[macro_use]
|
||||
pub mod span_utils;
|
||||
|
||||
use rustc::hir;
|
||||
use rustc::hir::map::NodeItem;
|
||||
use rustc::hir::def::Def;
|
||||
|
@ -45,14 +54,6 @@ use syntax::parse::token::{self, keywords};
|
|||
use syntax::visit::{self, Visitor};
|
||||
use syntax::print::pprust::ty_to_string;
|
||||
|
||||
mod csv_dumper;
|
||||
mod json_dumper;
|
||||
mod data;
|
||||
mod dump;
|
||||
mod dump_visitor;
|
||||
#[macro_use]
|
||||
pub mod span_utils;
|
||||
|
||||
pub use self::csv_dumper::CsvDumper;
|
||||
pub use self::json_dumper::JsonDumper;
|
||||
pub use self::data::*;
|
||||
|
@ -748,7 +749,6 @@ pub fn process_crate<'l, 'tcx>(tcx: &'l TyCtxt<'tcx>,
|
|||
root_path.pop();
|
||||
let output = &mut output_file;
|
||||
|
||||
let utils: SpanUtils<'tcx> = SpanUtils::new(&tcx.sess);
|
||||
let save_ctxt = SaveContext::new(tcx);
|
||||
|
||||
macro_rules! dump {
|
||||
|
@ -762,8 +762,8 @@ pub fn process_crate<'l, 'tcx>(tcx: &'l TyCtxt<'tcx>,
|
|||
}
|
||||
|
||||
match format {
|
||||
Format::Csv => dump!(CsvDumper::new(output, utils)),
|
||||
Format::Json => dump!(JsonDumper::new(output, utils.sess.codemap())),
|
||||
Format::Csv => dump!(CsvDumper::new(output)),
|
||||
Format::Json => dump!(JsonDumper::new(output)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,10 +18,8 @@ use std::path::Path;
|
|||
|
||||
use syntax::ast;
|
||||
use syntax::codemap::*;
|
||||
use syntax::parse::lexer;
|
||||
use syntax::parse::lexer::{Reader, StringReader};
|
||||
use syntax::parse::token;
|
||||
use syntax::parse::token::{keywords, Token};
|
||||
use syntax::parse::lexer::{self, Reader, StringReader};
|
||||
use syntax::parse::token::{self, keywords, Token};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct SpanUtils<'a> {
|
||||
|
@ -48,23 +46,6 @@ impl<'a> SpanUtils<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
// Standard string for extents/location.
|
||||
#[rustfmt_skip]
|
||||
pub fn extent_str(&self, span: Span) -> String {
|
||||
let lo_loc = self.sess.codemap().lookup_char_pos(span.lo);
|
||||
let hi_loc = self.sess.codemap().lookup_char_pos(span.hi);
|
||||
let lo_pos = self.sess.codemap().bytepos_to_file_charpos(span.lo);
|
||||
let hi_pos = self.sess.codemap().bytepos_to_file_charpos(span.hi);
|
||||
let lo_pos_byte = self.sess.codemap().lookup_byte_offset(span.lo).pos;
|
||||
let hi_pos_byte = self.sess.codemap().lookup_byte_offset(span.hi).pos;
|
||||
|
||||
format!("file_name,\"{}\",file_line,{},file_col,{},extent_start,{},extent_start_bytes,{},\
|
||||
file_line_end,{},file_col_end,{},extent_end,{},extent_end_bytes,{}",
|
||||
SpanUtils::make_path_string(&lo_loc.file.name),
|
||||
lo_loc.line, lo_loc.col.to_usize(), lo_pos.to_usize(), lo_pos_byte.to_usize(),
|
||||
hi_loc.line, hi_loc.col.to_usize(), hi_pos.to_usize(), hi_pos_byte.to_usize())
|
||||
}
|
||||
|
||||
// sub_span starts at span.lo, so we need to adjust the positions etc.
|
||||
// If sub_span is None, we don't need to adjust.
|
||||
pub fn make_sub_span(&self, span: Span, sub_span: Option<Span>) -> Option<Span> {
|
||||
|
|
|
@ -1540,6 +1540,13 @@ impl Type {
|
|||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_generic(&self) -> bool {
|
||||
match *self {
|
||||
ResolvedPath { is_generic, .. } => is_generic,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GetDefId for Type {
|
||||
|
|
|
@ -783,7 +783,7 @@ fn write_shared(cx: &Context,
|
|||
try_err!(write!(&mut f, "{}", *implementor), &mydst);
|
||||
}
|
||||
|
||||
try_err!(write!(&mut f, r"implementors['{}'] = [", krate.name), &mydst);
|
||||
try_err!(write!(&mut f, r#"implementors["{}"] = ["#, krate.name), &mydst);
|
||||
for imp in imps {
|
||||
// If the trait and implementation are in the same crate, then
|
||||
// there's no need to emit information about it (there's inlining
|
||||
|
@ -2144,7 +2144,7 @@ fn render_stability_since_raw<'a>(w: &mut fmt::Formatter,
|
|||
containing_ver: Option<&'a str>) -> fmt::Result {
|
||||
if let Some(v) = ver {
|
||||
if containing_ver != ver && v.len() > 0 {
|
||||
write!(w, "<span class=\"since\">{}</span>",
|
||||
write!(w, "<div class=\"since\">{}</div>",
|
||||
v)?
|
||||
}
|
||||
}
|
||||
|
@ -2545,13 +2545,16 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
|
|||
render_header: bool, outer_version: Option<&str>) -> fmt::Result {
|
||||
if render_header {
|
||||
write!(w, "<h3 class='impl'><span class='in-band'><code>{}</code>", i.inner_impl())?;
|
||||
let since = i.impl_item.stability.as_ref().map(|s| &s.since[..]);
|
||||
render_stability_since_raw(w, since, outer_version)?;
|
||||
write!(w, "</span><span class='out-of-band'>")?;
|
||||
let since = i.impl_item.stability.as_ref().map(|s| &s.since[..]);
|
||||
if let Some(l) = (Item { item: &i.impl_item, cx: cx }).href() {
|
||||
write!(w, "<div class='ghost'></div>")?;
|
||||
render_stability_since_raw(w, since, outer_version)?;
|
||||
write!(w, "<a id='src-{}' class='srclink' \
|
||||
href='{}' title='{}'>[src]</a>",
|
||||
i.impl_item.def_id.index.as_usize(), l, "goto source code")?;
|
||||
} else {
|
||||
render_stability_since_raw(w, since, outer_version)?;
|
||||
}
|
||||
write!(w, "</span>")?;
|
||||
write!(w, "</h3>\n")?;
|
||||
|
|
|
@ -97,6 +97,7 @@ h1, h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):no
|
|||
h1.fqn {
|
||||
border-bottom: 1px dashed;
|
||||
margin-top: 0;
|
||||
position: relative;
|
||||
}
|
||||
h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) {
|
||||
border-bottom: 1px solid;
|
||||
|
@ -105,6 +106,7 @@ h3.impl, h3.method, h4.method, h3.type, h4.type {
|
|||
font-weight: 600;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
position: relative;
|
||||
}
|
||||
h3.impl, h3.method, h3.type {
|
||||
margin-top: 15px;
|
||||
|
@ -265,20 +267,39 @@ nav.sub {
|
|||
|
||||
.content .out-of-band {
|
||||
font-size: 23px;
|
||||
width: 40%;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
text-align: right;
|
||||
display: inline-block;
|
||||
font-weight: normal;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
h3.impl > .out-of-band {
|
||||
font-size: 21px;
|
||||
}
|
||||
|
||||
h4 > code, h3 > code {
|
||||
position: inherit;
|
||||
}
|
||||
|
||||
.in-band, code {
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.content .in-band {
|
||||
width: 60%;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#main { position: relative; }
|
||||
#main > .since {
|
||||
top: inherit;
|
||||
font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
.content table {
|
||||
border-spacing: 0 5px;
|
||||
border-collapse: separate;
|
||||
|
@ -498,11 +519,13 @@ em.stab p {
|
|||
opacity: 0.65;
|
||||
}
|
||||
|
||||
span.since {
|
||||
float: right;
|
||||
.since {
|
||||
font-weight: normal;
|
||||
font-size: initial;
|
||||
color: grey;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.variants_table {
|
||||
|
@ -597,7 +620,19 @@ a.test-arrow {
|
|||
color: #999;
|
||||
}
|
||||
|
||||
.ghost {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ghost + .since {
|
||||
position: initial;
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
.since + .srclink {
|
||||
display: table-cell;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
/* Media Queries */
|
||||
|
||||
|
|
|
@ -26,6 +26,9 @@ h1.fqn {
|
|||
h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) {
|
||||
border-bottom-color: #DDDDDD;
|
||||
}
|
||||
.in-band, code {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.docblock code {
|
||||
background-color: #F5F5F5;
|
||||
|
|
|
@ -115,9 +115,9 @@ impl<'a> fold::DocFolder for Stripper<'a> {
|
|||
|
||||
// trait impls for private items should be stripped
|
||||
clean::ImplItem(clean::Impl{
|
||||
for_: clean::ResolvedPath{ did, .. }, ..
|
||||
for_: clean::ResolvedPath{ did, is_generic, .. }, ..
|
||||
}) => {
|
||||
if did.is_local() && !self.access_levels.is_exported(did) {
|
||||
if did.is_local() && !is_generic && !self.access_levels.is_exported(did) {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
@ -183,7 +183,9 @@ impl<'a> fold::DocFolder for ImplStripper<'a> {
|
|||
fn fold_item(&mut self, i: Item) -> Option<Item> {
|
||||
if let clean::ImplItem(ref imp) = i.inner {
|
||||
if let Some(did) = imp.for_.def_id() {
|
||||
if did.is_local() && !self.retained.contains(&did) {
|
||||
if did.is_local() && !imp.for_.is_generic() &&
|
||||
!self.retained.contains(&did)
|
||||
{
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3948,7 +3948,7 @@ mod tests {
|
|||
let mut mem_buf = string::String::new();
|
||||
let mut encoder = Encoder::new(&mut mem_buf);
|
||||
let result = hm.encode(&mut encoder);
|
||||
match result.err().unwrap() {
|
||||
match result.unwrap_err() {
|
||||
EncoderError::BadHashmapKey => (),
|
||||
_ => panic!("expected bad hash map key")
|
||||
}
|
||||
|
|
|
@ -1772,7 +1772,7 @@ mod tests {
|
|||
let tmpdir = tmpdir();
|
||||
let dir = &tmpdir.join("mkdir_error_twice");
|
||||
check!(fs::create_dir(dir));
|
||||
let e = fs::create_dir(dir).err().unwrap();
|
||||
let e = fs::create_dir(dir).unwrap_err();
|
||||
assert_eq!(e.kind(), ErrorKind::AlreadyExists);
|
||||
}
|
||||
|
||||
|
|
|
@ -1127,7 +1127,7 @@ mod tests {
|
|||
let mut writer = BufWriter::new(PanicWriter);
|
||||
let _ = writer.write(b"hello world");
|
||||
let _ = writer.flush();
|
||||
}).join().err().unwrap();
|
||||
}).join().unwrap_err();
|
||||
|
||||
assert_eq!(WRITES.load(Ordering::SeqCst), 1);
|
||||
}
|
||||
|
|
|
@ -535,7 +535,7 @@ impl<T> Sender<T> {
|
|||
///
|
||||
/// // This send will fail because the receiver is gone
|
||||
/// drop(rx);
|
||||
/// assert_eq!(tx.send(1).err().unwrap().0, 1);
|
||||
/// assert_eq!(tx.send(1).unwrap_err().0, 1);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn send(&self, t: T) -> Result<(), SendError<T>> {
|
||||
|
|
|
@ -594,7 +594,7 @@ mod test {
|
|||
assert!(res.is_ok(),
|
||||
"Op {} failed with 1 stack entry: {}",
|
||||
cap,
|
||||
res.err().unwrap());
|
||||
res.unwrap_err());
|
||||
}
|
||||
let caps = ["%+", "%-", "%*", "%/", "%m", "%&", "%|", "%A", "%O"];
|
||||
for &cap in caps.iter() {
|
||||
|
@ -610,7 +610,7 @@ mod test {
|
|||
assert!(res.is_ok(),
|
||||
"Binop {} failed with 2 stack entries: {}",
|
||||
cap,
|
||||
res.err().unwrap());
|
||||
res.unwrap_err());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -625,15 +625,15 @@ mod test {
|
|||
for &(op, bs) in v.iter() {
|
||||
let s = format!("%{{1}}%{{2}}%{}%d", op);
|
||||
let res = expand(s.as_bytes(), &[], &mut Variables::new());
|
||||
assert!(res.is_ok(), res.err().unwrap());
|
||||
assert!(res.is_ok(), res.unwrap_err());
|
||||
assert_eq!(res.unwrap(), vec![b'0' + bs[0]]);
|
||||
let s = format!("%{{1}}%{{1}}%{}%d", op);
|
||||
let res = expand(s.as_bytes(), &[], &mut Variables::new());
|
||||
assert!(res.is_ok(), res.err().unwrap());
|
||||
assert!(res.is_ok(), res.unwrap_err());
|
||||
assert_eq!(res.unwrap(), vec![b'0' + bs[1]]);
|
||||
let s = format!("%{{2}}%{{1}}%{}%d", op);
|
||||
let res = expand(s.as_bytes(), &[], &mut Variables::new());
|
||||
assert!(res.is_ok(), res.err().unwrap());
|
||||
assert!(res.is_ok(), res.unwrap_err());
|
||||
assert_eq!(res.unwrap(), vec![b'0' + bs[2]]);
|
||||
}
|
||||
}
|
||||
|
@ -643,13 +643,13 @@ mod test {
|
|||
let mut vars = Variables::new();
|
||||
let s = b"\\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m";
|
||||
let res = expand(s, &[Number(1)], &mut vars);
|
||||
assert!(res.is_ok(), res.err().unwrap());
|
||||
assert!(res.is_ok(), res.unwrap_err());
|
||||
assert_eq!(res.unwrap(), "\\E[31m".bytes().collect::<Vec<_>>());
|
||||
let res = expand(s, &[Number(8)], &mut vars);
|
||||
assert!(res.is_ok(), res.err().unwrap());
|
||||
assert!(res.is_ok(), res.unwrap_err());
|
||||
assert_eq!(res.unwrap(), "\\E[90m".bytes().collect::<Vec<_>>());
|
||||
let res = expand(s, &[Number(42)], &mut vars);
|
||||
assert!(res.is_ok(), res.err().unwrap());
|
||||
assert!(res.is_ok(), res.unwrap_err());
|
||||
assert_eq!(res.unwrap(), "\\E[38;5;42m".bytes().collect::<Vec<_>>());
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ fn main() {
|
|||
thread::spawn(move|| {
|
||||
let _a = A;
|
||||
lib::callback(|| panic!());
|
||||
}).join().err().unwrap();
|
||||
}).join().unwrap_err();
|
||||
|
||||
unsafe {
|
||||
assert_eq!(lib::statik, 1);
|
||||
|
|
|
@ -62,7 +62,7 @@ fn main() {
|
|||
|
||||
let output = Command::new(&me).arg("bad").before_exec(|| {
|
||||
Err(Error::from_raw_os_error(102))
|
||||
}).output().err().unwrap();
|
||||
}).output().unwrap_err();
|
||||
assert_eq!(output.raw_os_error(), Some(102));
|
||||
|
||||
let pid = unsafe { libc::getpid() };
|
||||
|
|
|
@ -27,6 +27,6 @@ fn main() {
|
|||
thread::spawn(move|| -> () {
|
||||
let _a = A;
|
||||
panic!();
|
||||
}).join().err().unwrap();
|
||||
}).join().unwrap_err();
|
||||
assert!(unsafe { !HIT });
|
||||
}
|
||||
|
|
|
@ -28,10 +28,10 @@ fn main() {
|
|||
panic!("hi there");
|
||||
});
|
||||
|
||||
panic::propagate(result.err().unwrap());
|
||||
panic::propagate(result.unwrap_err());
|
||||
}).join();
|
||||
|
||||
let msg = *result.err().unwrap().downcast::<&'static str>().unwrap();
|
||||
let msg = *result.unwrap_err().downcast::<&'static str>().unwrap();
|
||||
assert_eq!("hi there", msg);
|
||||
assert_eq!(1, A.load(Ordering::SeqCst));
|
||||
}
|
||||
|
|
|
@ -39,5 +39,5 @@ mod b {
|
|||
}
|
||||
|
||||
fn main() {
|
||||
thread::spawn(move|| { ::b::g() }).join().err().unwrap();
|
||||
thread::spawn(move|| { ::b::g() }).join().unwrap_err();
|
||||
}
|
||||
|
|
|
@ -24,13 +24,13 @@ fn test_ret() { let _x: Box<isize> = return; }
|
|||
|
||||
fn test_panic() {
|
||||
fn f() { let _x: Box<isize> = panic!(); }
|
||||
thread::spawn(move|| f() ).join().err().unwrap();
|
||||
thread::spawn(move|| f() ).join().unwrap_err();
|
||||
}
|
||||
|
||||
fn test_panic_indirect() {
|
||||
fn f() -> ! { panic!(); }
|
||||
fn g() { let _x: Box<isize> = f(); }
|
||||
thread::spawn(move|| g() ).join().err().unwrap();
|
||||
thread::spawn(move|| g() ).join().unwrap_err();
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
|
|
|
@ -30,6 +30,6 @@ pub fn main() {
|
|||
let _b = Foo;
|
||||
}).join();
|
||||
|
||||
let s = x.err().unwrap().downcast::<&'static str>().unwrap();
|
||||
let s = x.unwrap_err().downcast::<&'static str>().unwrap();
|
||||
assert_eq!(&**s, "This panic should happen.");
|
||||
}
|
||||
|
|
26
src/test/rustdoc/issue-29503.rs
Normal file
26
src/test/rustdoc/issue-29503.rs
Normal file
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2016 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.
|
||||
|
||||
use std::fmt;
|
||||
|
||||
// @has issue_29503/trait.MyTrait.html
|
||||
pub trait MyTrait {
|
||||
fn my_string(&self) -> String;
|
||||
}
|
||||
|
||||
// @has - "//ul[@id='implementors-list']/li" "impl<T> MyTrait for T where T: Debug"
|
||||
impl<T> MyTrait for T where T: fmt::Debug {
|
||||
fn my_string(&self) -> String {
|
||||
format!("{:?}", self)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue