Skip to content

Commit

Permalink
Fixes for specific error message. (#6758)
Browse files Browse the repository at this point in the history
The added test case was emitting a wrong/confusing error message,
because a for loop only gets type-checked in its desugared form, as a
while loop.

The error message was `A while loop's loop body cannot implicitly return
a value. Try assigning it to a mutable variable declared outside of the
loop instead.`

Corrected to: `A for loop's loop body cannot implicitly return a value.
Try assigning it to a mutable variable declared outside of the loop
instead.`

Fixes #6395

## Description


## 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.
- [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: IGI-111 <igi-111@protonmail.com>
  • Loading branch information
esdrubal and IGI-111 authored Nov 28, 2024
1 parent a02e8ea commit 33d3674
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 7 deletions.
1 change: 1 addition & 0 deletions sway-core/src/language/parsed/expression/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ impl PartialEqWithEngines for IntrinsicFunctionExpression {
pub struct WhileLoopExpression {
pub condition: Box<Expression>,
pub body: CodeBlock,
pub is_desugared_for_loop: bool,
}

impl EqWithEngines for WhileLoopExpression {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -506,9 +506,18 @@ impl ty::TyExpression {
arguments,
span,
),
ExpressionKind::WhileLoop(WhileLoopExpression { condition, body }) => {
Self::type_check_while_loop(handler, ctx.by_ref(), condition, body, span)
}
ExpressionKind::WhileLoop(WhileLoopExpression {
condition,
body,
is_desugared_for_loop,
}) => Self::type_check_while_loop(
handler,
ctx.by_ref(),
condition,
body,
*is_desugared_for_loop,
span,
),
ExpressionKind::ForLoop(ForLoopExpression { desugared }) => {
Self::type_check_for_loop(handler, ctx.by_ref(), desugared)
}
Expand Down Expand Up @@ -2131,6 +2140,7 @@ impl ty::TyExpression {
mut ctx: TypeCheckContext,
condition: &Expression,
body: &CodeBlock,
is_desugared_for_loop: bool,
span: Span,
) -> Result<Self, ErrorEmitted> {
let type_engine = ctx.engines.te();
Expand All @@ -2144,11 +2154,17 @@ impl ty::TyExpression {
};

let unit_ty = type_engine.id_of_unit();
let mut ctx = ctx.with_type_annotation(unit_ty).with_help_text(
"A while loop's loop body cannot implicitly return a value. Try \
let mut ctx = ctx
.with_type_annotation(unit_ty)
.with_help_text(if is_desugared_for_loop {
"A for loop's loop body cannot implicitly return a value. Try \
assigning it to a mutable variable declared outside of the loop \
instead.",
);
instead."
} else {
"A while loop's loop body cannot implicitly return a value. Try \
assigning it to a mutable variable declared outside of the loop \
instead."
});
let typed_body = ty::TyCodeBlock::type_check(handler, ctx.by_ref(), body, false)?;

let exp = ty::TyExpression {
Expand Down
2 changes: 2 additions & 0 deletions sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2131,6 +2131,7 @@ fn expr_to_expression(
kind: ExpressionKind::WhileLoop(WhileLoopExpression {
condition: Box::new(expr_to_expression(context, handler, engines, *condition)?),
body: braced_code_block_contents_to_code_block(context, handler, engines, block)?,
is_desugared_for_loop: false,
}),
span,
},
Expand Down Expand Up @@ -3278,6 +3279,7 @@ fn for_expr_to_expression(
span: Span::dummy(),
}),
body: while_body,
is_desugared_for_loop: true,
}),
span: Span::dummy(),
}),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[[package]]
name = "core"
source = "path+from-root-FF35018BB7DF2595"

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

[[package]]
name = "std"
source = "path+from-root-FF35018BB7DF2595"
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 = "for_loop_error"
entry = "main.sw"

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

fn main() {
let mut v : Vec<u8> = Vec::new();
v.push(1);
v.push(2);
v.push(3);
for elem in v.iter() {
log(elem);
3
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
category = "fail"

# check: $()3
# nextln: $()Mismatched types.
# nextln: $()expected: ()
# nextln: $()found: numeric.
# nextln: $()Implicit return must match up with block's type.

# check: $()3
# nextln: $()Mismatched types.
# nextln: $()expected: ()
# nextln: $()found: numeric.
# nextln: $()A for loop's loop body cannot implicitly return a value. Try assigning it to a mutable variable declared outside of the loop instead.

0 comments on commit 33d3674

Please # to comment.