Skip to content

Commit

Permalink
Reduce boilerplate for BytePos and CharPos
Browse files Browse the repository at this point in the history
  • Loading branch information
Juici committed Sep 21, 2020
1 parent e0bf356 commit b4b4a2f
Showing 1 changed file with 55 additions and 82 deletions.
137 changes: 55 additions & 82 deletions compiler/rustc_span/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1558,58 +1558,71 @@ pub trait Pos {
fn to_u32(&self) -> u32;
}

/// A byte offset. Keep this small (currently 32-bits), as AST contains
/// a lot of them.
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
pub struct BytePos(pub u32);

/// A character offset. Because of multibyte UTF-8 characters, a byte offset
/// is not equivalent to a character offset. The `SourceMap` will convert `BytePos`
/// values to `CharPos` values as necessary.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub struct CharPos(pub usize);
macro_rules! impl_pos {
(
$(
$(#[$attr:meta])*
$vis:vis struct $ident:ident($inner_vis:vis $inner_ty:ty);
)*
) => {
$(
$(#[$attr])*
$vis struct $ident($inner_vis $inner_ty);

impl Pos for $ident {
#[inline(always)]
fn from_usize(n: usize) -> $ident {
$ident(n as $inner_ty)
}

// FIXME: lots of boilerplate in these impls, but so far my attempts to fix
// have been unsuccessful.
#[inline(always)]
fn to_usize(&self) -> usize {
self.0 as usize
}

impl Pos for BytePos {
#[inline(always)]
fn from_usize(n: usize) -> BytePos {
BytePos(n as u32)
}
#[inline(always)]
fn from_u32(n: u32) -> $ident {
$ident(n as $inner_ty)
}

#[inline(always)]
fn to_usize(&self) -> usize {
self.0 as usize
}
#[inline(always)]
fn to_u32(&self) -> u32 {
self.0 as u32
}
}

#[inline(always)]
fn from_u32(n: u32) -> BytePos {
BytePos(n)
}
impl Add for $ident {
type Output = $ident;

#[inline(always)]
fn to_u32(&self) -> u32 {
self.0
}
}
#[inline(always)]
fn add(self, rhs: $ident) -> $ident {
$ident((self.to_usize() + rhs.to_usize()) as $inner_ty)
}
}

impl Add for BytePos {
type Output = BytePos;
impl Sub for $ident {
type Output = $ident;

#[inline(always)]
fn add(self, rhs: BytePos) -> BytePos {
BytePos((self.to_usize() + rhs.to_usize()) as u32)
}
#[inline(always)]
fn sub(self, rhs: $ident) -> $ident {
$ident((self.to_usize() - rhs.to_usize()) as $inner_ty)
}
}
)*
};
}

impl Sub for BytePos {
type Output = BytePos;
impl_pos! {
/// A byte offset. Keep this small (currently 32-bits), as AST contains
/// a lot of them.
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
pub struct BytePos(pub u32);

#[inline(always)]
fn sub(self, rhs: BytePos) -> BytePos {
BytePos((self.to_usize() - rhs.to_usize()) as u32)
}
/// A character offset. Because of multibyte UTF-8 characters, a byte offset
/// is not equivalent to a character offset. The `SourceMap` will convert `BytePos`
/// values to `CharPos` values as necessary.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub struct CharPos(pub usize);
}

impl<S: rustc_serialize::Encoder> Encodable<S> for BytePos {
Expand All @@ -1624,46 +1637,6 @@ impl<D: rustc_serialize::Decoder> Decodable<D> for BytePos {
}
}

impl Pos for CharPos {
#[inline(always)]
fn from_usize(n: usize) -> CharPos {
CharPos(n)
}

#[inline(always)]
fn to_usize(&self) -> usize {
self.0
}

#[inline(always)]
fn from_u32(n: u32) -> CharPos {
CharPos(n as usize)
}

#[inline(always)]
fn to_u32(&self) -> u32 {
self.0 as u32
}
}

impl Add for CharPos {
type Output = CharPos;

#[inline(always)]
fn add(self, rhs: CharPos) -> CharPos {
CharPos(self.to_usize() + rhs.to_usize())
}
}

impl Sub for CharPos {
type Output = CharPos;

#[inline(always)]
fn sub(self, rhs: CharPos) -> CharPos {
CharPos(self.to_usize() - rhs.to_usize())
}
}

// _____________________________________________________________________________
// Loc, SourceFileAndLine, SourceFileAndBytePos
//
Expand Down

0 comments on commit b4b4a2f

Please sign in to comment.