diff options
| author | Tyler Mandry <tmandry@gmail.com> | 2020-08-31 19:18:16 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-08-31 19:18:16 -0700 |
| commit | 934127cca51219a19c213429d873d1153af78c1c (patch) | |
| tree | b79106178405a9b4d14b17d9ae628c070f43520f | |
| parent | 6d834a4046f9591ea9678ce9be2adbbb4a9aeedd (diff) | |
| parent | 7225f668874779f9791fec778e2502e45b311e37 (diff) | |
| download | rust-934127cca51219a19c213429d873d1153af78c1c.tar.gz rust-934127cca51219a19c213429d873d1153af78c1c.zip | |
Rollup merge of #76003 - richkadel:llvm-coverage-map-gen-6b.4, r=wesleywiser
Adds two source span utility functions used in source-based coverage `span.is_empty()` - returns true if `lo()` and `hi()` are equal. This is not only a convenience, but makes it clear that a `Span` can be empty (that is, retrieving the source for an empty `Span` will return an empty string), and codifies the (otherwise undocumented--in the rustc_span package, at least) fact that `Span` is a half-open interval (where `hi()` is the open end). `source_map.lookup_file_span()` - returns an enclosing `Span` representing the start and end positions of the file enclosing the given `BytePos`. This gives developers a clear way to quickly determine if any any other `BytePos` or `Span` is also from the same file (for example, by simply calling `file_span.contains(span)`). This results in much simpler code and is much more runtime efficient compared with the obvious alternative: calling `source_map.lookup_line()` for any two `Span`'s byte positions, handle both arms of the `Result` (both contain the file), and then compare files. It is also more efficient than the non-public method `lookup_source_file_idx()` for each `BytePos`, because, while comparing the internal source file indexes would be efficient, looking up the source file index for every `BytePos` or `Span` to be compared requires a binary search (worst case performance being O(log n) for every lookup). `source_map.lookup_file_span()` performs the binary search only once, to get the `file_span` result that can be used to compare to any number of other `BytePos` or `Span` values and those comparisons are always O(1). This PR was split out from PR #75828 . r? @tmandry FYI: @wesleywiser
| -rw-r--r-- | compiler/rustc_span/src/lib.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_span/src/source_map.rs | 9 |
2 files changed, 16 insertions, 0 deletions
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index c654dade2ab..b478a1d15c5 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -400,6 +400,13 @@ impl Span { span.with_lo(span.hi) } + #[inline] + /// Returns true if hi == lo + pub fn is_empty(&self) -> bool { + let span = self.data(); + span.hi == span.lo + } + /// Returns `self` if `self` is not the dummy span, and `other` otherwise. pub fn substitute_dummy(self, other: Span) -> Span { if self.is_dummy() { other } else { self } diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index 7c656db22ed..37596b8ef6f 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -487,6 +487,15 @@ impl SourceMap { } } + /// Returns a new `Span` covering the start and end `BytePos`s of the file containing the given + /// `pos`. This can be used to quickly determine if another `BytePos` or `Span` is from the same + /// file. + pub fn lookup_file_span(&self, pos: BytePos) -> Span { + let idx = self.lookup_source_file_idx(pos); + let SourceFile { start_pos, end_pos, .. } = *(*self.files.borrow().source_files)[idx]; + Span::with_root_ctxt(start_pos, end_pos) + } + /// Returns `Some(span)`, a union of the LHS and RHS span. The LHS must precede the RHS. If /// there are gaps between LHS and RHS, the resulting union will cross these gaps. /// For this to work, |
