From cfc01150bf9793934f504c5cfdef680c3799ddea Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Sat, 14 Jan 2023 12:45:20 +0000 Subject: [PATCH] implement `AstNode` for `Either` --- crates/hir/src/semantics.rs | 9 +-------- crates/syntax/src/ast.rs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index e0d26103915c0..b801cd785e008 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -1472,14 +1472,7 @@ impl<'db> SemanticsImpl<'db> { } fn is_inside_unsafe(&self, expr: &ast::Expr) -> bool { - let item_or_variant = |ancestor: SyntaxNode| { - if ast::Item::can_cast(ancestor.kind()) { - ast::Item::cast(ancestor).map(Either::Left) - } else { - ast::Variant::cast(ancestor).map(Either::Right) - } - }; - let Some(enclosing_item) = expr.syntax().ancestors().find_map(item_or_variant) else { return false }; + let Some(enclosing_item) = expr.syntax().ancestors().find_map(Either::::cast) else { return false }; let def = match &enclosing_item { Either::Left(ast::Item::Fn(it)) if it.unsafe_token().is_some() => return true, diff --git a/crates/syntax/src/ast.rs b/crates/syntax/src/ast.rs index 10c04575833c8..385a4e0a3cee1 100644 --- a/crates/syntax/src/ast.rs +++ b/crates/syntax/src/ast.rs @@ -13,6 +13,8 @@ pub mod prec; use std::marker::PhantomData; +use itertools::Either; + use crate::{ syntax_node::{SyntaxNode, SyntaxNodeChildren, SyntaxToken}, SyntaxKind, @@ -98,6 +100,34 @@ impl Iterator for AstChildren { } } +impl AstNode for Either +where + L: AstNode, + R: AstNode, +{ + fn can_cast(kind: SyntaxKind) -> bool + where + Self: Sized, + { + L::can_cast(kind) || R::can_cast(kind) + } + + fn cast(syntax: SyntaxNode) -> Option + where + Self: Sized, + { + if L::can_cast(syntax.kind()) { + L::cast(syntax).map(Either::Left) + } else { + R::cast(syntax).map(Either::Right) + } + } + + fn syntax(&self) -> &SyntaxNode { + self.as_ref().either(L::syntax, R::syntax) + } +} + mod support { use super::{AstChildren, AstNode, SyntaxKind, SyntaxNode, SyntaxToken};