Skip to content

Commit

Permalink
Replace TypeInfo::SelfType with a generic type parameter (#4962)
Browse files Browse the repository at this point in the history
## Description

Fixes #4877

## Tasks

- [x] Make a simple example with a trait and an impl for it compile
- [x] Fix typechecking for empty enums
- [x] Fix typechecking for trait impl methods
- [x] Fix typechecking for impl self blocks
- [x] Fix the case of non-implemented supertraits
- [x] Fix typechecking of generic traits
- [x] Fix typechecking of generic impl self blocks
- [x] Resolve ambiguity between term/path-level `Self` and the
type-level `Self` type parameter (related PR #4459):
       - [x] enums
       - [x] structs (deferred as issue #5164)
- [x] Fix `Self` for type constraints
- [x] Fix looping during insertion of trait constraints for generic
tuples (inserted `occurs_check` to prevent unification of a generic `A`
with a tuple `(A, A)`;
- [x] Fix exponential growth of the traits map (around 30 tests out of
more than 680 are failing now); related PR: #5004
- [x] Fix `Self` type for blanket implementations
- [x] Fix `Self` for associated consts
- [x] Fix name resolution issues for some tests with traits (like
`should_pass/language/eq_intrinsic`); blocking issues:
       - #5018 
       - #5036
- [x] Fix `should_fail/generic_traits` test
- [x] Fix `should_pass/language/where_clause_impls` test
- [x] Fix `should_pass/language/name_resolution_inside_intrinsics` test
- [x] Remove some commented out code in `impl_trait.rs`
- [x] Comment new code
- [x] **Disable** `should_pass/language/associated_type_container` test
- [x] **Disable** `should_pass/language/associated_type_method` test
- [x] **Disable**
`should_pass/language/associated_type_and_associated_const` test
- [x] **Disable** `should_pass/language/associated_type_iterator` test

## Checklist

- [x] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [x] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [x] I have added tests that prove my fix is effective or that my
feature works.
- [x] 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.

---------

Co-authored-by: Joshua Batty <joshpbatty@gmail.com>
Co-authored-by: IGI-111 <igi-111@protonmail.com>
  • Loading branch information
3 people authored Oct 3, 2023
1 parent 32582e0 commit 4636a93
Show file tree
Hide file tree
Showing 73 changed files with 548 additions and 1,211 deletions.
3 changes: 0 additions & 3 deletions forc-plugins/forc-doc/src/render/item/type_anchor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,6 @@ pub(crate) fn render_type_anchor(
TypeInfo::Custom { call_path, .. } => Ok(box_html! {
: call_path.suffix.as_str();
}),
TypeInfo::SelfType => Ok(box_html! {
: "Self";
}),
TypeInfo::B256 => Ok(box_html! {
: "b256";
}),
Expand Down
1 change: 0 additions & 1 deletion sway-core/src/abi_generation/evm_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ pub fn abi_str(type_info: &TypeInfo, type_engine: &TypeEngine, decl_engine: &Dec
.collect::<Vec<String>>();
format!("({})", field_strs.join(", "))
}
SelfType => "Self".into(),
B256 => "uint256".into(),
Numeric => "u64".into(), // u64 is the default
Contract => "contract".into(),
Expand Down
1 change: 0 additions & 1 deletion sway-core/src/abi_generation/fuel_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -807,7 +807,6 @@ impl TypeInfo {
.collect::<Vec<String>>();
format!("({})", field_strs.join(", "))
}
SelfType => "Self".into(),
B256 => "b256".into(),
Numeric => "u64".into(), // u64 is the default
Contract => "contract".into(),
Expand Down
8 changes: 4 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 @@ -922,10 +922,10 @@ fn connect_typed_fn_decl<'eng: 'cfg, 'cfg>(
for fn_param in fn_decl.parameters.iter() {
let fn_param_node = graph.add_node(ControlFlowGraphNode::FunctionParameter {
param_name: fn_param.name.clone(),
is_self: matches!(
type_engine.get(fn_param.type_argument.initial_type_id),
TypeInfo::SelfType
),
is_self: engines
.te()
.get(fn_param.type_argument.initial_type_id)
.is_self_type(),
});
graph.add_edge(entry_node, fn_param_node, "".into());

Expand Down
66 changes: 1 addition & 65 deletions sway-core/src/decl_engine/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ impl SubstTypes for DeclId<TyTypeAliasDecl> {
decl_engine.replace(*self, decl);
}
}

impl SubstTypes for DeclId<TyTraitType> {
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) {
let decl_engine = engines.de();
Expand All @@ -142,68 +143,3 @@ impl SubstTypes for DeclId<TyTraitType> {
decl_engine.replace(*self, decl);
}
}

impl ReplaceSelfType for DeclId<TyFunctionDecl> {
fn replace_self_type(&mut self, engines: &Engines, self_type: TypeId) {
let decl_engine = engines.de();
let mut decl = decl_engine.get(self);
decl.replace_self_type(engines, self_type);
decl_engine.replace(*self, decl);
}
}
impl ReplaceSelfType for DeclId<TyTraitDecl> {
fn replace_self_type(&mut self, engines: &Engines, self_type: TypeId) {
let decl_engine = engines.de();
let mut decl = decl_engine.get(self);
decl.replace_self_type(engines, self_type);
decl_engine.replace(*self, decl);
}
}
impl ReplaceSelfType for DeclId<TyTraitFn> {
fn replace_self_type(&mut self, engines: &Engines, self_type: TypeId) {
let decl_engine = engines.de();
let mut decl = decl_engine.get(self);
decl.replace_self_type(engines, self_type);
decl_engine.replace(*self, decl);
}
}
impl ReplaceSelfType for DeclId<TyImplTrait> {
fn replace_self_type(&mut self, engines: &Engines, self_type: TypeId) {
let decl_engine = engines.de();
let mut decl = decl_engine.get(self);
decl.replace_self_type(engines, self_type);
decl_engine.replace(*self, decl);
}
}
impl ReplaceSelfType for DeclId<TyStructDecl> {
fn replace_self_type(&mut self, engines: &Engines, self_type: TypeId) {
let decl_engine = engines.de();
let mut decl = decl_engine.get(self);
decl.replace_self_type(engines, self_type);
decl_engine.replace(*self, decl);
}
}
impl ReplaceSelfType for DeclId<TyEnumDecl> {
fn replace_self_type(&mut self, engines: &Engines, self_type: TypeId) {
let decl_engine = engines.de();
let mut decl = decl_engine.get(self);
decl.replace_self_type(engines, self_type);
decl_engine.replace(*self, decl);
}
}
impl ReplaceSelfType for DeclId<TyTypeAliasDecl> {
fn replace_self_type(&mut self, engines: &Engines, self_type: TypeId) {
let decl_engine = engines.de();
let mut decl = decl_engine.get(self);
decl.replace_self_type(engines, self_type);
decl_engine.replace(*self, decl);
}
}
impl ReplaceSelfType for DeclId<TyTraitType> {
fn replace_self_type(&mut self, engines: &Engines, self_type: TypeId) {
let decl_engine = engines.de();
let mut decl = decl_engine.get(self);
decl.replace_self_type(engines, self_type);
decl_engine.replace(*self, decl);
}
}
10 changes: 10 additions & 0 deletions sway-core/src/decl_engine/mapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,16 @@ impl fmt::Debug for DeclMapping {
}

impl DeclMapping {
pub(crate) fn new() -> Self {
Self {
mapping: Vec::new(),
}
}

pub(crate) fn insert(&mut self, k: SourceDecl, v: DestinationDecl) {
self.mapping.push((k, v))
}

pub(crate) fn is_empty(&self) -> bool {
self.mapping.is_empty()
}
Expand Down
51 changes: 2 additions & 49 deletions sway-core/src/decl_engine/ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,22 +119,6 @@ where
decl_engine.insert(decl)
}
}
impl<T> DeclRef<DeclId<T>>
where
DeclEngine: DeclEngineIndex<T>,
T: Named + Spanned + ReplaceSelfType,
{
pub(crate) fn replace_self_type_and_insert_new(
&self,
engines: &Engines,
self_type: TypeId,
) -> Self {
let decl_engine = engines.de();
let mut decl = decl_engine.get(&self.id);
decl.replace_self_type(engines, self_type);
decl_engine.insert(decl)
}
}

impl<T> DeclRef<DeclId<T>>
where
Expand Down Expand Up @@ -170,30 +154,12 @@ where
.with_parent(decl_engine, self.id.into())
}
}

impl<T> DeclRef<DeclId<T>>
where
AssociatedItemDeclId: From<DeclId<T>>,
DeclEngine: DeclEngineIndex<T>,
T: Named + Spanned + ReplaceSelfType,
{
pub(crate) fn replace_self_type_and_insert_new_with_parent(
&self,
engines: &Engines,
self_type: TypeId,
) -> Self {
let decl_engine = engines.de();
let mut decl = decl_engine.get(&self.id);
decl.replace_self_type(engines, self_type);
decl_engine
.insert(decl)
.with_parent(decl_engine, self.id.into())
}
}
impl<T> DeclRef<DeclId<T>>
where
AssociatedItemDeclId: From<DeclId<T>>,
DeclEngine: DeclEngineIndex<T>,
T: Named + Spanned + ReplaceDecls,
T: Named + Spanned + ReplaceDecls + std::fmt::Debug,
{
pub(crate) fn replace_decls_and_insert_new_with_parent(
&self,
Expand Down Expand Up @@ -324,19 +290,6 @@ where
}
}

impl<T> ReplaceSelfType for DeclRef<DeclId<T>>
where
DeclEngine: DeclEngineIndex<T>,
T: Named + Spanned + ReplaceSelfType,
{
fn replace_self_type(&mut self, engines: &Engines, self_type: TypeId) {
let decl_engine = engines.de();
let mut decl = decl_engine.get(&self.id);
decl.replace_self_type(engines, self_type);
decl_engine.replace(self.id, decl);
}
}

impl ReplaceDecls for DeclRefFunction {
fn replace_decls_inner(
&mut self,
Expand Down
1 change: 0 additions & 1 deletion sway-core/src/ir_generation/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,6 @@ fn convert_resolved_type(
// Unsupported types which shouldn't exist in the AST after type checking and
// monomorphisation.
TypeInfo::Custom { .. } => reject_type!("Custom"),
TypeInfo::SelfType { .. } => reject_type!("Self"),
TypeInfo::Contract => reject_type!("Contract"),
TypeInfo::ContractCaller { .. } => reject_type!("ContractCaller"),
TypeInfo::Unknown => reject_type!("Unknown"),
Expand Down
18 changes: 0 additions & 18 deletions sway-core/src/language/ty/ast_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,24 +72,6 @@ impl SubstTypes for TyAstNode {
}
}

impl ReplaceSelfType for TyAstNode {
fn replace_self_type(&mut self, engines: &Engines, self_type: TypeId) {
match self.content {
TyAstNodeContent::ImplicitReturnExpression(ref mut exp) => {
exp.replace_self_type(engines, self_type)
}
TyAstNodeContent::Declaration(ref mut decl) => {
decl.replace_self_type(engines, self_type)
}
TyAstNodeContent::Expression(ref mut expr) => {
expr.replace_self_type(engines, self_type)
}
TyAstNodeContent::SideEffect(_) => (),
TyAstNodeContent::Error(_, _) => (),
}
}
}

impl ReplaceDecls for TyAstNode {
fn replace_decls_inner(
&mut self,
Expand Down
8 changes: 0 additions & 8 deletions sway-core/src/language/ty/code_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,6 @@ impl SubstTypes for TyCodeBlock {
}
}

impl ReplaceSelfType for TyCodeBlock {
fn replace_self_type(&mut self, engines: &Engines, self_type: TypeId) {
self.contents
.iter_mut()
.for_each(|x| x.replace_self_type(engines, self_type));
}
}

impl ReplaceDecls for TyCodeBlock {
fn replace_decls_inner(
&mut self,
Expand Down
10 changes: 0 additions & 10 deletions sway-core/src/language/ty/declaration/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,6 @@ impl SubstTypes for TyConstantDecl {
}
}

impl ReplaceSelfType for TyConstantDecl {
fn replace_self_type(&mut self, engines: &Engines, self_type: TypeId) {
self.return_type.replace_self_type(engines, self_type);
self.type_ascription.replace_self_type(engines, self_type);
if let Some(expr) = &mut self.value {
expr.replace_self_type(engines, self_type);
}
}
}

impl ReplaceDecls for TyConstantDecl {
fn replace_decls_inner(
&mut self,
Expand Down
50 changes: 10 additions & 40 deletions sway-core/src/language/ty/declaration/declaration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,46 +349,6 @@ impl SubstTypes for TyDecl {
}
}

impl ReplaceSelfType for TyDecl {
fn replace_self_type(&mut self, engines: &Engines, self_type: TypeId) {
match self {
TyDecl::VariableDecl(ref mut var_decl) => {
var_decl.replace_self_type(engines, self_type)
}
TyDecl::FunctionDecl(FunctionDecl {
ref mut decl_id, ..
}) => decl_id.replace_self_type(engines, self_type),
TyDecl::TraitDecl(TraitDecl {
ref mut decl_id, ..
}) => decl_id.replace_self_type(engines, self_type),
TyDecl::StructDecl(StructDecl {
ref mut decl_id, ..
}) => decl_id.replace_self_type(engines, self_type),
TyDecl::EnumDecl(EnumDecl {
ref mut decl_id, ..
}) => decl_id.replace_self_type(engines, self_type),
TyDecl::EnumVariantDecl(EnumVariantDecl {
ref mut enum_ref, ..
}) => enum_ref.replace_self_type(engines, self_type),
TyDecl::ImplTrait(ImplTrait {
ref mut decl_id, ..
}) => decl_id.replace_self_type(engines, self_type),
TyDecl::TypeAliasDecl(TypeAliasDecl {
ref mut decl_id, ..
}) => decl_id.replace_self_type(engines, self_type),
TyDecl::TraitTypeDecl(TraitTypeDecl {
ref mut decl_id, ..
}) => decl_id.replace_self_type(engines, self_type),
// generics in an ABI is unsupported by design
TyDecl::AbiDecl(_)
| TyDecl::ConstantDecl(_)
| TyDecl::StorageDecl(_)
| TyDecl::GenericTypeForFunctionScope(_)
| TyDecl::ErrorRecovery(..) => (),
}
}
}

impl TyDecl {
pub fn get_fun_decl_ref(&self) -> Option<DeclRefFunction> {
if let TyDecl::FunctionDecl(FunctionDecl {
Expand Down Expand Up @@ -613,6 +573,16 @@ impl TyDecl {
.get(ty.type_id)
.expect_enum(handler, engines, "", &span)
}
// `Self` type parameter might resolve to an Enum
TyDecl::GenericTypeForFunctionScope(GenericTypeForFunctionScope {
type_id, ..
}) => match engines.te().get(*type_id) {
TypeInfo::Enum(r) => Ok(r),
_ => Err(handler.emit_err(CompileError::DeclIsNotAnEnum {
actually: self.friendly_type_name().to_string(),
span: self.span(),
})),
},
TyDecl::ErrorRecovery(_, err) => Err(*err),
decl => Err(handler.emit_err(CompileError::DeclIsNotAnEnum {
actually: decl.friendly_type_name().to_string(),
Expand Down
21 changes: 4 additions & 17 deletions sway-core/src/language/ty/declaration/enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,17 +73,6 @@ impl SubstTypes for TyEnumDecl {
}
}

impl ReplaceSelfType for TyEnumDecl {
fn replace_self_type(&mut self, engines: &Engines, self_type: TypeId) {
self.variants
.iter_mut()
.for_each(|x| x.replace_self_type(engines, self_type));
self.type_parameters
.iter_mut()
.for_each(|x| x.replace_self_type(engines, self_type));
}
}

impl Spanned for TyEnumDecl {
fn span(&self) -> Span {
self.span.clone()
Expand All @@ -98,6 +87,10 @@ impl MonomorphizeHelper for TyEnumDecl {
fn name(&self) -> &Ident {
&self.call_path.suffix
}

fn has_self_type_param(&self) -> bool {
false
}
}

impl TyEnumDecl {
Expand Down Expand Up @@ -184,9 +177,3 @@ impl SubstTypes for TyEnumVariant {
self.type_argument.subst_inner(type_mapping, engines);
}
}

impl ReplaceSelfType for TyEnumVariant {
fn replace_self_type(&mut self, engines: &Engines, self_type: TypeId) {
self.type_argument.replace_self_type(engines, self_type);
}
}
Loading

0 comments on commit 4636a93

Please sign in to comment.