Skip to content

Commit

Permalink
Fixes dummy method while using where clause in trait impl. (#5684)
Browse files Browse the repository at this point in the history
## Description

When using nested generic methods, as in the use case added, the lower
method would not be properly replaced and would remain as a trait dummy
method.

The fix was to do find_method_for_type in the ReplaceDecls of
FunctionAplication, this allows the replacement of the function
application dummy method with a proper method implementation.

Fixes #5673


## Checklist

- [x] I have linked to any relevant issues.
- [x] 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).
- [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.
  • Loading branch information
esdrubal committed Mar 4, 2024
1 parent 0c03ce0 commit 6ee40a3
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 0 deletions.
25 changes: 25 additions & 0 deletions sway-core/src/language/ty/expression/expression_variant.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::{
collections::VecDeque,
fmt::{self, Write},
hash::{Hash, Hasher},
};
Expand All @@ -11,6 +12,7 @@ use crate::{
decl_engine::*,
engine_threading::*,
language::{ty::*, *},
namespace::TryInsertingTraitImplOnFailure,
semantic_analysis::{
TyNodeDepGraphEdge, TyNodeDepGraphEdgeInfo, TypeCheckAnalysis, TypeCheckAnalysisContext,
TypeCheckContext, TypeCheckFinalization, TypeCheckFinalizationContext,
Expand Down Expand Up @@ -822,6 +824,29 @@ impl ReplaceDecls for TyExpressionVariant {
let decl_engine = ctx.engines().de();
let mut method = (*decl_engine.get(fn_ref)).clone();

// Finds method implementation for method dummy and replaces it.
// This is required because dummy methods don't have type parameters from impl traits.
// Thus we use the implementated method that already contains all the required type parameters,
// including those from the impl trait.
if method.is_trait_method_dummy {
if let Some(implementing_for_typeid) = method.implementing_for_typeid {
let implementing_type_method_ref = ctx.find_method_for_type(
handler,
implementing_for_typeid,
&[],
method.name(),
method.return_type.type_id,
&arguments
.iter()
.map(|a| a.1.return_type)
.collect::<VecDeque<_>>(),
None,
TryInsertingTraitImplOnFailure::Yes,
)?;
method = (*decl_engine.get(&implementing_type_method_ref)).clone();
}
}

// Handle the trait constraints. This includes checking to see if the trait
// constraints are satisfied and replacing old decl ids based on the
let inner_decl_mapping =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[[package]]
name = "core"
source = "path+from-root-0E536E049C0227B9"

[[package]]
name = "dummy_method_issue"
source = "member"
dependencies = ["core"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[project]
authors = ["Fuel Labs <contact@fuel.sh>"]
license = "Apache-2.0"
name = "dummy_method_issue"
entry = "main.sw"

[dependencies]
core = { path = "../../../../../../../sway-lib-core" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
script;

trait AbiEncode2 {
fn abi_encode2(self, ref mut buffer: Buffer);
}

impl AbiEncode2 for u64 { fn abi_encode2(self, ref mut buffer: Buffer) { } }
impl AbiEncode2 for u32 { fn abi_encode2(self, ref mut buffer: Buffer) { } }

struct GenericBimbam<U> {
val: U,
}

impl<U> AbiEncode2 for GenericBimbam<U> where U: AbiEncode2
{
fn abi_encode2(self, ref mut buffer: Buffer) {
self.val.abi_encode2(buffer);
}
}

struct GenericSnack<T, V> {
twix: GenericBimbam<T>,
mars: V,
}

impl<T, V> AbiEncode2 for GenericSnack<T, V> where T: AbiEncode2, V: AbiEncode2
{
fn abi_encode2(self, ref mut buffer: Buffer) {
self.twix.abi_encode2(buffer);
self.mars.abi_encode2(buffer);
}
}

fn encode2<T>(item: T) -> raw_slice where T: AbiEncode2 {
let mut buffer = Buffer::new();
item.abi_encode2(buffer);
buffer.as_raw_slice()
}

fn main() {
encode2(GenericSnack { twix: GenericBimbam { val: 2u64 }, mars: 2u32 });
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
category = "run"
expected_result = { action = "return", value = 0 }
validate_abi = false
expected_warnings = 7

0 comments on commit 6ee40a3

Please sign in to comment.