Skip to content

Commit

Permalink
Cleanup DeclRef references from TypeInfo::Enum and `TypeInfo::Str…
Browse files Browse the repository at this point in the history
…uct` (#6178)

## Description

This cleans up `DeclRef` references from `TypeInfo::Enum` and
`TypeInfo::Struct`, which both will allows us to long-term get rid of
the unnecessary and unperformant `DeclRef` abstraction. I'm touching
this to allow subsequent usage of `ResolvedDeclaration` in its place in
a future PR, so decided to go ahead and do this cleanup while at it.

## Checklist

- [ ] I have linked to any relevant issues.
- [ ] I have commented my code, particularly in hard-to-understand
areas.
- [ ] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [ ] I have added tests that prove my fix is effective or that my
feature works.
- [ ] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.
  • Loading branch information
tritao authored Jun 25, 2024
1 parent 4608878 commit 3993f25
Show file tree
Hide file tree
Showing 22 changed files with 198 additions and 177 deletions.
22 changes: 11 additions & 11 deletions forc-plugins/forc-doc/src/render/item/type_anchor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{doc::module::ModuleInfo, RenderPlan};
use anyhow::{anyhow, Result};
use horrorshow::{box_html, RenderBox};
use sway_core::{AbiName, TypeInfo};
use sway_types::Spanned;
use sway_types::{Named, Spanned};

/// Handles types & nested types that should have links
/// eg. (`[]` represent types with links).
Expand Down Expand Up @@ -50,38 +50,38 @@ pub(crate) fn render_type_anchor(
: ")";
})
}
TypeInfo::Enum(decl_ref) => {
let enum_decl = render_plan.engines.de().get_enum(&decl_ref);
TypeInfo::Enum(decl_id) => {
let enum_decl = render_plan.engines.de().get_enum(&decl_id);
if !render_plan.document_private_items && enum_decl.visibility.is_private() {
Ok(box_html! {
: decl_ref.name().clone().as_str();
: enum_decl.name().clone().as_str();
})
} else {
let module_info = ModuleInfo::from_call_path(&enum_decl.call_path);
let file_name = format!("enum.{}.html", decl_ref.name().clone().as_str());
let file_name = format!("enum.{}.html", enum_decl.name().clone().as_str());
let href =
module_info.file_path_from_location(&file_name, current_module_info, false)?;
Ok(box_html! {
a(class="enum", href=href) {
: decl_ref.name().clone().as_str();
: enum_decl.name().clone().as_str();
}
})
}
}
TypeInfo::Struct(decl_ref) => {
let struct_decl = render_plan.engines.de().get_struct(&decl_ref);
TypeInfo::Struct(decl_id) => {
let struct_decl = render_plan.engines.de().get_struct(&decl_id);
if !render_plan.document_private_items && struct_decl.visibility.is_private() {
Ok(box_html! {
: decl_ref.name().clone().as_str();
: struct_decl.name().clone().as_str();
})
} else {
let module_info = ModuleInfo::from_call_path(&struct_decl.call_path);
let file_name = format!("struct.{}.html", decl_ref.name().clone().as_str());
let file_name = format!("struct.{}.html", struct_decl.name().clone().as_str());
let href =
module_info.file_path_from_location(&file_name, current_module_info, false)?;
Ok(box_html! {
a(class="struct", href=href) {
: decl_ref.name().clone().as_str();
: struct_decl.name().clone().as_str();
}
})
}
Expand Down
12 changes: 8 additions & 4 deletions sway-core/src/control_flow_analysis/dead_code_analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1580,11 +1580,15 @@ fn connect_expression<'eng: 'cfg, 'cfg>(
connect_code_block(engines, a, graph, leaves, exit_node, tree_type, options)
}
StructExpression {
struct_ref, fields, ..
struct_id, fields, ..
} => {
let decl = match graph.namespace.find_struct_decl(struct_ref.name().as_str()) {
let struct_decl = engines.de().get_struct(struct_id);
let decl = match graph
.namespace
.find_struct_decl(struct_decl.name().as_str())
{
Some(ix) => *ix,
None => graph.add_node(format!("External struct {}", struct_ref.name()).into()),
None => graph.add_node(format!("External struct {}", struct_decl.name()).into()),
};
let entry = graph.add_node("Struct declaration entry".into());
let exit = graph.add_node("Struct declaration exit".into());
Expand All @@ -1597,7 +1601,7 @@ fn connect_expression<'eng: 'cfg, 'cfg>(

// connect the struct fields to the struct if its requested as an option
if options.force_struct_fields_connection {
if let Some(ns) = graph.namespace.get_struct(struct_ref.name()).cloned() {
if let Some(ns) = graph.namespace.get_struct(struct_decl.name()).cloned() {
for (_, field_ix) in ns.fields.iter() {
graph.add_edge(decl, *field_ix, "".into());
}
Expand Down
55 changes: 55 additions & 0 deletions sway-core/src/decl_engine/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use std::hash::Hasher;
use std::marker::PhantomData;
use std::{fmt, hash::Hash};

use sway_types::{Named, Spanned};

use crate::language::ty::TyTraitType;
use crate::{
decl_engine::*,
Expand Down Expand Up @@ -96,6 +98,39 @@ impl<T> Into<usize> for DeclId<T> {
}
}

impl<T> EqWithEngines for DeclId<T>
where
DeclEngine: DeclEngineIndex<T>,
T: Named + Spanned + PartialEqWithEngines + EqWithEngines,
{
}

impl<T> PartialEqWithEngines for DeclId<T>
where
DeclEngine: DeclEngineIndex<T>,
T: Named + Spanned + PartialEqWithEngines,
{
fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
let decl_engine = ctx.engines().de();
let l_decl = decl_engine.get(self);
let r_decl = decl_engine.get(other);
l_decl.name() == r_decl.name() && l_decl.eq(&r_decl, ctx)
}
}

impl<T> HashWithEngines for DeclId<T>
where
DeclEngine: DeclEngineIndex<T>,
T: Named + Spanned + HashWithEngines,
{
fn hash<H: Hasher>(&self, state: &mut H, engines: &Engines) {
let decl_engine = engines.de();
let decl = decl_engine.get(self);
decl.name().hash(state);
decl.hash(state, engines);
}
}

impl SubstTypes for DeclId<TyFunctionDecl> {
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) -> HasChanges {
let decl_engine = engines.de();
Expand Down Expand Up @@ -193,3 +228,23 @@ impl SubstTypes for DeclId<TyTraitType> {
}
}
}

impl<T> DeclId<T>
where
DeclEngine: DeclEngineIndex<T>,
T: Named + Spanned + SubstTypes + Clone,
{
pub(crate) fn subst_types_and_insert_new(
&self,
type_mapping: &TypeSubstMap,
engines: &Engines,
) -> Option<DeclRef<Self>> {
let decl_engine = engines.de();
let mut decl = (*decl_engine.get(self)).clone();
if decl.subst(type_mapping, engines).has_changes() {
Some(decl_engine.insert(decl))
} else {
None
}
}
}
1 change: 1 addition & 0 deletions sway-core/src/decl_engine/ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ where
T: Named + Spanned + PartialEqWithEngines + EqWithEngines,
{
}

impl<T> PartialEqWithEngines for DeclRef<DeclId<T>>
where
DeclEngine: DeclEngineIndex<T>,
Expand Down
42 changes: 10 additions & 32 deletions sway-core/src/language/ty/declaration/declaration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -488,23 +488,16 @@ impl GetDeclIdent for TyDecl {
}

impl TyDecl {
/// Retrieves the declaration as a `DeclRef<DeclId<TyEnumDecl>>`.
/// Retrieves the declaration as a `DeclId<TyEnumDecl>`.
///
/// Returns an error if `self` is not the [TyDecl][EnumDecl] variant.
pub(crate) fn to_enum_ref(
pub(crate) fn to_enum_id(
&self,
handler: &Handler,
engines: &Engines,
) -> Result<DeclRefEnum, ErrorEmitted> {
) -> Result<DeclId<TyEnumDecl>, ErrorEmitted> {
match self {
TyDecl::EnumDecl(EnumDecl { decl_id }) => {
let enum_decl = engines.de().get_enum(decl_id);
Ok(DeclRef::new(
enum_decl.name().clone(),
*decl_id,
enum_decl.span.clone(),
))
}
TyDecl::EnumDecl(EnumDecl { decl_id }) => Ok(*decl_id),
TyDecl::TypeAliasDecl(TypeAliasDecl { decl_id, .. }) => {
let alias_decl = engines.de().get_type_alias(decl_id);
let TyTypeAliasDecl { ty, span, .. } = &*alias_decl;
Expand All @@ -517,7 +510,7 @@ impl TyDecl {
TyDecl::GenericTypeForFunctionScope(GenericTypeForFunctionScope {
type_id, ..
}) => match &*engines.te().get(*type_id) {
TypeInfo::Enum(r) => Ok(r.clone()),
TypeInfo::Enum(r) => Ok(*r),
_ => Err(handler.emit_err(CompileError::DeclIsNotAnEnum {
actually: self.friendly_type_name().to_string(),
span: self.span(engines),
Expand All @@ -534,20 +527,13 @@ impl TyDecl {
/// Retrieves the declaration as a `DeclRef<DeclId<TyStructDecl>>`.
///
/// Returns an error if `self` is not the [TyDecl][StructDecl] variant.
pub(crate) fn to_struct_ref(
pub(crate) fn to_struct_id(
&self,
handler: &Handler,
engines: &Engines,
) -> Result<DeclRefStruct, ErrorEmitted> {
) -> Result<DeclId<TyStructDecl>, ErrorEmitted> {
match self {
TyDecl::StructDecl(StructDecl { decl_id }) => {
let struct_decl = engines.de().get_struct(decl_id);
Ok(DeclRef::new(
struct_decl.name().clone(),
*decl_id,
struct_decl.span.clone(),
))
}
TyDecl::StructDecl(StructDecl { decl_id }) => Ok(*decl_id),
TyDecl::TypeAliasDecl(TypeAliasDecl { decl_id, .. }) => {
let alias_decl = engines.de().get_type_alias(decl_id);
let TyTypeAliasDecl { ty, span, .. } = &*alias_decl;
Expand Down Expand Up @@ -729,23 +715,15 @@ impl TyDecl {
let decl = decl_engine.get_struct(decl_id);
type_engine.insert(
engines,
TypeInfo::Struct(DeclRef::new(
decl.name().clone(),
*decl_id,
decl.span.clone(),
)),
TypeInfo::Struct(*decl_id),
decl.name().span().source_id(),
)
}
TyDecl::EnumDecl(EnumDecl { decl_id }) => {
let decl = decl_engine.get_enum(decl_id);
type_engine.insert(
engines,
TypeInfo::Enum(DeclRef::new(
decl.name().clone(),
*decl_id,
decl.span.clone(),
)),
TypeInfo::Enum(*decl_id),
decl.name().span().source_id(),
)
}
Expand Down
14 changes: 7 additions & 7 deletions sway-core/src/language/ty/expression/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,10 @@ impl CollectTypesMetadata for TyExpression {
StructExpression {
fields,
instantiation_span,
struct_ref,
struct_id,
..
} => {
let struct_decl = decl_engine.get_struct(struct_ref);
let struct_decl = decl_engine.get_struct(struct_id);
for type_parameter in &struct_decl.type_parameters {
ctx.call_site_insert(type_parameter.type_id, instantiation_span.clone());
}
Expand Down Expand Up @@ -388,13 +388,13 @@ impl TyExpression {

match &self.expression {
TyExpressionVariant::StructExpression {
struct_ref,
struct_id,
instantiation_span,
..
} => {
let s = engines.de().get(struct_ref.id());
let struct_decl = engines.de().get(struct_id);
emit_warning_if_deprecated(
&s.attributes,
&struct_decl.attributes,
instantiation_span,
handler,
"deprecated struct",
Expand All @@ -406,8 +406,8 @@ impl TyExpression {
} => {
if let Some(TyDecl::ImplTrait(t)) = &engines.de().get(fn_ref).implementing_type {
let t = &engines.de().get(&t.decl_id).implementing_for;
if let TypeInfo::Struct(struct_ref) = &*engines.te().get(t.type_id) {
let s = engines.de().get(struct_ref.id());
if let TypeInfo::Struct(struct_id) = &*engines.te().get(t.type_id) {
let s = engines.de().get(struct_id);
emit_warning_if_deprecated(
&s.attributes,
&call_path.span(),
Expand Down
27 changes: 15 additions & 12 deletions sway-core/src/language/ty/expression/expression_variant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ pub enum TyExpressionVariant {
index: Box<TyExpression>,
},
StructExpression {
struct_ref: DeclRef<DeclId<TyStructDecl>>,
struct_id: DeclId<TyStructDecl>,
fields: Vec<TyStructExpressionField>,
instantiation_span: Span,
call_path_binding: TypeBinding<CallPath>,
Expand Down Expand Up @@ -265,19 +265,21 @@ impl PartialEqWithEngines for TyExpressionVariant {
) => (**l_prefix).eq(&**r_prefix, ctx) && (**l_index).eq(&**r_index, ctx),
(
Self::StructExpression {
struct_ref: l_struct_ref,
struct_id: l_struct_id,
fields: l_fields,
instantiation_span: l_span,
call_path_binding: _,
},
Self::StructExpression {
struct_ref: r_struct_ref,
struct_id: r_struct_id,
fields: r_fields,
instantiation_span: r_span,
call_path_binding: _,
},
) => {
l_struct_ref.eq(r_struct_ref, ctx) && l_fields.eq(r_fields, ctx) && l_span == r_span
PartialEqWithEngines::eq(&l_struct_id, &r_struct_id, ctx)
&& l_fields.eq(r_fields, ctx)
&& l_span == r_span
}
(Self::CodeBlock(l0), Self::CodeBlock(r0)) => l0.eq(r0, ctx),
(
Expand Down Expand Up @@ -499,14 +501,14 @@ impl HashWithEngines for TyExpressionVariant {
index.hash(state, engines);
}
Self::StructExpression {
struct_ref,
struct_id,
fields,
// these fields are not hashed because they aren't relevant/a
// reliable source of obj v. obj distinction
instantiation_span: _,
call_path_binding: _,
} => {
struct_ref.hash(state, engines);
HashWithEngines::hash(&struct_id, state, engines);
fields.hash(state, engines);
}
Self::CodeBlock(contents) => {
Expand Down Expand Up @@ -683,15 +685,15 @@ impl SubstTypes for TyExpressionVariant {
index.subst(type_mapping, engines);
},
StructExpression {
struct_ref,
struct_id,
fields,
instantiation_span: _,
call_path_binding: _,
} => has_changes! {
if let Some(new_struct_ref) = struct_ref
if let Some(new_struct_ref) = struct_id
.clone()
.subst_types_and_insert_new(type_mapping, engines) {
struct_ref.replace_id(*new_struct_ref.id());
struct_id.replace_id(*new_struct_ref.id());
HasChanges::Yes
} else {
HasChanges::No
Expand Down Expand Up @@ -893,7 +895,7 @@ impl ReplaceDecls for TyExpressionVariant {
Ok(has_changes)
}
StructExpression {
struct_ref: _,
struct_id: _,
fields,
instantiation_span: _,
call_path_binding: _,
Expand Down Expand Up @@ -1412,8 +1414,9 @@ impl DebugWithEngines for TyExpressionVariant {
}
TyExpressionVariant::Array { .. } => "array".into(),
TyExpressionVariant::ArrayIndex { .. } => "[..]".into(),
TyExpressionVariant::StructExpression { struct_ref, .. } => {
format!("\"{}\" struct init", struct_ref.name().as_str())
TyExpressionVariant::StructExpression { struct_id, .. } => {
let decl = engines.de().get(struct_id);
format!("\"{}\" struct init", decl.name().as_str())
}
TyExpressionVariant::CodeBlock(_) => "code block entry".into(),
TyExpressionVariant::FunctionParameter => "fn param access".into(),
Expand Down
Loading

0 comments on commit 3993f25

Please sign in to comment.