Skip to content

Conditionally print message about record possibly being component #6337

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@

- `$$default` is no longer exported from the generated JavaScript when using default exports. https://github.com/rescript-lang/rescript-compiler/pull/6328

#### :nail_care: Polish
- Conditionally print error message about record with missing label potentially being a component. https://github.com/rescript-lang/rescript-compiler/pull/6337

# 11.0.0-beta.4

#### :rocket: New Feature
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

We've found a bug for you!
/.../fixtures/component_missing_prop.res:5:34-35

3 │ type props<'name> = {name: 'name}
4 │
5 │ let make = (): props<'name> => {}
6 │ }
7 │

Some required record fields are missing:
name. If this is a component, add the missing props.
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@
3 │
4 │ let b: b = One({name: "hello"})

Some required record fields are missing:
age. If this is a component, add the missing props.
Some required record fields are missing: age.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Since the React transform isn't active in the tests, mimic what the transform outputs.
module Component = {
type props<'name> = {name: 'name}

let make = (): props<'name> => {}
}
24 changes: 16 additions & 8 deletions jscomp/ml/typecore.ml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type error =
| Apply_non_function of type_expr
| Apply_wrong_label of arg_label * type_expr
| Label_multiply_defined of string
| Labels_missing of string list
| Labels_missing of string list * bool
| Label_not_mutable of Longident.t
| Wrong_name of string * type_expr * string * Path.t * string * string list
| Name_type_mismatch of
Expand Down Expand Up @@ -1963,6 +1963,11 @@ let rec lower_args env seen ty_fun =
let not_function env ty =
let ls, tvar = list_labels env ty in
ls = [] && not tvar

let check_might_be_component env ty_record =
match (expand_head env ty_record).desc with
| Tconstr (path, _, _) when path |> Path.last = "props" -> true
| _ -> false

type lazy_args =
(Asttypes.arg_label * (unit -> Typedtree.expression) option) list
Expand Down Expand Up @@ -2299,8 +2304,9 @@ and type_expect_ ?in_function ?(recarg=Rejected) env sexp ty_expected =
else
Some name in
let labels_missing = fields |> List.filter_map filter_missing in
if labels_missing <> [] then
raise(Error(loc, env, Labels_missing labels_missing));
if labels_missing <> [] then (
let might_be_component = check_might_be_component env ty_record in
raise(Error(loc, env, Labels_missing (labels_missing, might_be_component))));
[||], representation
| [], _ ->
if fields = [] && repr_opt <> None then
Expand All @@ -2324,8 +2330,9 @@ and type_expect_ ?in_function ?(recarg=Rejected) env sexp ty_expected =
Overridden ({loc ; txt = Lident lbl.lbl_name}, option_none lbl.lbl_arg loc))
label_descriptions
in
if !labels_missing <> [] then
raise(Error(loc, env, Labels_missing (List.rev !labels_missing)));
if !labels_missing <> [] then (
let might_be_component = check_might_be_component env ty_record in
raise(Error(loc, env, Labels_missing ((List.rev !labels_missing), might_be_component))));
let fields =
Array.map2 (fun descr def -> descr, def)
label_descriptions label_definitions
Expand Down Expand Up @@ -3862,11 +3869,12 @@ let report_error env ppf = function
type_expr ty print_label l
| Label_multiply_defined s ->
fprintf ppf "The record field label %s is defined several times" s
| Labels_missing labels ->
| Labels_missing (labels, might_be_component) ->
let print_labels ppf =
List.iter (fun lbl -> fprintf ppf "@ %s" ( lbl)) in
fprintf ppf "@[<hov>Some required record fields are missing:%a. If this is a component, add the missing props.@]"
print_labels labels
let component_text = if might_be_component then " If this is a component, add the missing props." else "" in
fprintf ppf "@[<hov>Some required record fields are missing:%a.%s@]"
print_labels labels component_text
| Label_not_mutable lid ->
fprintf ppf "The record field %a is not mutable" longident lid
| Wrong_name (eorp, ty, kind, p, name, valid_names) ->
Expand Down
2 changes: 1 addition & 1 deletion jscomp/ml/typecore.mli
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ type error =
| Apply_non_function of type_expr
| Apply_wrong_label of arg_label * type_expr
| Label_multiply_defined of string
| Labels_missing of string list
| Labels_missing of string list * bool
| Label_not_mutable of Longident.t
| Wrong_name of string * type_expr * string * Path.t * string * string list
| Name_type_mismatch of
Expand Down