Skip to content

Commit

Permalink
Merge pull request #245 from xFrednet/189-smaller-emit-lint
Browse files Browse the repository at this point in the history
API: Reduce parameters for `AstContext::emit_lint` and add docs
  • Loading branch information
xFrednet authored Sep 25, 2023
2 parents c45e608 + b5e01ba commit 4bd433f
Show file tree
Hide file tree
Showing 19 changed files with 534 additions and 237 deletions.
14 changes: 5 additions & 9 deletions marker_adapter/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,12 @@
#![allow(clippy::needless_lifetimes)]

use marker_api::{
ast::{
item::{Body, ItemKind},
ty::SemTyKind,
BodyId, ExpnId, ExpnInfo, ExprId, FileInfo, FilePos, ItemId, Span, SpanId, SpanPos, SpanSource, SymbolId,
TyDefId,
},
ast::{ty::SemTyKind, ExpnId, ExpnInfo, ExprId, FileInfo, FilePos, SpanId, SpanPos, SpanSource, SymbolId},
context::DriverCallbacks,
diagnostic::{Diagnostic, EmissionNode},
diagnostic::Diagnostic,
ffi::{self, FfiOption},
lint::{Level, Lint},
prelude::*,
};

/// ### Safety
Expand Down Expand Up @@ -59,7 +55,7 @@ impl<'ast> DriverContextWrapper<'ast> {

// False positive because `EmissionNode` are non-exhaustive
#[allow(improper_ctypes_definitions)]
extern "C" fn lint_level_at<'ast>(data: &'ast (), lint: &'static Lint, node: EmissionNode) -> Level {
extern "C" fn lint_level_at<'ast>(data: &'ast (), lint: &'static Lint, node: NodeId) -> Level {
unsafe { as_driver_cx(data) }.lint_level_at(lint, node)
}

Expand Down Expand Up @@ -129,7 +125,7 @@ unsafe fn as_driver_cx<'ast>(data: &'ast ()) -> &'ast dyn DriverContext<'ast> {
}

pub trait DriverContext<'ast> {
fn lint_level_at(&'ast self, lint: &'static Lint, node: EmissionNode) -> Level;
fn lint_level_at(&'ast self, lint: &'static Lint, node: NodeId) -> Level;
fn emit_diag(&'ast self, diag: &Diagnostic<'_, 'ast>);

fn item(&'ast self, api_id: ItemId) -> Option<ItemKind<'ast>>;
Expand Down
62 changes: 62 additions & 0 deletions marker_api/src/ast/common/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ macro_rules! new_id {

use new_id;

use crate::private::Sealed;

new_id!(
/// This ID uniquely identifies a crate during linting.
pub CrateId: u32
Expand Down Expand Up @@ -144,3 +146,63 @@ new_id! {
/// This ID uniquely identifies a statement during linting.
pub StmtId: u64
}

#[repr(C)]
#[non_exhaustive]
#[derive(Debug, Clone, Copy)]
pub enum NodeId {
Expr(ExprId),
Item(ItemId),
Stmt(StmtId),
Body(BodyId),
Field(FieldId),
Variant(VariantId),
}

macro_rules! impl_into_node_id_for {
($variant:ident, $ty:ty) => {
impl From<$ty> for NodeId {
fn from(value: $ty) -> Self {
NodeId::$variant(value)
}
}

impl From<&$ty> for NodeId {
fn from(value: &$ty) -> Self {
NodeId::$variant(*value)
}
}
};
}

impl_into_node_id_for!(Expr, ExprId);
impl_into_node_id_for!(Item, ItemId);
impl_into_node_id_for!(Stmt, StmtId);
impl_into_node_id_for!(Body, BodyId);
impl_into_node_id_for!(Field, FieldId);
impl_into_node_id_for!(Variant, VariantId);

pub trait HasNodeId: Sealed {
/// Returns the [`NodeId`] of the identifiable node
fn node_id(&self) -> NodeId;
}

impl<N: HasNodeId> HasNodeId for &N {
fn node_id(&self) -> NodeId {
(*self).node_id()
}
}

macro_rules! impl_identifiable_for {
($ty:ty$(, use $data_trait:path)?) => {
impl<'ast> $crate::ast::HasNodeId for $ty {
fn node_id(&self) -> $crate::ast::NodeId {
$(
use $data_trait;
)*
self.id().into()
}
}
};
}
pub(crate) use impl_identifiable_for;
39 changes: 37 additions & 2 deletions marker_api/src/ast/common/span.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::marker::PhantomData;

use crate::{context::with_cx, diagnostic::Applicability, ffi};
use crate::{context::with_cx, diagnostic::Applicability, ffi, private::Sealed};

use super::{ExpnId, MacroId, SpanId, SpanSrcId, SymbolId};

Expand Down Expand Up @@ -386,6 +386,13 @@ impl<'ast> Span<'ast> {
}
}

impl<'ast> HasSpan<'ast> for Span<'ast> {
fn span(&self) -> &Span<'ast> {
self
}
}
impl Sealed for Span<'_> {}

#[cfg(feature = "driver-api")]
impl<'ast> Span<'ast> {
#[must_use]
Expand Down Expand Up @@ -509,11 +516,14 @@ impl<'ast> Ident<'ast> {
pub fn name(&self) -> &str {
with_cx(self, |cx| cx.symbol_str(self.sym))
}
}

pub fn span(&self) -> &Span<'ast> {
impl<'ast> HasSpan<'ast> for Ident<'ast> {
fn span(&self) -> &Span<'ast> {
with_cx(self, |cx| cx.span(self.span))
}
}
impl<'ast> crate::private::Sealed for Ident<'ast> {}

#[cfg(feature = "driver-api")]
impl<'ast> Ident<'ast> {
Expand Down Expand Up @@ -570,3 +580,28 @@ impl_ident_eq_for!(
std::ffi::OsString,
std::borrow::Cow<'_, str>
);

/// A trait for nodes, that provide a [`Span`].
pub trait HasSpan<'ast>: Sealed {
/// This returns the [`Span`] of the implementing AST node.
fn span(&self) -> &Span<'ast>;
}

/// This macro implements the [`HasSpan`] trait for data types, that provide a
/// `span()` method.
macro_rules! impl_spanned_for {
($ty:ty) => {
impl<'ast> $crate::ast::HasSpan<'ast> for $ty {
fn span(&self) -> &$crate::ast::Span<'ast> {
self.span()
}
}
};
}
pub(crate) use impl_spanned_for;

impl<'ast, N: HasSpan<'ast>> HasSpan<'ast> for &N {
fn span(&self) -> &Span<'ast> {
(*self).span()
}
}
26 changes: 16 additions & 10 deletions marker_api/src/ast/expr.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{private::Sealed, CtorBlocker};
use crate::{prelude::EmissionNode, private::Sealed, CtorBlocker};

use super::{ty::SemTyKind, ExprId, Span, SpanId};
use super::{ty::SemTyKind, ExprId, HasNodeId, HasSpan, Span, SpanId};

use std::{fmt::Debug, marker::PhantomData};

Expand All @@ -27,13 +27,10 @@ pub use unstable_expr::*;
///
/// This trait is only meant to be implemented inside this crate. The `Sealed`
/// super trait prevents external implementations.
pub trait ExprData<'ast>: Debug + Sealed {
pub trait ExprData<'ast>: Debug + EmissionNode<'ast> + HasSpan<'ast> + HasNodeId + Sealed {
/// Returns the [`ExprId`] of this expression.
fn id(&self) -> ExprId;

/// Returns the [`Span`] of this expression.
fn span(&self) -> &Span<'ast>;

/// Returns the semantic type of this expression.
fn ty(&self) -> SemTyKind<'ast>;

Expand Down Expand Up @@ -93,6 +90,8 @@ impl<'ast> ExprKind<'ast> {
impl_expr_kind_fn!(ExprKind: precedence() -> ExprPrecedence);
}

crate::ast::impl_spanned_for!(ExprKind<'ast>);
crate::ast::impl_identifiable_for!(ExprKind<'ast>);
impl Sealed for ExprKind<'_> {}

#[repr(C)]
Expand All @@ -117,6 +116,10 @@ impl<'ast> LitExprKind<'ast> {
impl_expr_kind_fn!(LitExprKind: precedence() -> ExprPrecedence);
}

crate::ast::impl_spanned_for!(LitExprKind<'ast>);
crate::ast::impl_identifiable_for!(LitExprKind<'ast>);
impl Sealed for LitExprKind<'_> {}

impl<'ast> From<LitExprKind<'ast>> for ExprKind<'ast> {
fn from(value: LitExprKind<'ast>) -> Self {
match value {
Expand Down Expand Up @@ -313,10 +316,6 @@ macro_rules! impl_expr_data {
self.data.id
}

fn span(&self) -> &crate::ast::Span<'ast> {
$crate::context::with_cx(self, |cx| cx.span(self.data.span))
}

fn ty(&self) -> $crate::ast::ty::SemTyKind<'ast> {
$crate::context::with_cx(self, |cx| cx.expr_ty(self.data.id))
}
Expand All @@ -328,6 +327,13 @@ macro_rules! impl_expr_data {
}
}

impl<'ast> $crate::ast::HasSpan<'ast> for $self_ty {
fn span(&self) -> &crate::ast::Span<'ast> {
$crate::context::with_cx(self, |cx| cx.span(self.data.span))
}
}
$crate::ast::impl_identifiable_for!($self_ty, use $crate::ast::expr::ExprData);

impl<'ast> $crate::private::Sealed for $self_ty {}

impl<'ast> From<&'ast $self_ty> for $crate::ast::expr::ExprKind<'ast> {
Expand Down
2 changes: 1 addition & 1 deletion marker_api/src/ast/expr/lit_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ impl<'ast> CharLitExpr<'ast> {
/// can be hardware-dependent. For exact value checks, it might be better to check
/// the written float literal by getting the code snipped from the expression span.
/// See:
/// * [`ExprData::span()`](`super::ExprData::span`)
/// * [`HasSpan::span()`](`super::HasSpan::span`)
/// * [`Span::snippet()`](`crate::ast::Span::snippet`)
///
/// All integer literals are unsigned, negative numbers have a unary negation
Expand Down
36 changes: 24 additions & 12 deletions marker_api/src/ast/item.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use std::{fmt::Debug, marker::PhantomData};

use crate::diagnostic::EmissionNode;
use crate::private::Sealed;
use crate::CtorBlocker;

use super::expr::ExprKind;
use super::{Ident, ItemId, Span, SpanId};
use super::{HasNodeId, HasSpan, Ident, ItemId, Span, SpanId};

// Item implementations
mod extern_crate_item;
Expand Down Expand Up @@ -36,15 +37,11 @@ pub use unstable_item::*;
///
/// This trait is only meant to be implemented inside this crate. The `Sealed`
/// super trait prevents external implementations.
pub trait ItemData<'ast>: Debug + Sealed {
pub trait ItemData<'ast>: Debug + EmissionNode<'ast> + HasSpan<'ast> + HasNodeId + Sealed {
/// Returns the [`ItemId`] of this item. This is a unique identifier used for comparison
/// and to request items from the [`AstContext`](`crate::context::AstContext`).
fn id(&self) -> ItemId;

/// The [`Span`] of the entire item. This span should be used for general item related
/// diagnostics.
fn span(&self) -> &Span<'ast>;

/// The [`Visibility`] of this item.
fn visibility(&self) -> &Visibility<'ast>;

Expand Down Expand Up @@ -93,8 +90,12 @@ impl<'ast> ItemKind<'ast> {
impl_item_type_fn!(ItemKind: attrs() -> ());
}

crate::ast::impl_spanned_for!(ItemKind<'ast>);
crate::ast::impl_identifiable_for!(ItemKind<'ast>);
impl<'ast> crate::private::Sealed for ItemKind<'ast> {}

#[non_exhaustive]
#[derive(Debug)]
#[derive(Debug, Copy, Clone)]
pub enum AssocItemKind<'ast> {
TyAlias(&'ast TyAliasItem<'ast>, CtorBlocker),
Const(&'ast ConstItem<'ast>, CtorBlocker),
Expand All @@ -111,6 +112,10 @@ impl<'ast> AssocItemKind<'ast> {
// FIXME: Potentially add a field to the items to optionally store the owner id
}

crate::ast::impl_spanned_for!(AssocItemKind<'ast>);
crate::ast::impl_identifiable_for!(AssocItemKind<'ast>);
impl<'ast> crate::private::Sealed for AssocItemKind<'ast> {}

impl<'ast> From<AssocItemKind<'ast>> for ItemKind<'ast> {
fn from(value: AssocItemKind<'ast>) -> Self {
match value {
Expand All @@ -122,7 +127,7 @@ impl<'ast> From<AssocItemKind<'ast>> for ItemKind<'ast> {
}

#[non_exhaustive]
#[derive(Debug)]
#[derive(Debug, Copy, Clone)]
pub enum ExternItemKind<'ast> {
Static(&'ast StaticItem<'ast>, CtorBlocker),
Fn(&'ast FnItem<'ast>, CtorBlocker),
Expand All @@ -137,6 +142,10 @@ impl<'ast> ExternItemKind<'ast> {
impl_item_type_fn!(ExternItemKind: as_item() -> ItemKind<'ast>);
}

crate::ast::impl_spanned_for!(ExternItemKind<'ast>);
crate::ast::impl_identifiable_for!(ExternItemKind<'ast>);
impl<'ast> crate::private::Sealed for ExternItemKind<'ast> {}

impl<'ast> From<ExternItemKind<'ast>> for ItemKind<'ast> {
fn from(value: ExternItemKind<'ast>) -> Self {
match value {
Expand Down Expand Up @@ -193,10 +202,6 @@ macro_rules! impl_item_data {
self.data.id
}

fn span(&self) -> &crate::ast::Span<'ast> {
$crate::context::with_cx(self, |cx| cx.span(self.data.span))
}

fn visibility(&self) -> &crate::ast::item::Visibility<'ast> {
&self.data.vis
}
Expand All @@ -212,6 +217,13 @@ macro_rules! impl_item_data {
fn attrs(&self) {}
}

impl<'ast> $crate::ast::HasSpan<'ast> for $self_name<'ast> {
fn span(&self) -> &crate::ast::Span<'ast> {
$crate::context::with_cx(self, |cx| cx.span(self.data.span))
}
}

$crate::ast::impl_identifiable_for!($self_name<'ast>, use $crate::ast::item::ItemData);
impl $crate::private::Sealed for $self_name<'_> {}

impl<'ast> From<&'ast $self_name<'ast>> for crate::ast::item::ItemKind<'ast> {
Expand Down
Loading

0 comments on commit 4bd433f

Please sign in to comment.