diff --git a/CHANGELOG.md b/CHANGELOG.md index dc406c6b..84d03bbc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,6 @@ -[Unreleased]: https://github.com/rust-marker/marker/compare/v0.4.0...HEAD +[Unreleased]: https://github.com/rust-marker/marker/compare/v0.4.2...HEAD +[0.4.2]: https://github.com/rust-marker/marker/releases/tag/v0.4.2 +[0.4.1]: https://github.com/rust-marker/marker/releases/tag/v0.4.1 [0.4.0]: https://github.com/rust-marker/marker/releases/tag/v0.4.0 [0.3.0]: https://github.com/rust-marker/marker/releases/tag/v0.3.0 [0.2.1]: https://github.com/rust-marker/marker/releases/tag/v0.2.1 @@ -24,10 +26,24 @@ The following components are considered to be internal and they are excluded fro ## [Unreleased] +[#322]: https://github.com/rust-marker/marker/pull/322 + +### Added + +- [#322]: `sem::TyKind` now implements `From<*>` for all semantic types. + +### Breaking Changes + +- [#322]: Renamed `sem::TyKind::FnTy` -> `sem::TyKind::Fn` +- [#322]: Renamed `sem::TyKind::ClosureTy` -> `sem::TyKind::Closure` +- [#322]: Renamed `sem::ClosureTy::closure_ty_id` -> `sem::ClosureTy::def_id` + ## [0.4.2] - 2023-11-25 [#320]: https://github.com/rust-marker/marker/pull/320 +### Fixed + - [#320]: Disable LTO on release builds to fix the crash on Windows with `exit code: 0xc0000005, STATUS_ACCESS_VIOLATION` ## [0.4.1] - 2023-11-24 diff --git a/marker_api/src/common/id.rs b/marker_api/src/common/id.rs index 2368da49..8705c8a3 100644 --- a/marker_api/src/common/id.rs +++ b/marker_api/src/common/id.rs @@ -142,6 +142,15 @@ new_id! { pub(crate) SymbolId: u32 } +new_id! { + /// **Unstable** + /// + /// This id is used by the driver to lint the semantic type representation, back to the + /// driver type representation, if needed. + #[cfg_attr(feature = "driver-api", visibility::make(pub))] + pub(crate) DriverTyId: u64 +} + new_id! { /// This ID uniquely identifies a statement during linting. pub StmtId: u64 diff --git a/marker_api/src/sem/ty.rs b/marker_api/src/sem/ty.rs index 6921de24..74166b09 100644 --- a/marker_api/src/sem/ty.rs +++ b/marker_api/src/sem/ty.rs @@ -5,6 +5,7 @@ mod ptr_ty; mod sequence_ty; mod trait_ty; mod user_ty; + pub use fn_ty::*; pub use other_ty::*; pub use prim_ty::*; @@ -13,6 +14,9 @@ pub use sequence_ty::*; pub use trait_ty::*; pub use user_ty::*; +use crate::common::DriverTyId; +use std::{fmt::Debug, marker::PhantomData}; + /// The semantic representation of a type. #[repr(C)] #[non_exhaustive] @@ -43,10 +47,10 @@ pub enum TyKind<'ast> { // ================================ /// A [function item type](https://doc.rust-lang.org/reference/types/function-item.html) /// identifying a specific function and potentualy additional generics. - FnTy(&'ast FnTy<'ast>), + Fn(&'ast FnTy<'ast>), /// The semantic representation of a /// [closure type](https://doc.rust-lang.org/reference/types/closure.html). - ClosureTy(&'ast ClosureTy<'ast>), + Closure(&'ast ClosureTy<'ast>), // ================================ // Pointer types // ================================ @@ -110,3 +114,43 @@ impl<'ast> TyKind<'ast> { ty } } + +#[repr(C)] +#[cfg_attr(feature = "driver-api", visibility::make(pub))] +#[cfg_attr(feature = "driver-api", derive(typed_builder::TypedBuilder))] +pub(crate) struct CommonTyData<'ast> { + #[cfg_attr(feature = "driver-api", builder(default))] + _lifetime: PhantomData<&'ast ()>, + driver_id: DriverTyId, +} + +impl<'ast> Debug for CommonTyData<'ast> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("CommonTyData {...}").finish() + } +} + +#[cfg(feature = "driver-api")] +impl<'ast> CommonTyData<'ast> { + pub fn driver_id(&self) -> DriverTyId { + self.driver_id + } +} + +macro_rules! impl_ty_data { + ($self_ty:ty, $enum_name:ident) => { + #[cfg(feature = "driver_api")] + impl<'ast> $self_ty { + pub fn data(&self) -> &$crate::sem::ty::CommonTyData<'ast> { + &self.data + } + } + + impl<'ast> From<&'ast $self_ty> for $crate::sem::ty::TyKind<'ast> { + fn from(from: &'ast $self_ty) -> Self { + $crate::sem::ty::TyKind::$enum_name(from) + } + } + }; +} +use impl_ty_data; diff --git a/marker_api/src/sem/ty/fn_ty.rs b/marker_api/src/sem/ty/fn_ty.rs index 3412f893..7580e524 100644 --- a/marker_api/src/sem/ty/fn_ty.rs +++ b/marker_api/src/sem/ty/fn_ty.rs @@ -3,11 +3,15 @@ use crate::{ sem::generic::GenericArgs, }; +use super::CommonTyData; + /// A [function item type](https://doc.rust-lang.org/reference/types/function-item.html) /// identifying a specific function and potentualy additional generics. #[repr(C)] #[derive(Debug)] +#[cfg_attr(feature = "driver-api", derive(typed_builder::TypedBuilder))] pub struct FnTy<'ast> { + data: CommonTyData<'ast>, fn_id: ItemId, generics: GenericArgs<'ast>, } @@ -24,12 +28,7 @@ impl<'ast> FnTy<'ast> { } } -#[cfg(feature = "driver-api")] -impl<'ast> FnTy<'ast> { - pub fn new(fn_id: ItemId, generics: GenericArgs<'ast>) -> Self { - Self { fn_id, generics } - } -} +super::impl_ty_data!(FnTy<'ast>, Fn); /// The semantic representation of a /// [closure type](https://doc.rust-lang.org/reference/types/closure.html). @@ -38,18 +37,20 @@ impl<'ast> FnTy<'ast> { /// closure. This type on it's own therefore only identifies the type of the closure. #[repr(C)] #[derive(Debug)] +#[cfg_attr(feature = "driver-api", derive(typed_builder::TypedBuilder))] pub struct ClosureTy<'ast> { - closure_ty_id: TyDefId, + data: CommonTyData<'ast>, + def_id: TyDefId, generics: GenericArgs<'ast>, } impl<'ast> ClosureTy<'ast> { - /// This returns the [`ItemId`] of the identified function. - pub fn closure_ty_id(&self) -> TyDefId { - self.closure_ty_id + /// This returns the [`ItemId`] of the struct that was generated for this closure. + pub fn def_id(&self) -> TyDefId { + self.def_id } - /// This returns the [`GenericArgs`] used by identified function + /// This returns the [`GenericArgs`] used by closure. pub fn generics(&self) -> &GenericArgs<'ast> { &self.generics } @@ -58,12 +59,4 @@ impl<'ast> ClosureTy<'ast> { // parameters and return type. } -#[cfg(feature = "driver-api")] -impl<'ast> ClosureTy<'ast> { - pub fn new(closure_ty_id: TyDefId, generics: GenericArgs<'ast>) -> Self { - Self { - closure_ty_id, - generics, - } - } -} +super::impl_ty_data!(ClosureTy<'ast>, Closure); diff --git a/marker_api/src/sem/ty/other_ty.rs b/marker_api/src/sem/ty/other_ty.rs index f9764508..4ca762b6 100644 --- a/marker_api/src/sem/ty/other_ty.rs +++ b/marker_api/src/sem/ty/other_ty.rs @@ -1,16 +1,12 @@ -use std::marker::PhantomData; +use super::CommonTyData; /// The placeholder type, signalling that the semantic type is still unstable /// and therefor not represented as part of the API. #[repr(C)] #[derive(Debug)] +#[cfg_attr(feature = "driver-api", derive(typed_builder::TypedBuilder))] pub struct UnstableTy<'ast> { - _lt: PhantomData<&'ast ()>, + data: CommonTyData<'ast>, } -#[cfg(feature = "driver-api")] -impl<'ast> UnstableTy<'ast> { - pub fn new() -> Self { - Self { _lt: PhantomData } - } -} +super::impl_ty_data!(UnstableTy<'ast>, Unstable); diff --git a/marker_api/src/sem/ty/prim_ty.rs b/marker_api/src/sem/ty/prim_ty.rs index 2f8bb159..bf74a5ad 100644 --- a/marker_api/src/sem/ty/prim_ty.rs +++ b/marker_api/src/sem/ty/prim_ty.rs @@ -1,19 +1,13 @@ -use std::marker::PhantomData; - use crate::common::{NumKind, TextKind}; +use super::CommonTyData; + /// The semantic representation of the [`bool`] type. #[repr(C)] #[derive(Debug)] +#[cfg_attr(feature = "driver-api", derive(typed_builder::TypedBuilder))] pub struct BoolTy<'ast> { - _lt: PhantomData<&'ast ()>, -} - -#[cfg(feature = "driver-api")] -impl<'ast> BoolTy<'ast> { - pub fn new() -> Self { - Self { _lt: PhantomData } - } + data: CommonTyData<'ast>, } impl<'ast> std::fmt::Display for BoolTy<'ast> { @@ -22,24 +16,17 @@ impl<'ast> std::fmt::Display for BoolTy<'ast> { } } +super::impl_ty_data!(BoolTy<'ast>, Bool); + /// The semantic representation of a numeric type like [`u32`], [`i32`], [`f64`]. #[repr(C)] #[derive(Debug)] +#[cfg_attr(feature = "driver-api", derive(typed_builder::TypedBuilder))] pub struct NumTy<'ast> { - _ast: PhantomData<&'ast ()>, + data: CommonTyData<'ast>, numeric_kind: NumKind, } -#[cfg(feature = "driver-api")] -impl<'ast> NumTy<'ast> { - pub fn new(numeric_kind: NumKind) -> Self { - Self { - _ast: PhantomData, - numeric_kind, - } - } -} - impl<'ast> NumTy<'ast> { pub fn numeric_kind(&self) -> NumKind { self.numeric_kind @@ -62,6 +49,8 @@ impl<'ast> NumTy<'ast> { } } +super::impl_ty_data!(NumTy<'ast>, Num); + impl<'ast> std::fmt::Display for NumTy<'ast> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{:?}", self.numeric_kind) @@ -70,21 +59,12 @@ impl<'ast> std::fmt::Display for NumTy<'ast> { /// The semantic representation of a textual type like [`char`] or [`str`]. #[repr(C)] +#[cfg_attr(feature = "driver-api", derive(typed_builder::TypedBuilder))] pub struct TextTy<'ast> { - _ast: PhantomData<&'ast ()>, + data: CommonTyData<'ast>, textual_kind: TextKind, } -#[cfg(feature = "driver-api")] -impl<'ast> TextTy<'ast> { - pub fn new(textual_kind: TextKind) -> Self { - Self { - _ast: PhantomData, - textual_kind, - } - } -} - impl<'ast> TextTy<'ast> { pub fn textual_kind(&self) -> TextKind { self.textual_kind @@ -99,6 +79,8 @@ impl<'ast> TextTy<'ast> { } } +super::impl_ty_data!(TextTy<'ast>, Text); + impl<'ast> std::fmt::Debug for TextTy<'ast> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{:?}", self.textual_kind) @@ -107,16 +89,12 @@ impl<'ast> std::fmt::Debug for TextTy<'ast> { /// The semantic representation of the never type [`!`](prim@never). #[repr(C)] +#[cfg_attr(feature = "driver-api", derive(typed_builder::TypedBuilder))] pub struct NeverTy<'ast> { - _lt: PhantomData<&'ast ()>, + data: CommonTyData<'ast>, } -#[cfg(feature = "driver-api")] -impl<'ast> NeverTy<'ast> { - pub fn new() -> Self { - Self { _lt: PhantomData } - } -} +super::impl_ty_data!(NeverTy<'ast>, Never); impl<'ast> std::fmt::Debug for NeverTy<'ast> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { diff --git a/marker_api/src/sem/ty/ptr_ty.rs b/marker_api/src/sem/ty/ptr_ty.rs index 5970247f..20be8e76 100644 --- a/marker_api/src/sem/ty/ptr_ty.rs +++ b/marker_api/src/sem/ty/ptr_ty.rs @@ -3,7 +3,7 @@ use crate::{ ffi::FfiSlice, }; -use super::TyKind; +use super::{CommonTyData, TyKind}; /// The semantic representation of a reference like [`&T`](prim@reference) /// or [`&mut T`](prim@reference) @@ -13,7 +13,9 @@ use super::TyKind; /// from the type also simplifies type comparisons. #[repr(C)] #[derive(Debug)] +#[cfg_attr(feature = "driver-api", derive(typed_builder::TypedBuilder))] pub struct RefTy<'ast> { + data: CommonTyData<'ast>, mutability: Mutability, inner_ty: TyKind<'ast>, } @@ -30,18 +32,15 @@ impl<'ast> RefTy<'ast> { } } -#[cfg(feature = "driver-api")] -impl<'ast> RefTy<'ast> { - pub fn new(mutability: Mutability, inner_ty: TyKind<'ast>) -> Self { - Self { mutability, inner_ty } - } -} +super::impl_ty_data!(RefTy<'ast>, Ref); /// The semantic representation of a raw pointer like [`*const T`](prim@pointer) /// or [`*mut T`](prim@pointer) #[repr(C)] #[derive(Debug)] +#[cfg_attr(feature = "driver-api", derive(typed_builder::TypedBuilder))] pub struct RawPtrTy<'ast> { + data: CommonTyData<'ast>, mutability: Mutability, inner_ty: TyKind<'ast>, } @@ -56,19 +55,17 @@ impl<'ast> RawPtrTy<'ast> { } } -#[cfg(feature = "driver-api")] -impl<'ast> RawPtrTy<'ast> { - pub fn new(mutability: Mutability, inner_ty: TyKind<'ast>) -> Self { - Self { mutability, inner_ty } - } -} +super::impl_ty_data!(RawPtrTy<'ast>, RawPtr); /// The semantic representation of a function pointer, like [`fn (T) -> U`](prim@fn) #[repr(C)] #[derive(Debug)] +#[cfg_attr(feature = "driver-api", derive(typed_builder::TypedBuilder))] pub struct FnPtrTy<'ast> { + data: CommonTyData<'ast>, safety: Safety, abi: Abi, + #[cfg_attr(feature = "driver-api", builder(setter(into)))] params: FfiSlice<'ast, TyKind<'ast>>, return_ty: TyKind<'ast>, } @@ -91,14 +88,4 @@ impl<'ast> FnPtrTy<'ast> { } } -#[cfg(feature = "driver-api")] -impl<'ast> FnPtrTy<'ast> { - pub fn new(safety: Safety, abi: Abi, params: &'ast [TyKind<'ast>], return_ty: TyKind<'ast>) -> Self { - Self { - safety, - abi, - params: params.into(), - return_ty, - } - } -} +super::impl_ty_data!(FnPtrTy<'ast>, FnPtr); diff --git a/marker_api/src/sem/ty/sequence_ty.rs b/marker_api/src/sem/ty/sequence_ty.rs index b1fefd72..186681f6 100644 --- a/marker_api/src/sem/ty/sequence_ty.rs +++ b/marker_api/src/sem/ty/sequence_ty.rs @@ -1,11 +1,14 @@ use crate::{ffi::FfiSlice, sem::ConstValue}; -use super::TyKind; +use super::{CommonTyData, TyKind}; /// The semantic representation of a tuple type like [`()`](prim@tuple) or [`(T, U)`](prim@tuple) #[repr(C)] #[derive(Debug)] +#[cfg_attr(feature = "driver-api", derive(typed_builder::TypedBuilder))] pub struct TupleTy<'ast> { + data: CommonTyData<'ast>, + #[cfg_attr(feature = "driver-api", builder(setter(into)))] types: FfiSlice<'ast, TyKind<'ast>>, } @@ -15,12 +18,7 @@ impl<'ast> TupleTy<'ast> { } } -#[cfg(feature = "driver-api")] -impl<'ast> TupleTy<'ast> { - pub fn new(types: &'ast [TyKind<'ast>]) -> Self { - Self { types: types.into() } - } -} +super::impl_ty_data!(TupleTy<'ast>, Tuple); impl<'ast> std::fmt::Display for TupleTy<'ast> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { @@ -36,7 +34,9 @@ impl<'ast> std::fmt::Display for TupleTy<'ast> { /// The semantic representation of a variable length slice like [`[T]`](prim@slice) #[repr(C)] +#[cfg_attr(feature = "driver-api", derive(typed_builder::TypedBuilder))] pub struct SliceTy<'ast> { + data: CommonTyData<'ast>, inner_ty: TyKind<'ast>, } @@ -46,12 +46,7 @@ impl<'ast> SliceTy<'ast> { } } -#[cfg(feature = "driver-api")] -impl<'ast> SliceTy<'ast> { - pub fn new(inner_ty: TyKind<'ast>) -> Self { - Self { inner_ty } - } -} +super::impl_ty_data!(SliceTy<'ast>, Slice); impl<'ast> std::fmt::Debug for SliceTy<'ast> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { @@ -62,7 +57,9 @@ impl<'ast> std::fmt::Debug for SliceTy<'ast> { /// The semantic representation of an array with a known size like: [`[T; N]`](prim@array) #[repr(C)] #[derive(Debug)] +#[cfg_attr(feature = "driver-api", derive(typed_builder::TypedBuilder))] pub struct ArrayTy<'ast> { + data: CommonTyData<'ast>, inner_ty: TyKind<'ast>, len: ConstValue<'ast>, } @@ -77,12 +74,7 @@ impl<'ast> ArrayTy<'ast> { } } -#[cfg(feature = "driver-api")] -impl<'ast> ArrayTy<'ast> { - pub fn new(inner_ty: TyKind<'ast>, len: ConstValue<'ast>) -> Self { - Self { inner_ty, len } - } -} +super::impl_ty_data!(ArrayTy<'ast>, Array); impl<'ast> std::fmt::Display for ArrayTy<'ast> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { diff --git a/marker_api/src/sem/ty/trait_ty.rs b/marker_api/src/sem/ty/trait_ty.rs index d5237930..7b758683 100644 --- a/marker_api/src/sem/ty/trait_ty.rs +++ b/marker_api/src/sem/ty/trait_ty.rs @@ -1,23 +1,23 @@ use crate::{ffi::FfiSlice, sem::generic::TraitBound}; +use super::CommonTyData; + /// The semantic representation of a [trait object]. /// /// [trait object]: https://doc.rust-lang.org/reference/types/trait-object.html #[repr(C)] #[derive(Debug)] +#[cfg_attr(feature = "driver-api", derive(typed_builder::TypedBuilder))] pub struct TraitObjTy<'ast> { - bound: FfiSlice<'ast, TraitBound<'ast>>, + data: CommonTyData<'ast>, + #[cfg_attr(feature = "driver-api", builder(setter(into)))] + bounds: FfiSlice<'ast, TraitBound<'ast>>, } impl<'ast> TraitObjTy<'ast> { pub fn bounds(&self) -> &[TraitBound<'ast>] { - self.bound.get() + self.bounds.get() } } -#[cfg(feature = "driver-api")] -impl<'ast> TraitObjTy<'ast> { - pub fn new(bound: &'ast [TraitBound<'ast>]) -> Self { - Self { bound: bound.into() } - } -} +super::impl_ty_data!(TraitObjTy<'ast>, TraitObj); diff --git a/marker_api/src/sem/ty/user_ty.rs b/marker_api/src/sem/ty/user_ty.rs index 34d96118..2b8b1c4b 100644 --- a/marker_api/src/sem/ty/user_ty.rs +++ b/marker_api/src/sem/ty/user_ty.rs @@ -1,10 +1,10 @@ -use std::marker::PhantomData; - use crate::{ common::{GenericId, ItemId, TyDefId}, sem::generic::GenericArgs, }; +use super::CommonTyData; + /// The semantic representation of an abstract data type. This can be an /// [`Enum`], [`Struct`], or [`Union`]. /// @@ -13,7 +13,9 @@ use crate::{ /// [`Union`]: https://doc.rust-lang.org/reference/types/union.html #[repr(C)] #[derive(Debug)] +#[cfg_attr(feature = "driver-api", derive(typed_builder::TypedBuilder))] pub struct AdtTy<'ast> { + data: CommonTyData<'ast>, def_id: TyDefId, generics: GenericArgs<'ast>, } @@ -30,12 +32,7 @@ impl<'ast> AdtTy<'ast> { } } -#[cfg(feature = "driver-api")] -impl<'ast> AdtTy<'ast> { - pub fn new(def_id: TyDefId, generics: GenericArgs<'ast>) -> Self { - Self { def_id, generics } - } -} +super::impl_ty_data!(AdtTy<'ast>, Adt); /// The semantic representation of a generic type. For example /// @@ -47,8 +44,9 @@ impl<'ast> AdtTy<'ast> { /// ``` #[repr(C)] #[derive(Debug)] +#[cfg_attr(feature = "driver-api", derive(typed_builder::TypedBuilder))] pub struct GenericTy<'ast> { - _lifetime: PhantomData<&'ast ()>, + data: CommonTyData<'ast>, generic_id: GenericId, } @@ -61,15 +59,7 @@ impl<'ast> GenericTy<'ast> { } } -#[cfg(feature = "driver-api")] -impl<'ast> GenericTy<'ast> { - pub fn new(generic_id: GenericId) -> Self { - Self { - _lifetime: PhantomData, - generic_id, - } - } -} +super::impl_ty_data!(GenericTy<'ast>, Generic); /// The semantic representation of a type alias. /// @@ -78,8 +68,9 @@ impl<'ast> GenericTy<'ast> { /// known. #[repr(C)] #[derive(Debug)] +#[cfg_attr(feature = "driver-api", derive(typed_builder::TypedBuilder))] pub struct AliasTy<'ast> { - _lifetime: PhantomData<&'ast ()>, + data: CommonTyData<'ast>, alias_item: ItemId, } @@ -90,12 +81,4 @@ impl<'ast> AliasTy<'ast> { } } -#[cfg(feature = "driver-api")] -impl<'ast> AliasTy<'ast> { - pub fn new(alias_item: ItemId) -> Self { - Self { - _lifetime: PhantomData, - alias_item, - } - } -} +super::impl_ty_data!(AliasTy<'ast>, Alias); diff --git a/marker_rustc_driver/src/conversion/marker/common.rs b/marker_rustc_driver/src/conversion/marker/common.rs index 5f7026f3..45f0027a 100644 --- a/marker_rustc_driver/src/conversion/marker/common.rs +++ b/marker_rustc_driver/src/conversion/marker/common.rs @@ -6,6 +6,7 @@ use marker_api::{ span::Ident, }; use rustc_hir as hir; +use rustc_middle as mid; use crate::conversion::common::{BodyIdLayout, DefIdLayout, ExpnIdLayout, HirIdLayout}; use crate::transmute_id; @@ -162,6 +163,16 @@ impl<'ast, 'tcx> MarkerConverterInner<'ast, 'tcx> { // transmute and expect the type to always be 32 bits long. transmute_id!(rustc_span::SyntaxContext as SpanSrcId = id) } + + #[must_use] + pub fn to_driver_ty_id(&self, ty: mid::ty::Ty<'tcx>) -> DriverTyId { + // FIXME(xFrednet): This is another theoretically unsafe conversion, since + // `mid::ty::Ty` doesn't have `#[repr(..)]`. However, it should be fine, as + // long as we only access it in the driver, which has the same ABI for all + // types. This specific one, is even a wrapper around rustc's `Interned` typed + // which should remain valid for `'tcx` and continue to have a small memory footprint. + transmute_id!(mid::ty::Ty as DriverTyId = ty) + } } // Other magical cool things diff --git a/marker_rustc_driver/src/conversion/marker/sem/ty.rs b/marker_rustc_driver/src/conversion/marker/sem/ty.rs index 88eff1ce..e3937ecb 100644 --- a/marker_rustc_driver/src/conversion/marker/sem/ty.rs +++ b/marker_rustc_driver/src/conversion/marker/sem/ty.rs @@ -1,8 +1,8 @@ use marker_api::{ common::{NumKind, TextKind}, sem::{ - AdtTy, AliasTy, ArrayTy, BoolTy, ClosureTy, ConstValue, FnPtrTy, FnTy, GenericTy, NeverTy, NumTy, RawPtrTy, - RefTy, SliceTy, TextTy, TraitObjTy, TupleTy, TyKind, UnstableTy, + self, AdtTy, AliasTy, ArrayTy, BoolTy, ClosureTy, ConstValue, FnPtrTy, FnTy, GenericTy, NeverTy, NumTy, + RawPtrTy, RefTy, SliceTy, TextTy, TraitObjTy, TupleTy, TyKind, UnstableTy, }, }; use rustc_middle as mid; @@ -12,11 +12,14 @@ use crate::conversion::marker::MarkerConverterInner; impl<'ast, 'tcx> MarkerConverterInner<'ast, 'tcx> { #[must_use] pub fn to_sem_ty(&self, rustc_ty: mid::ty::Ty<'tcx>) -> TyKind<'ast> { + let data = sem::CommonTyData::builder() + .driver_id(self.to_driver_ty_id(rustc_ty)) + .build(); + // Semantic types could be cached, the question is if they should and at // which level. match &rustc_ty.kind() { - mid::ty::TyKind::Bool => TyKind::Bool(self.alloc(BoolTy::new())), - mid::ty::TyKind::Char => TyKind::Text(self.alloc(TextTy::new(TextKind::Char))), + mid::ty::TyKind::Bool => TyKind::Bool(self.alloc(BoolTy::builder().data(data).build())), mid::ty::TyKind::Int(int_ty) => { let num_ty = match int_ty { mid::ty::IntTy::Isize => NumKind::Isize, @@ -26,7 +29,7 @@ impl<'ast, 'tcx> MarkerConverterInner<'ast, 'tcx> { mid::ty::IntTy::I64 => NumKind::I64, mid::ty::IntTy::I128 => NumKind::I128, }; - TyKind::Num(self.alloc(NumTy::new(num_ty))) + TyKind::Num(self.alloc(NumTy::builder().data(data).numeric_kind(num_ty).build())) }, mid::ty::TyKind::Uint(uint_ty) => { let num_ty = match uint_ty { @@ -37,70 +40,133 @@ impl<'ast, 'tcx> MarkerConverterInner<'ast, 'tcx> { mid::ty::UintTy::U64 => NumKind::U64, mid::ty::UintTy::U128 => NumKind::U128, }; - TyKind::Num(self.alloc(NumTy::new(num_ty))) + TyKind::Num(self.alloc(NumTy::builder().data(data).numeric_kind(num_ty).build())) }, mid::ty::TyKind::Float(float_ty) => { let num_ty = match float_ty { mid::ty::FloatTy::F32 => NumKind::F32, mid::ty::FloatTy::F64 => NumKind::F64, }; - TyKind::Num(self.alloc(NumTy::new(num_ty))) + TyKind::Num(self.alloc(NumTy::builder().data(data).numeric_kind(num_ty).build())) + }, + mid::ty::TyKind::Char => { + TyKind::Text(self.alloc(TextTy::builder().data(data).textual_kind(TextKind::Char).build())) }, - mid::ty::TyKind::Str => TyKind::Text(self.alloc(TextTy::new(TextKind::Str))), - mid::ty::TyKind::Adt(def, generics) => TyKind::Adt(self.alloc(AdtTy::new( - self.to_ty_def_id(def.did()), - self.to_sem_generic_args(generics), - ))), + mid::ty::TyKind::Str => { + TyKind::Text(self.alloc(TextTy::builder().data(data).textual_kind(TextKind::Str).build())) + }, + mid::ty::TyKind::Adt(def, generics) => TyKind::Adt( + self.alloc( + AdtTy::builder() + .data(data) + .def_id(self.to_ty_def_id(def.did())) + .generics(self.to_sem_generic_args(generics)) + .build(), + ), + ), mid::ty::TyKind::Foreign(_) => { todo!("foreign type are currently sadly not supported. See rust-marker/marker#182") }, - mid::ty::TyKind::Array(inner, _len) => { - TyKind::Array(self.alloc(ArrayTy::new(self.to_sem_ty(*inner), ConstValue::new()))) - }, - mid::ty::TyKind::Slice(inner) => TyKind::Slice(self.alloc(SliceTy::new(self.to_sem_ty(*inner)))), - mid::ty::TyKind::Tuple(ty_lst) => TyKind::Tuple(self.alloc(TupleTy::new( - self.alloc_slice(ty_lst.iter().map(|ty| self.to_sem_ty(ty))), - ))), - mid::ty::TyKind::RawPtr(ty_and_mut) => TyKind::RawPtr(self.alloc(RawPtrTy::new( - self.to_mutability(ty_and_mut.mutbl), - self.to_sem_ty(ty_and_mut.ty), - ))), - mid::ty::TyKind::Ref(_lifetime, inner, muta) => { - TyKind::Ref(self.alloc(RefTy::new(self.to_mutability(*muta), self.to_sem_ty(*inner)))) + mid::ty::TyKind::Array(inner, _len) => TyKind::Array( + self.alloc( + ArrayTy::builder() + .data(data) + .inner_ty(self.to_sem_ty(*inner)) + .len(ConstValue::new()) + .build(), + ), + ), + mid::ty::TyKind::Slice(inner) => { + TyKind::Slice(self.alloc(SliceTy::builder().data(data).inner_ty(self.to_sem_ty(*inner)).build())) }, - mid::ty::TyKind::FnDef(fn_id, generic_args) => TyKind::FnTy(self.alloc(FnTy::new( - self.to_item_id(*fn_id), - self.to_sem_generic_args(generic_args), - ))), + mid::ty::TyKind::Tuple(ty_lst) => TyKind::Tuple( + self.alloc( + TupleTy::builder() + .data(data) + .types(self.alloc_slice(ty_lst.iter().map(|ty| self.to_sem_ty(ty)))) + .build(), + ), + ), + mid::ty::TyKind::RawPtr(ty_and_mut) => TyKind::RawPtr( + self.alloc( + RawPtrTy::builder() + .data(data) + .mutability(self.to_mutability(ty_and_mut.mutbl)) + .inner_ty(self.to_sem_ty(ty_and_mut.ty)) + .build(), + ), + ), + mid::ty::TyKind::Ref(_lifetime, inner, muta) => TyKind::Ref( + self.alloc( + RefTy::builder() + .data(data) + .mutability(self.to_mutability(*muta)) + .inner_ty(self.to_sem_ty(*inner)) + .build(), + ), + ), + mid::ty::TyKind::FnDef(fn_id, generic_args) => TyKind::Fn( + self.alloc( + FnTy::builder() + .data(data) + .fn_id(self.to_item_id(*fn_id)) + .generics(self.to_sem_generic_args(generic_args)) + .build(), + ), + ), mid::ty::TyKind::FnPtr(fn_info) => TyKind::FnPtr( - self.alloc(FnPtrTy::new( - self.to_safety(fn_info.unsafety()), - self.to_abi(fn_info.abi()), - self.alloc_slice( - fn_info - .inputs() - .skip_binder() - .iter() - .map(|input| self.to_sem_ty(*input)), - ), - self.to_sem_ty(fn_info.output().skip_binder()), - )), + self.alloc( + FnPtrTy::builder() + .data(data) + .safety(self.to_safety(fn_info.unsafety())) + .abi(self.to_abi(fn_info.abi())) + .params( + self.alloc_slice( + fn_info + .inputs() + .skip_binder() + .iter() + .map(|input| self.to_sem_ty(*input)), + ), + ) + .return_ty(self.to_sem_ty(fn_info.output().skip_binder())) + .build(), + ), ), mid::ty::TyKind::Dynamic(binders, _region, kind) => { if !matches!(kind, mid::ty::DynKind::Dyn) { unimplemented!("the docs are not totally clear, when `DynStar` is used, her it is: {rustc_ty:#?}") } - TyKind::TraitObj(self.alloc(TraitObjTy::new(self.to_sem_trait_bounds(binders)))) + TyKind::TraitObj( + self.alloc( + TraitObjTy::builder() + .data(data) + .bounds(self.to_sem_trait_bounds(binders)) + .build(), + ), + ) }, - mid::ty::TyKind::Closure(id, generics) => TyKind::ClosureTy(self.alloc(ClosureTy::new( - self.to_ty_def_id(*id), - self.to_sem_generic_args(generics), - ))), + mid::ty::TyKind::Closure(id, generics) => TyKind::Closure( + self.alloc( + ClosureTy::builder() + .data(data) + .def_id(self.to_ty_def_id(*id)) + .generics(self.to_sem_generic_args(generics)) + .build(), + ), + ), mid::ty::TyKind::Coroutine(_, _, _) | mid::ty::TyKind::CoroutineWitness(_, _) => { - TyKind::Unstable(self.alloc(UnstableTy::new())) + TyKind::Unstable(self.alloc(UnstableTy::builder().data(data).build())) }, - mid::ty::TyKind::Never => TyKind::Never(self.alloc(NeverTy::new())), - mid::ty::TyKind::Alias(_, info) => TyKind::Alias(self.alloc(AliasTy::new(self.to_item_id(info.def_id)))), + mid::ty::TyKind::Never => TyKind::Never(self.alloc(NeverTy::builder().data(data).build())), + mid::ty::TyKind::Alias(_, info) => TyKind::Alias( + self.alloc( + AliasTy::builder() + .data(data) + .alias_item(self.to_item_id(info.def_id)) + .build(), + ), + ), mid::ty::TyKind::Param(param) => { let body_id = self .rustc_body @@ -114,7 +180,14 @@ impl<'ast, 'tcx> MarkerConverterInner<'ast, 'tcx> { .rustc_cx .generics_of(owner.to_def_id()) .type_param(param, self.rustc_cx); - TyKind::Generic(self.alloc(GenericTy::new(self.to_generic_id(generic_info.def_id)))) + TyKind::Generic( + self.alloc( + GenericTy::builder() + .data(data) + .generic_id(self.to_generic_id(generic_info.def_id)) + .build(), + ), + ) }, mid::ty::TyKind::Bound(_, _) => { unreachable!("used by rustc for higher ranked types, which are not represented in marker") diff --git a/marker_rustc_driver/src/conversion/rustc/common.rs b/marker_rustc_driver/src/conversion/rustc/common.rs index 4b55c0a0..4b96a33b 100644 --- a/marker_rustc_driver/src/conversion/rustc/common.rs +++ b/marker_rustc_driver/src/conversion/rustc/common.rs @@ -1,12 +1,13 @@ use std::mem::{size_of, transmute}; use marker_api::{ - common::{CrateId, ExpnId, Level, SpanId, SpanSrcId, SymbolId}, + common::{CrateId, DriverTyId, ExpnId, Level, SpanId, SpanSrcId, SymbolId}, diagnostic::Applicability, prelude::*, span::SpanPos, }; use rustc_hir as hir; +use rustc_middle as mid; use crate::conversion::common::{BodyIdLayout, DefIdInfo, DefIdLayout, ExpnIdLayout, HirIdLayout}; use crate::transmute_id; @@ -159,11 +160,18 @@ impl<'ast, 'tcx> RustcConverter<'ast, 'tcx> { #[must_use] pub fn to_syntax_context(&self, src: SpanSrcId) -> rustc_span::SyntaxContext { - // FIXME(xFrednet): This is unsound, since `SyntaxContext` doesn't have + // FIXME(xFrednet): This is theoretically unsound, since `SyntaxContext` doesn't have // `#[repr(...)]`. See comment in `MarkerConverterInner::to_span_src_id` transmute_id!(SpanSrcId as rustc_span::SyntaxContext = src) } + #[must_use] + pub fn to_driver_ty_id(&self, id: DriverTyId) -> mid::ty::Ty<'tcx> { + // FIXME(xFrednet): This is theoretically unsound, but should be fine. + // See comment in `MarkerConverterInner::to_driver_ty_id` + transmute_id!(DriverTyId as mid::ty::Ty<'tcx> = id) + } + #[must_use] pub(crate) fn to_expn_id(&self, expn_id: ExpnId) -> rustc_span::ExpnId { let layout = transmute_id!(ExpnId as ExpnIdLayout = expn_id); diff --git a/marker_uilints/tests/ui/print_const_generics.stderr b/marker_uilints/tests/ui/print_const_generics.stderr index 5044e375..866afddf 100644 --- a/marker_uilints/tests/ui/print_const_generics.stderr +++ b/marker_uilints/tests/ui/print_const_generics.stderr @@ -216,6 +216,7 @@ warning: print type test | = note: Adt( AdtTy { + data: CommonTyData {...}, def_id: TyDefId(..), generics: GenericArgs { args: [ diff --git a/marker_uilints/tests/ui/print_semantic_ty.stderr b/marker_uilints/tests/ui/print_semantic_ty.stderr index 26483bbc..48450bb0 100644 --- a/marker_uilints/tests/ui/print_semantic_ty.stderr +++ b/marker_uilints/tests/ui/print_semantic_ty.stderr @@ -6,7 +6,7 @@ warning: print type test | = note: Alias( AliasTy { - _lifetime: PhantomData<&()>, + data: CommonTyData {...}, alias_item: ItemId(..), }, ) @@ -20,7 +20,7 @@ warning: print type test | = note: Alias( AliasTy { - _lifetime: PhantomData<&()>, + data: CommonTyData {...}, alias_item: ItemId(..), }, ) @@ -33,7 +33,7 @@ warning: print type test | = note: Num( NumTy { - _ast: PhantomData<&()>, + data: CommonTyData {...}, numeric_kind: U32, }, ) @@ -46,7 +46,7 @@ warning: print type test | = note: Num( NumTy { - _ast: PhantomData<&()>, + data: CommonTyData {...}, numeric_kind: U32, }, ) @@ -59,7 +59,7 @@ warning: print type test | = note: Generic( GenericTy { - _lifetime: PhantomData<&()>, + data: CommonTyData {...}, generic_id: GenericId(..), }, ) @@ -72,7 +72,7 @@ warning: print type test | = note: Num( NumTy { - _ast: PhantomData<&()>, + data: CommonTyData {...}, numeric_kind: U32, }, ) @@ -85,46 +85,48 @@ warning: print type test | = note: Adt( AdtTy { + data: CommonTyData {...}, def_id: TyDefId(..), generics: GenericArgs { args: [ Ty( Tuple( TupleTy { + data: CommonTyData {...}, types: [ Num( NumTy { - _ast: PhantomData<&()>, + data: CommonTyData {...}, numeric_kind: U8, }, ), Num( NumTy { - _ast: PhantomData<&()>, + data: CommonTyData {...}, numeric_kind: U16, }, ), Num( NumTy { - _ast: PhantomData<&()>, + data: CommonTyData {...}, numeric_kind: U32, }, ), Num( NumTy { - _ast: PhantomData<&()>, + data: CommonTyData {...}, numeric_kind: U64, }, ), Num( NumTy { - _ast: PhantomData<&()>, + data: CommonTyData {...}, numeric_kind: U128, }, ), Num( NumTy { - _ast: PhantomData<&()>, + data: CommonTyData {...}, numeric_kind: Usize, }, ), @@ -145,46 +147,48 @@ warning: print type test | = note: Adt( AdtTy { + data: CommonTyData {...}, def_id: TyDefId(..), generics: GenericArgs { args: [ Ty( Tuple( TupleTy { + data: CommonTyData {...}, types: [ Num( NumTy { - _ast: PhantomData<&()>, + data: CommonTyData {...}, numeric_kind: I8, }, ), Num( NumTy { - _ast: PhantomData<&()>, + data: CommonTyData {...}, numeric_kind: I16, }, ), Num( NumTy { - _ast: PhantomData<&()>, + data: CommonTyData {...}, numeric_kind: I32, }, ), Num( NumTy { - _ast: PhantomData<&()>, + data: CommonTyData {...}, numeric_kind: I64, }, ), Num( NumTy { - _ast: PhantomData<&()>, + data: CommonTyData {...}, numeric_kind: I128, }, ), Num( NumTy { - _ast: PhantomData<&()>, + data: CommonTyData {...}, numeric_kind: Isize, }, ), @@ -205,30 +209,32 @@ warning: print type test | = note: Adt( AdtTy { + data: CommonTyData {...}, def_id: TyDefId(..), generics: GenericArgs { args: [ Ty( Tuple( TupleTy { + data: CommonTyData {...}, types: [ Text( Char, ), Bool( BoolTy { - _lt: PhantomData<&()>, + data: CommonTyData {...}, }, ), Num( NumTy { - _ast: PhantomData<&()>, + data: CommonTyData {...}, numeric_kind: F32, }, ), Num( NumTy { - _ast: PhantomData<&()>, + data: CommonTyData {...}, numeric_kind: F64, }, ), @@ -249,9 +255,10 @@ warning: print type test | = note: Array( ArrayTy { + data: CommonTyData {...}, inner_ty: Num( NumTy { - _ast: PhantomData<&()>, + data: CommonTyData {...}, numeric_kind: U32, }, ), @@ -267,12 +274,13 @@ warning: print type test | = note: Ref( RefTy { + data: CommonTyData {...}, mutability: Unmut, inner_ty: Slice( [ Num( NumTy { - _ast: PhantomData<&()>, + data: CommonTyData {...}, numeric_kind: U32, }, ), @@ -289,15 +297,18 @@ warning: print type test | = note: Adt( AdtTy { + data: CommonTyData {...}, def_id: TyDefId(..), generics: GenericArgs { args: [ Ty( Tuple( TupleTy { + data: CommonTyData {...}, types: [ Ref( RefTy { + data: CommonTyData {...}, mutability: Unmut, inner_ty: Text( Str, @@ -306,10 +317,11 @@ warning: print type test ), RawPtr( RawPtrTy { + data: CommonTyData {...}, mutability: Unmut, inner_ty: Num( NumTy { - _ast: PhantomData<&()>, + data: CommonTyData {...}, numeric_kind: I32, }, ), @@ -317,10 +329,11 @@ warning: print type test ), RawPtr( RawPtrTy { + data: CommonTyData {...}, mutability: Mut, inner_ty: Num( NumTy { - _ast: PhantomData<&()>, + data: CommonTyData {...}, numeric_kind: I32, }, ), @@ -341,8 +354,9 @@ warning: print type test 62 | let _ty_fn_item: fn(u32) -> f32 = u32_to_f32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: FnTy( + = note: Fn( FnTy { + data: CommonTyData {...}, fn_id: ItemId(..), generics: GenericArgs { args: [], @@ -356,15 +370,16 @@ warning: print type test 63 | let _ty_closure = || x = 9; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: ClosureTy( + = note: Closure( ClosureTy { - closure_ty_id: TyDefId(..), + data: CommonTyData {...}, + def_id: TyDefId(..), generics: GenericArgs { args: [ Ty( Num( NumTy { - _ast: PhantomData<&()>, + data: CommonTyData {...}, numeric_kind: I16, }, ), @@ -372,17 +387,20 @@ warning: print type test Ty( FnPtr( FnPtrTy { + data: CommonTyData {...}, safety: Safe, abi: Other, params: [ Tuple( TupleTy { + data: CommonTyData {...}, types: [], }, ), ], return_ty: Tuple( TupleTy { + data: CommonTyData {...}, types: [], }, ), @@ -392,13 +410,15 @@ warning: print type test Ty( Tuple( TupleTy { + data: CommonTyData {...}, types: [ Ref( RefTy { + data: CommonTyData {...}, mutability: Mut, inner_ty: Num( NumTy { - _ast: PhantomData<&()>, + data: CommonTyData {...}, numeric_kind: I32, }, ), @@ -421,19 +441,20 @@ warning: print type test | = note: FnPtr( FnPtrTy { + data: CommonTyData {...}, safety: Safe, abi: Default, params: [ Num( NumTy { - _ast: PhantomData<&()>, + data: CommonTyData {...}, numeric_kind: U32, }, ), ], return_ty: Num( NumTy { - _ast: PhantomData<&()>, + data: CommonTyData {...}, numeric_kind: F32, }, ), @@ -448,13 +469,14 @@ warning: print type test | = note: Adt( AdtTy { + data: CommonTyData {...}, def_id: TyDefId(..), generics: GenericArgs { args: [ Ty( Num( NumTy { - _ast: PhantomData<&()>, + data: CommonTyData {...}, numeric_kind: U32, }, ), @@ -462,6 +484,7 @@ warning: print type test Ty( Adt( AdtTy { + data: CommonTyData {...}, def_id: TyDefId(..), generics: GenericArgs { args: [], @@ -482,6 +505,7 @@ warning: print type test | = note: Adt( AdtTy { + data: CommonTyData {...}, def_id: TyDefId(..), generics: GenericArgs { args: [], @@ -497,19 +521,22 @@ warning: print type test | = note: Adt( AdtTy { + data: CommonTyData {...}, def_id: TyDefId(..), generics: GenericArgs { args: [ Ty( Adt( AdtTy { + data: CommonTyData {...}, def_id: TyDefId(..), generics: GenericArgs { args: [ Ty( TraitObj( TraitObjTy { - bound: [ + data: CommonTyData {...}, + bounds: [ TraitBound { is_relaxed: false, trait_id: TyDefId(..), @@ -524,6 +551,7 @@ warning: print type test Ty( Adt( AdtTy { + data: CommonTyData {...}, def_id: TyDefId(..), generics: GenericArgs { args: [], @@ -549,19 +577,22 @@ warning: print type test | = note: Adt( AdtTy { + data: CommonTyData {...}, def_id: TyDefId(..), generics: GenericArgs { args: [ Ty( Adt( AdtTy { + data: CommonTyData {...}, def_id: TyDefId(..), generics: GenericArgs { args: [ Ty( TraitObj( TraitObjTy { - bound: [ + data: CommonTyData {...}, + bounds: [ TraitBound { is_relaxed: false, trait_id: TyDefId(..), @@ -572,7 +603,7 @@ warning: print type test binding_target: ItemId(..), ty: Num( NumTy { - _ast: PhantomData<&()>, + data: CommonTyData {...}, numeric_kind: I32, }, ), @@ -588,6 +619,7 @@ warning: print type test Ty( Adt( AdtTy { + data: CommonTyData {...}, def_id: TyDefId(..), generics: GenericArgs { args: [],