Skip to content

Commit

Permalink
fix second pass of method application arguments (#6526)
Browse files Browse the repository at this point in the history
## Description

This PR fixes #6487.

## 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).
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [x] 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
xunilrj authored Sep 11, 2024
1 parent 09a992f commit 439f935
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 21 deletions.
20 changes: 19 additions & 1 deletion sway-core/src/language/ty/expression/expression_variant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1007,7 +1007,9 @@ impl TypeCheckAnalysis for TyExpressionVariant {
) -> Result<(), ErrorEmitted> {
match self {
TyExpressionVariant::Literal(_) => {}
TyExpressionVariant::FunctionApplication { fn_ref, .. } => {
TyExpressionVariant::FunctionApplication {
fn_ref, arguments, ..
} => {
let fn_decl_id = ctx.get_normalized_fn_node_id(fn_ref.id());

let fn_node = ctx.get_node_for_fn_decl(&fn_decl_id);
Expand All @@ -1021,6 +1023,22 @@ impl TypeCheckAnalysis for TyExpressionVariant {
let _ = fn_decl_id.type_check_analyze(handler, ctx);
}
}

// Unify arguments that are still not concrete
let decl = ctx.engines.de().get(fn_ref.id());

use crate::type_system::unify::unifier::*;
let unifier = Unifier::new(ctx.engines, "", UnifyKind::Default);

for (decl_param, arg) in decl.parameters.iter().zip(arguments.iter()) {
unifier.unify(
handler,
arg.1.return_type,
decl_param.type_argument.type_id,
&Span::dummy(),
false,
);
}
}
TyExpressionVariant::LazyOperator { lhs, rhs, .. } => {
lhs.type_check_analyze(handler, ctx)?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,7 @@ pub(crate) fn type_check_method_application(
let arg_handler = Handler::default();
let arg_opt = ty::TyExpression::type_check(&arg_handler, ctx, arg).ok();

// Check this type needs a second pass
let has_errors = arg_handler.has_errors();
let is_not_concrete = arg_opt
.as_ref()
.map(|x| {
x.return_type
.extract_inner_types(engines, IncludeSelf::Yes)
.iter()
.any(|x| !x.is_concrete(engines, TreatNumericAs::Abstract))
})
.unwrap_or_default();
let needs_second_pass = has_errors || is_not_concrete;
let needs_second_pass = arg_handler.has_errors();

if index == 0 {
// We want to emit errors in the self parameter and ignore TraitConstraintNotSatisfied with Placeholder
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
[[package]]
name = 'core'
source = 'path+from-root-DA3FEDB2AB26E552'
name = "core"
source = "path+from-root-DA3FEDB2AB26E552"

[[package]]
name = 'generic_impl_self'
source = 'member'
dependencies = ['std']
name = "generic_impl_self"
source = "member"
dependencies = [
"core",
"std",
]

[[package]]
name = 'std'
source = 'path+from-root-DA3FEDB2AB26E552'
dependencies = ['core']
name = "std"
source = "path+from-root-DA3FEDB2AB26E552"
dependencies = ["core"]
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ name = "generic_impl_self"
entry = "main.sw"

[dependencies]
core = { path = "../../../../../../../sway-lib-core" }
std = { path = "../../../../../../../sway-lib-std" }
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,23 @@ fn generic_impl_self_test() {
assert(u.first.value + u.second.value == 7u8);
}

use std::vec::*;

impl<T> Vec<T> {
pub fn with(self, with_value: T) -> Self {
let mut inside_vec = self;
inside_vec.push(with_value);
inside_vec
}
}

fn main() -> u32 {
generic_impl_self_test();
result_impl_test();

// data must be Vec<u256>
let data = Vec::new().with(0x333u256).with(0x222u256);
assert(data.len() == 2);

10u32
}

0 comments on commit 439f935

Please sign in to comment.