Skip to content

Commit

Permalink
Fixes unexpected trait dummy method error. (#5234)
Browse files Browse the repository at this point in the history
## Description

The unexpected trait dummy method error is now replaced by: `Trait
"MyTrait" is not implemented for type "u64".` This is the intended
behavior and now throws the equivalent of rust error.

This commit also adds some improvements to the `DebugWithEngines`.

Closes #5201

## 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: Igor Rončević <[email protected]>
Co-authored-by: IGI-111 <[email protected]>
  • Loading branch information
3 people authored Oct 30, 2023
1 parent f979b18 commit aee7926
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 2 deletions.
24 changes: 24 additions & 0 deletions sway-core/src/engine_threading.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,18 @@ impl<T: DisplayWithEngines> DisplayWithEngines for Box<T> {
}
}

impl<T: DisplayWithEngines> DisplayWithEngines for Vec<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>, engines: &Engines) -> fmt::Result {
let text = self
.iter()
.map(|e| format!("{}", engines.help_out(e)))
.collect::<Vec<_>>()
.join(", ")
.to_string();
f.write_str(&text)
}
}

pub(crate) trait DebugWithEngines {
fn fmt(&self, f: &mut fmt::Formatter<'_>, engines: &Engines) -> fmt::Result;
}
Expand All @@ -164,6 +176,18 @@ impl<T: DebugWithEngines> DebugWithEngines for Box<T> {
}
}

impl<T: DebugWithEngines> DebugWithEngines for Vec<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>, engines: &Engines) -> fmt::Result {
let text = self
.iter()
.map(|e| format!("{:?}", engines.help_out(e)))
.collect::<Vec<_>>()
.join(", ")
.to_string();
f.write_str(&text)
}
}

pub trait HashWithEngines {
fn hash<H: Hasher>(&self, state: &mut H, engines: &Engines);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -875,6 +875,29 @@ fn type_check_trait_implementation(
match item {
TyImplItem::Fn(decl_ref) => {
let mut method = decl_engine.get_function(decl_ref);

// We need to add impl type parameters to the method's type parameters
// so that in-line monomorphization can complete.
//
// We also need to add impl type parameters to the method's type
// parameters so the type constraints are correctly applied to the method.
//
// NOTE: this is a semi-hack that is used to force monomorphization of
// trait methods that contain a generic defined in the parent impl...
// without stuffing the generic into the method's type parameters, its
// not currently possible to monomorphize on that generic at function
// application time.
method.type_parameters.append(
&mut impl_type_parameters
.iter()
.cloned()
.map(|mut t| {
t.is_from_parent = true;
t
})
.collect::<Vec<_>>(),
);

method.replace_decls(&decl_mapping, handler, &mut ctx)?;
method.subst(&type_mapping, engines);
all_items_refs.push(TyImplItem::Fn(
Expand Down Expand Up @@ -1119,7 +1142,7 @@ fn type_check_impl_method(
);
}

// We need to add impl type parameters to the method's type parameters
// We need to add impl type parameters to the method's type parameters
// so that in-line monomorphization can complete.
//
// We also need to add impl type parameters to the method's type
Expand Down
2 changes: 1 addition & 1 deletion sway-core/src/type_system/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ impl DebugWithEngines for TypeInfo {
let s = match self {
Unknown => "unknown".into(),
UnknownGeneric { name, .. } => name.to_string(),
Placeholder(_) => "_".to_string(),
Placeholder(t) => format!("placeholder({:?})", engines.help_out(t)),
TypeParam(n) => format!("typeparam({n})"),
StringSlice => "str".into(),
StringArray(x) => format!("str[{}]", x.val()),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[[package]]
name = "trait_method_and_generic_trait_impl"
source = "member"
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[project]
authors = ["Fuel Labs <[email protected]>"]
entry = "main.sw"
license = "Apache-2.0"
name = "trait_method_and_generic_trait_impl"
implicit-std = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
script;

struct MyStruct<T> {
val: T
}

trait MyTrait {
fn foo(self, other: Self) -> bool;
} {
fn bar(self, other: Self) -> bool {
self.foo(other)
}
}

impl <T> MyTrait for MyStruct<T> where T: MyTrait {
fn foo(self, other: Self) -> bool {
self.val.foo(other.val)
}
}

fn main() -> bool {
let my_struct_1 = MyStruct { val: 5 };
let my_struct_2 = MyStruct { val: 9 };

// Calling foo() gives us the following expected error:
// Trait "MyTrait" is not implemented for type "u64".
my_struct_1.foo(my_struct_2);

// Calling bar() gives us the following expected error:
// Trait "MyTrait" is not implemented for type "u64".
my_struct_1.bar(my_struct_2);

true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
category = "fail"

# check: $()my_struct_1.foo(my_struct_2);
# nextln: $()Trait "MyTrait" is not implemented for type "u64".

# check: $()my_struct_1.bar(my_struct_2);
# nextln: $()Trait "MyTrait" is not implemented for type "u64".

0 comments on commit aee7926

Please sign in to comment.