Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use swc_ecma_ast as ast;
use crate::ir::*;
use crate::lower::{lower_expr, LoweringContext};
use crate::lower_patterns::*;
use crate::lower_types::*;

use crate::destructuring::var_decl_sources::*;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use swc_ecma_ast as ast;
use crate::ir::*;
use crate::lower::{lower_expr, LoweringContext};
use crate::lower_patterns::*;
use crate::lower_types::*;

use crate::destructuring::var_decl_sources::*;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use swc_ecma_ast as ast;
use crate::ir::*;
use crate::lower::{lower_expr, LoweringContext};
use crate::lower_patterns::*;
use crate::lower_types::*;

use crate::destructuring::helpers::{get_fetch_module, is_member_fetch_call};
use crate::destructuring::var_decl_sources::*;
Expand Down
1 change: 0 additions & 1 deletion crates/perry-hir/src/destructuring/var_decl/native_new.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use swc_ecma_ast as ast;
use crate::ir::*;
use crate::lower::{lower_expr, LoweringContext};
use crate::lower_patterns::*;
use crate::lower_types::*;

use crate::destructuring::var_decl_sources::*;

Expand Down
58 changes: 41 additions & 17 deletions crates/perry-hir/src/destructuring/var_decl/type_infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use swc_ecma_ast as ast;
use crate::ir::*;
use crate::lower::{lower_expr, LoweringContext};
use crate::lower_patterns::*;
use crate::lower_types::*;
use crate::lower_types::{extract_ts_type, infer_type_from_expr};

use crate::destructuring::var_decl_sources::*;

Expand Down Expand Up @@ -90,7 +90,46 @@ pub(crate) fn infer_decl_type(
if let ast::Expr::New(new_expr) = init_expr.as_ref() {
if let ast::Expr::Ident(class_ident) = new_expr.callee.as_ref() {
let class_name = class_ident.sym.as_ref();
if class_name == "Set" || class_name == "Map" {
// #6233: a USER class of this name lexically shadows the
// same-named built-in (`class Map { get(){…} }` … `const m
// = new Map()`), so the user-class arm must win — typing
// the binding as the built-in would route its method calls
// (`m.get(...)`) to the native intrinsic fast paths. For a
// built-in-colliding name the type stays `Named` even with
// explicit type args: `Generic { base: "Map", .. }` is
// exactly what the collection fast-path recognizers key
// on, so a generic user `class Map<T>` must not produce
// it.
if ctx.classes_index.contains_key(class_name) {
let type_args: Vec<Type> = new_expr
.type_args
.as_ref()
.map(|ta| ta.params.iter().map(|t| extract_ts_type(t)).collect())
.unwrap_or_default();
if type_args.is_empty()
|| crate::lower_types::builtin_constructor_inference_name(class_name)
{
ty = Type::Named(class_name.to_string());
} else {
ty = Type::Generic {
base: class_name.to_string(),
type_args,
};
}
} else if crate::lower_types::builtin_constructor_inference_name(class_name)
&& ctx.shadows_unqualified_global(class_name)
{
// #6233 (review follow-up): a NON-class user binding —
// a local, `function Map() {}`, an import — also
// shadows the built-in (mirrors the construction-side
// guard in expr_new.rs). Leave `ty` as inferred (Any)
// so none of the builtin arms below claims the binding
// for an intrinsic fast path. Scoped to the same
// conservative name set as the infer_type_from_expr
// guard: module-export names that legitimately arrive
// through local bindings (`Buffer`, the stream and
// event classes) keep their arms.
} else if class_name == "Set" || class_name == "Map" {
Comment thread
coderabbitai[bot] marked this conversation as resolved.
// Extract type arguments from new Set<T>() or new Map<K, V>()
let type_args: Vec<Type> = new_expr
.type_args
Expand Down Expand Up @@ -131,21 +170,6 @@ pub(crate) fn infer_decl_type(
| "Float64Array"
) {
ty = Type::Named(class_name.to_string());
} else if ctx.classes_index.contains_key(class_name) {
// User-defined class: infer type from new ClassName(...)
let type_args: Vec<Type> = new_expr
.type_args
.as_ref()
.map(|ta| ta.params.iter().map(|t| extract_ts_type(t)).collect())
.unwrap_or_default();
if type_args.is_empty() {
ty = Type::Named(class_name.to_string());
} else {
ty = Type::Generic {
base: class_name.to_string(),
type_args,
};
}
}
}
}
Expand Down
Loading
Loading