/// Tries to find the span of the semicolon of a macro call statement.
/// The input must be the *call site* span of a statement from macro expansion.
- ///
- /// v output
- /// mac!();
- /// ^^^^^^ input
+ /// ```ignore (illustrative)
+ /// // v output
+ /// mac!();
+ /// // ^^^^^^ input
+ /// ```
pub fn mac_call_stmt_semi_span(&self, mac_call: Span) -> Option<Span> {
let span = self.span_extend_while(mac_call, char::is_whitespace).ok()?;
let span = span.shrink_to_hi().with_hi(BytePos(span.hi().0.checked_add(1)?));
// take precedence.
for &(ref from, ref to) in self.mapping.iter().rev() {
if let Ok(rest) = path.strip_prefix(from) {
- return (to.join(rest), true);
+ let remapped = if rest.as_os_str().is_empty() {
+ // This is subtle, joining an empty path onto e.g. `foo/bar` will
+ // result in `foo/bar/`, that is, there'll be an additional directory
+ // separator at the end. This can lead to duplicated directory separators
+ // in remapped paths down the line.
+ // So, if we have an exact match, we just return that without a call
+ // to `Path::join()`.
+ to.clone()
+ } else {
+ to.join(rest)
+ };
+
+ return (remapped, true);
}
}