Skip to content

Commit 87d7869

Browse files
authored
Conditionally print message about record possibly being component (#6337)
* print message that this might be a component conditionally via a simple heuristic * changelog
1 parent 1615975 commit 87d7869

File tree

6 files changed

+39
-11
lines changed

6 files changed

+39
-11
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020

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

23+
#### :nail_care: Polish
24+
- Conditionally print error message about record with missing label potentially being a component. https://github.com/rescript-lang/rescript-compiler/pull/6337
25+
2326
# 11.0.0-beta.4
2427

2528
#### :rocket: New Feature
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
We've found a bug for you!
3+
/.../fixtures/component_missing_prop.res:5:34-35
4+
5+
3 │ type props<'name> = {name: 'name}
6+
4 │
7+
5 │ let make = (): props<'name> => {}
8+
6 │ }
9+
7 │
10+
11+
Some required record fields are missing:
12+
name. If this is a component, add the missing props.

jscomp/build_tests/super_errors/expected/variant_spread_inline_records.res.expected

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,4 @@
66
3 │
77
4 │ let b: b = One({name: "hello"})
88

9-
Some required record fields are missing:
10-
age. If this is a component, add the missing props.
9+
Some required record fields are missing: age.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Since the React transform isn't active in the tests, mimic what the transform outputs.
2+
module Component = {
3+
type props<'name> = {name: 'name}
4+
5+
let make = (): props<'name> => {}
6+
}

jscomp/ml/typecore.ml

+16-8
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ type error =
3535
| Apply_non_function of type_expr
3636
| Apply_wrong_label of arg_label * type_expr
3737
| Label_multiply_defined of string
38-
| Labels_missing of string list
38+
| Labels_missing of string list * bool
3939
| Label_not_mutable of Longident.t
4040
| Wrong_name of string * type_expr * string * Path.t * string * string list
4141
| Name_type_mismatch of
@@ -1963,6 +1963,11 @@ let rec lower_args env seen ty_fun =
19631963
let not_function env ty =
19641964
let ls, tvar = list_labels env ty in
19651965
ls = [] && not tvar
1966+
1967+
let check_might_be_component env ty_record =
1968+
match (expand_head env ty_record).desc with
1969+
| Tconstr (path, _, _) when path |> Path.last = "props" -> true
1970+
| _ -> false
19661971

19671972
type lazy_args =
19681973
(Asttypes.arg_label * (unit -> Typedtree.expression) option) list
@@ -2299,8 +2304,9 @@ and type_expect_ ?in_function ?(recarg=Rejected) env sexp ty_expected =
22992304
else
23002305
Some name in
23012306
let labels_missing = fields |> List.filter_map filter_missing in
2302-
if labels_missing <> [] then
2303-
raise(Error(loc, env, Labels_missing labels_missing));
2307+
if labels_missing <> [] then (
2308+
let might_be_component = check_might_be_component env ty_record in
2309+
raise(Error(loc, env, Labels_missing (labels_missing, might_be_component))));
23042310
[||], representation
23052311
| [], _ ->
23062312
if fields = [] && repr_opt <> None then
@@ -2324,8 +2330,9 @@ and type_expect_ ?in_function ?(recarg=Rejected) env sexp ty_expected =
23242330
Overridden ({loc ; txt = Lident lbl.lbl_name}, option_none lbl.lbl_arg loc))
23252331
label_descriptions
23262332
in
2327-
if !labels_missing <> [] then
2328-
raise(Error(loc, env, Labels_missing (List.rev !labels_missing)));
2333+
if !labels_missing <> [] then (
2334+
let might_be_component = check_might_be_component env ty_record in
2335+
raise(Error(loc, env, Labels_missing ((List.rev !labels_missing), might_be_component))));
23292336
let fields =
23302337
Array.map2 (fun descr def -> descr, def)
23312338
label_descriptions label_definitions
@@ -3862,11 +3869,12 @@ let report_error env ppf = function
38623869
type_expr ty print_label l
38633870
| Label_multiply_defined s ->
38643871
fprintf ppf "The record field label %s is defined several times" s
3865-
| Labels_missing labels ->
3872+
| Labels_missing (labels, might_be_component) ->
38663873
let print_labels ppf =
38673874
List.iter (fun lbl -> fprintf ppf "@ %s" ( lbl)) in
3868-
fprintf ppf "@[<hov>Some required record fields are missing:%a. If this is a component, add the missing props.@]"
3869-
print_labels labels
3875+
let component_text = if might_be_component then " If this is a component, add the missing props." else "" in
3876+
fprintf ppf "@[<hov>Some required record fields are missing:%a.%s@]"
3877+
print_labels labels component_text
38703878
| Label_not_mutable lid ->
38713879
fprintf ppf "The record field %a is not mutable" longident lid
38723880
| Wrong_name (eorp, ty, kind, p, name, valid_names) ->

jscomp/ml/typecore.mli

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ type error =
7272
| Apply_non_function of type_expr
7373
| Apply_wrong_label of arg_label * type_expr
7474
| Label_multiply_defined of string
75-
| Labels_missing of string list
75+
| Labels_missing of string list * bool
7676
| Label_not_mutable of Longident.t
7777
| Wrong_name of string * type_expr * string * Path.t * string * string list
7878
| Name_type_mismatch of

0 commit comments

Comments
 (0)