Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

JSX preserve mode spreads an `@unboxed` props record (`{..."x"}` instead of `"x"`)

Đã đóng
#8,813 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Một pull request liên quan đã được merge.

  • #8847 của @cknitt — đã đóng, không merge
  • #8857 của @cknitt — đã merge

Đánh giá

Độ khó
4/5
Thời gian dự kiến
1-2 ngày
Mức phù hợp với người mới
25/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Đình trệ
Công nghệ
javascript, ocaml
Lĩnh vực
compilers

Hướng nghiên cứu

Start with jsx_props_of in compiler/ml/translcore.ml and jsx_printable in compiler/core/js_dump.ml, then compare the preserve-mode output with the reproduction and expected output in the issue. Done means both @unboxed record examples preserve the string as the props value instead of spreading it. Pull request #8847 is already open for this issue.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Found by adversarial experiments on semantic analysts.

What is broken

jsx_props_of turns every props expression that is not a Record_regular record literal into Jsx_props_spread:
https://github.com/rescript-lang/rescript/blob/8d51b9ce7/compiler/ml/translcore.ml#L1049-L1096

An @unboxed record literal compiles to its single field's value, which is not an object. jsx_printable does not reject this case:
https://github.com/rescript-lang/rescript/blob/8d51b9ce7/compiler/core/js_dump.ml#L176-L190

Reproduction

@@jsxConfig({version: 4, module_: "MyJsx"})
module MyJsx = {
  type element = int
  type component<'props> = 'props => element
  external component: component<'props> => component<'props> = "%identity"
  @module("rt") external jsx: (component<'props>, 'props) => element = "jsx"
  @module("rt") external jsxs: (component<'props>, 'props) => element = "jsxs"
  external array: array<element> => element = "%identity"
}
@unboxed type props = {title: string}
module C = {@module("lib") external make: MyJsx.component<props> = "C"}
module D = {@val external make: MyJsx.component<props> = "lowerD"}
let el = <C title="x" />
let el2 = <D title="y" />

bsc -nopervasives -bs-jsx 4 -bs-jsx-preserve K12.res at master:

let el = <Lib.C
  {..."x"}
/>;
let el2 = Rt.jsx(lowerD, {..."y"});

Expected, as printed by bsc -nopervasives -bs-jsx 4 and by preserve mode at ece8b148:

let el = Rt.jsx(Lib.C, "x");
let el2 = Rt.jsx(lowerD, "y");

Introduced

#8754 (a7721303a).

Impact

The component receives {0: "x"} instead of "x": the generated code is wrong, with no error or warning. The case is rare, because the props type must be an @unboxed record.

Ngôn ngữ chính
OCaml
Star
7.5k
Fork
484
Merge trung bình
20 giờ 27 phút
Pull request đã merge (30 ngày)
120

Chuẩn bị môi trường

Mở trong Codespaces

Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của rescript-lang/rescript

Tất cả issue của rescript-lang/rescript

Issue tương tự

Thêm issue về Compilers

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.