1
Fork 0
mirror of https://github.com/RGBCube/cstree synced 2025-07-27 09:07:44 +00:00

Fix overly restrictive derive(Clone)s

Previously, we couldn't clone `SyntaxNodeChildren<S, D>` if D wasn't `Clone`,
but `D` doesn't get cloned, so this is misleading and overly restrictive.

This patch fixes that & other structs that did the same thing.
This commit is contained in:
RGBCube 2025-07-09 00:08:07 +03:00
parent fb8cc54104
commit 34b58256ae
Signed by: RGBCube
SSH key fingerprint: SHA256:CzqbPcfwt+GxFYNnFVCqoN5Itn4YFrshg1TrnACpA5M
2 changed files with 74 additions and 4 deletions

View file

@ -66,12 +66,21 @@ impl ExactSizeIterator for Iter<'_> {
impl FusedIterator for Iter<'_> {} impl FusedIterator for Iter<'_> {}
/// An iterator over the child nodes of a [`SyntaxNode`]. /// An iterator over the child nodes of a [`SyntaxNode`].
#[derive(Clone, Debug)] #[derive(Debug)]
pub struct SyntaxNodeChildren<'n, S: Syntax, D: 'static = ()> { pub struct SyntaxNodeChildren<'n, S: Syntax, D: 'static = ()> {
inner: Iter<'n>, inner: Iter<'n>,
parent: &'n SyntaxNode<S, D>, parent: &'n SyntaxNode<S, D>,
} }
impl<S: Syntax, D> Clone for SyntaxNodeChildren<'_, S, D> {
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
parent: self.parent,
}
}
}
impl<'n, S: Syntax, D> SyntaxNodeChildren<'n, S, D> { impl<'n, S: Syntax, D> SyntaxNodeChildren<'n, S, D> {
#[inline] #[inline]
pub(super) fn new(parent: &'n SyntaxNode<S, D>) -> Self { pub(super) fn new(parent: &'n SyntaxNode<S, D>) -> Self {
@ -118,12 +127,21 @@ impl<S: Syntax, D> ExactSizeIterator for SyntaxNodeChildren<'_, S, D> {
impl<S: Syntax, D> FusedIterator for SyntaxNodeChildren<'_, S, D> {} impl<S: Syntax, D> FusedIterator for SyntaxNodeChildren<'_, S, D> {}
/// An iterator over the children of a [`SyntaxNode`]. /// An iterator over the children of a [`SyntaxNode`].
#[derive(Clone, Debug)] #[derive(Debug)]
pub struct SyntaxElementChildren<'n, S: Syntax, D: 'static = ()> { pub struct SyntaxElementChildren<'n, S: Syntax, D: 'static = ()> {
inner: Iter<'n>, inner: Iter<'n>,
parent: &'n SyntaxNode<S, D>, parent: &'n SyntaxNode<S, D>,
} }
impl<S: Syntax, D> Clone for SyntaxElementChildren<'_, S, D> {
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
parent: self.parent,
}
}
}
impl<'n, S: Syntax, D> SyntaxElementChildren<'n, S, D> { impl<'n, S: Syntax, D> SyntaxElementChildren<'n, S, D> {
#[inline] #[inline]
pub(super) fn new(parent: &'n SyntaxNode<S, D>) -> Self { pub(super) fn new(parent: &'n SyntaxNode<S, D>) -> Self {
@ -166,3 +184,35 @@ impl<S: Syntax, D> ExactSizeIterator for SyntaxElementChildren<'_, S, D> {
} }
} }
impl<S: Syntax, D> FusedIterator for SyntaxElementChildren<'_, S, D> {} impl<S: Syntax, D> FusedIterator for SyntaxElementChildren<'_, S, D> {}
#[cfg(test)]
#[allow(dead_code)]
mod tests {
use super::*;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct DummyKind;
impl Syntax for DummyKind {
fn from_raw(_: crate::RawSyntaxKind) -> Self {
unreachable!()
}
fn into_raw(self) -> crate::RawSyntaxKind {
unreachable!()
}
fn static_text(self) -> Option<&'static str> {
unreachable!()
}
}
struct NotClone;
fn assert_clone<C: Clone>() {}
fn test_impls_clone() {
assert_clone::<SyntaxNodeChildren<DummyKind, NotClone>>();
assert_clone::<SyntaxElementChildren<DummyKind, NotClone>>();
}
}

View file

@ -40,13 +40,20 @@ use crate::{
/// let sub = text.slice(2.into()..5.into()); /// let sub = text.slice(2.into()..5.into());
/// assert_eq!(sub, "748"); /// assert_eq!(sub, "748");
/// ``` /// ```
#[derive(Clone)]
pub struct SyntaxText<'n, 'i, I: ?Sized, S: Syntax, D: 'static = ()> { pub struct SyntaxText<'n, 'i, I: ?Sized, S: Syntax, D: 'static = ()> {
node: &'n SyntaxNode<S, D>, node: &'n SyntaxNode<S, D>,
range: TextRange, range: TextRange,
resolver: &'i I, resolver: &'i I,
} }
impl<I: ?Sized, S: Syntax, D> Clone for SyntaxText<'_, '_, I, S, D> {
fn clone(&self) -> Self {
*self
}
}
impl<I: ?Sized, S: Syntax, D> Copy for SyntaxText<'_, '_, I, S, D> {}
impl<'n, 'i, I: Resolver<TokenKey> + ?Sized, S: Syntax, D> SyntaxText<'n, 'i, I, S, D> { impl<'n, 'i, I: Resolver<TokenKey> + ?Sized, S: Syntax, D> SyntaxText<'n, 'i, I, S, D> {
pub(crate) fn new(node: &'n SyntaxNode<S, D>, resolver: &'i I) -> Self { pub(crate) fn new(node: &'n SyntaxNode<S, D>, resolver: &'i I) -> Self {
let range = node.text_range(); let range = node.text_range();
@ -378,7 +385,7 @@ mod private {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::{build::GreenNodeBuilder, RawSyntaxKind}; use crate::{build::GreenNodeBuilder, interning::TokenInterner, RawSyntaxKind};
use super::*; use super::*;
@ -450,4 +457,17 @@ mod tests {
check(&["{", "abc", "}"], &["{", "123", "}", "{"]); check(&["{", "abc", "}"], &["{", "123", "}", "{"]);
check(&["{", "abc", "}ab"], &["{", "abc", "}", "ab"]); check(&["{", "abc", "}ab"], &["{", "abc", "}", "ab"]);
} }
#[allow(dead_code)]
mod impl_asserts {
use super::*;
struct NotClone;
fn assert_copy<C: Copy>() {}
fn test_impls_copy() {
assert_copy::<SyntaxText<TokenInterner, SyntaxKind, NotClone>>();
}
}
} }