Skip to content

Commit

Permalink
Fixes error while using From trait that returns a tuple.
Browse files Browse the repository at this point in the history
Instead of `Trait "MyFrom<u256>" is not implemented for type "U".`
We now get `Trait "MyFrom<u256>" is not implemented for type "(_, _, _, _)".`

The error is followed by:
`Cannot infer type for type parameter "_". Insufficient type information provided. Try annotating its type.`

While Rust compiler is able to inference the type in this situation
it is non trivial to do it properly hence we should probably keep asking
for the type to be annotated.
  • Loading branch information
esdrubal committed Jan 16, 2024
1 parent 813ef65 commit 8eb448f
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 30 deletions.
52 changes: 22 additions & 30 deletions sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3483,36 +3483,6 @@ fn statement_let_to_ast_nodes(

let tuple_name = Ident::new_with_override(tuple_name, span.clone());

// Parse the type ascription and the type ascription span.
// In the event that the user did not provide a type ascription,
// it is set to TypeInfo::Unknown and the span to None.
let type_ascription = match &ty_opt {
Some(ty) => ty_to_type_argument(context, handler, engines, ty.clone())?,
None => {
let type_id = engines.te().insert(engines, TypeInfo::Unknown, None);
TypeArgument {
type_id,
initial_type_id: type_id,
span: tuple_name.span(),
call_path_tree: None,
}
}
};

// Save the tuple to the new name as a new variable declaration.
let save_body_first = VariableDeclaration {
name: tuple_name.clone(),
type_ascription,
body: expression,
is_mutable: false,
};
ast_nodes.push(AstNode {
content: AstNodeContent::Declaration(Declaration::VariableDeclaration(
save_body_first,
)),
span: span.clone(),
});

// Acript a second declaration to a tuple of placeholders to check that the tuple
// is properly sized to the pattern
let placeholders_type_ascription = {
Expand Down Expand Up @@ -3561,6 +3531,28 @@ fn statement_let_to_ast_nodes(
}
};

// Parse the type ascription and the type ascription span.
// In the event that the user did not provide a type ascription,
// it is set to TypeInfo::Unknown and the span to None.
let type_ascription = match &ty_opt {
Some(ty) => ty_to_type_argument(context, handler, engines, ty.clone())?,
None => placeholders_type_ascription.clone(),
};

// Save the tuple to the new name as a new variable declaration.
let save_body_first = VariableDeclaration {
name: tuple_name.clone(),
type_ascription,
body: expression,
is_mutable: false,
};
ast_nodes.push(AstNode {
content: AstNodeContent::Declaration(Declaration::VariableDeclaration(
save_body_first,
)),
span: span.clone(),
});

// create a variable expression that points to the new tuple name that we just created
let new_expr = Expression {
kind: ExpressionKind::Variable(tuple_name.clone()),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[[package]]
name = "core"
source = "path+from-root-B089E2A459F9A9B9"

[[package]]
name = "generic_trait_tuple_without_type_ascription"
source = "member"
dependencies = ["std"]

[[package]]
name = "std"
source = "path+from-root-B089E2A459F9A9B9"
dependencies = ["core"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[project]
authors = ["Fuel Labs <[email protected]>"]
entry = "main.sw"
license = "Apache-2.0"
name = "generic_trait_tuple_without_type_ascription"

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

pub trait MyFrom<T> {
fn from(b: T) -> Self;
}


pub trait MyInto<T> {
fn into(self) -> T;
}


impl<T, U> MyInto<U> for T
where
U: MyFrom<T>,
{
fn into(self) -> U {
U::from(self)
}
}

impl MyFrom<u256> for (u64, u64, u64, u64) {
fn from(_val: u256) -> (u64, u64, u64, u64) {
(42, 0, 0, 0)
}
}

fn main() -> bool {
let (_a, _b, _c, _d) = u256::min().into();

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

# check: $()let (_a, _b, _c, _d) = u256::min().into();
# nextln: $()Trait "MyFrom<u256>" is not implemented for type "(_, _, _, _)".

# check: $()let (_a, _b, _c, _d) = u256::min().into();
# nextln: $()Cannot infer type for type parameter "_". Insufficient type information provided. Try annotating its type.

0 comments on commit 8eb448f

Please sign in to comment.