From b61b26b3867b048a1dc040741ed955bc1dbf111e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 18 May 2023 22:46:42 +0900 Subject: [PATCH 1/7] Add a test --- .../1.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 crates/stc_ts_file_analyzer/tests/errors/conformance/types/assignmentCompatibility/assignmentCompatWithCallSignaturesWithRestParameters/1.ts diff --git a/crates/stc_ts_file_analyzer/tests/errors/conformance/types/assignmentCompatibility/assignmentCompatWithCallSignaturesWithRestParameters/1.ts b/crates/stc_ts_file_analyzer/tests/errors/conformance/types/assignmentCompatibility/assignmentCompatWithCallSignaturesWithRestParameters/1.ts new file mode 100644 index 0000000000..117a06ddb1 --- /dev/null +++ b/crates/stc_ts_file_analyzer/tests/errors/conformance/types/assignmentCompatibility/assignmentCompatWithCallSignaturesWithRestParameters/1.ts @@ -0,0 +1,13 @@ +// call signatures in derived types must have the same or fewer optional parameters as the target for assignment + +interface Base { + a: (...args: number[]) => number; + a2: (x: number, ...z: number[]) => number; + a3: (x: number, y?: string, ...z: number[]) => number; + a4: (x?: number, y?: string, ...z: number[]) => number; +} + +declare var a: (...args: number[]) => number; // ok, same number of required params +a = (x?: string) => 1; // error, incompatible type + +export { } \ No newline at end of file From ffdd54b1733c2dd9b3f19120f59d0f50b02e58a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Fri, 19 May 2023 16:08:50 +0900 Subject: [PATCH 2/7] Reduce --- .../1.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/crates/stc_ts_file_analyzer/tests/errors/conformance/types/assignmentCompatibility/assignmentCompatWithCallSignaturesWithRestParameters/1.ts b/crates/stc_ts_file_analyzer/tests/errors/conformance/types/assignmentCompatibility/assignmentCompatWithCallSignaturesWithRestParameters/1.ts index 117a06ddb1..b48b544688 100644 --- a/crates/stc_ts_file_analyzer/tests/errors/conformance/types/assignmentCompatibility/assignmentCompatWithCallSignaturesWithRestParameters/1.ts +++ b/crates/stc_ts_file_analyzer/tests/errors/conformance/types/assignmentCompatibility/assignmentCompatWithCallSignaturesWithRestParameters/1.ts @@ -1,12 +1,5 @@ // call signatures in derived types must have the same or fewer optional parameters as the target for assignment -interface Base { - a: (...args: number[]) => number; - a2: (x: number, ...z: number[]) => number; - a3: (x: number, y?: string, ...z: number[]) => number; - a4: (x?: number, y?: string, ...z: number[]) => number; -} - declare var a: (...args: number[]) => number; // ok, same number of required params a = (x?: string) => 1; // error, incompatible type From e0d9e5b03060522d5c312883e86ae1a5a67968e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Fri, 19 May 2023 23:09:01 +0900 Subject: [PATCH 3/7] Fix loop count --- crates/stc_ts_file_analyzer/src/analyzer/assign/function.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/stc_ts_file_analyzer/src/analyzer/assign/function.rs b/crates/stc_ts_file_analyzer/src/analyzer/assign/function.rs index 3ca18ade81..47ffa7e904 100644 --- a/crates/stc_ts_file_analyzer/src/analyzer/assign/function.rs +++ b/crates/stc_ts_file_analyzer/src/analyzer/assign/function.rs @@ -854,6 +854,9 @@ impl Analyzer<'_, '_> { ) }); + let l_count = li.clone().count(); + let r_count = ri.clone().count(); + let l_has_rest = l.iter().any(|p| matches!(p.pat, RPat::Rest(..))); // TODO(kdy1): Consider optional parameters. @@ -931,7 +934,6 @@ impl Analyzer<'_, '_> { (RPat::Rest(..), _) => { // TODO(kdy1): Implement correct logic - return Ok(()); } @@ -939,7 +941,7 @@ impl Analyzer<'_, '_> { // If r is an iterator, we should assign each element to l. if let Ok(r_iter) = self.get_iterator(span, Cow::Borrowed(&r.ty), Default::default()) { if let Ok(l_iter) = self.get_iterator(span, Cow::Borrowed(&l.ty), Default::default()) { - for idx in 0..max(li.clone().count(), ri.clone().count()) { + for idx in 0..max(l_count, r_count) { let le = self.access_property( span, &l_iter, From 2904fe912d3e27fc8a35be43741e4b0eca4e4c5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Fri, 19 May 2023 23:19:28 +0900 Subject: [PATCH 4/7] Don't use Ok(()) --- .../src/analyzer/assign/function.rs | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/crates/stc_ts_file_analyzer/src/analyzer/assign/function.rs b/crates/stc_ts_file_analyzer/src/analyzer/assign/function.rs index 47ffa7e904..07493fdef5 100644 --- a/crates/stc_ts_file_analyzer/src/analyzer/assign/function.rs +++ b/crates/stc_ts_file_analyzer/src/analyzer/assign/function.rs @@ -4,7 +4,7 @@ use fxhash::FxHashMap; use itertools::Itertools; use stc_ts_ast_rnode::{RBindingIdent, RIdent, RNumber, RPat, RTsLit}; use stc_ts_errors::{ - debug::{dump_type_map, force_dump_type_as_string}, + debug::{dump_type_map, force_dump_type_as_string, print_backtrace}, DebugExt, ErrorKind, }; use stc_ts_types::{Constructor, FnParam, Function, IdCtx, Key, KeywordType, LitType, Type, TypeElement, TypeParamDecl}; @@ -386,6 +386,8 @@ impl Analyzer<'_, '_> { }, ) .context("tried to assign parameters of a function to parameters of another function")?; + + dbg!(&l_params, &r_params); } if let Some(l_ret_ty) = l_ret_ty { @@ -920,6 +922,7 @@ impl Analyzer<'_, '_> { ..opts }, ) { + dbg!(); continue; } } @@ -927,21 +930,27 @@ impl Analyzer<'_, '_> { // A rest pattern is always the last match (&l.pat, &r.pat) { (RPat::Rest(..), RPat::Rest(..)) => { + dbg!(); self.assign_param(data, l, r, opts) .with_context(|| "tried to assign a rest parameter to another rest parameter".to_string())?; break; } (RPat::Rest(..), _) => { + dbg!(); // TODO(kdy1): Implement correct logic - return Ok(()); + return Err(ErrorKind::SimpleAssignFailed { span, cause: None }.context("l is rest but r is not")); } (_, RPat::Rest(..)) => { + dbg!(); // If r is an iterator, we should assign each element to l. if let Ok(r_iter) = self.get_iterator(span, Cow::Borrowed(&r.ty), Default::default()) { + dbg!(); if let Ok(l_iter) = self.get_iterator(span, Cow::Borrowed(&l.ty), Default::default()) { + dbg!(); for idx in 0..max(l_count, r_count) { + dbg!(); let le = self.access_property( span, &l_iter, @@ -981,30 +990,36 @@ impl Analyzer<'_, '_> { }, )?; - self.assign_param_type(data, &le, &re, opts).with_context(|| { + print_backtrace(); + + dbg!(self.assign_param_type(data, &le, &re, opts).with_context(|| { format!( "tried to assign a rest parameter to parameters; r_ty = {}", force_dump_type_as_string(&r.ty) ) - })?; + }))?; } } - return Ok(()); + continue; } + dbg!(); self.assign_param(data, l, r, opts) .context("tried to assign a rest parameter to parameters where r-ty is not a tuple")?; for l in li { + dbg!(); self.assign_param(data, l, r, opts) .context("tried to assign a rest parameter to parameters where r-ty is not a tuple (iter)")?; } + dbg!(); return Ok(()); } _ => { + dbg!(); self.assign_param( data, l, @@ -1014,6 +1029,7 @@ impl Analyzer<'_, '_> { ..opts }, )?; + dbg!(); } } } From 56ec6083900b4e7231ad19c6f575cf8d1d0c7b5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Fri, 19 May 2023 23:22:10 +0900 Subject: [PATCH 5/7] Update test refs --- .../1.swc-stderr | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 crates/stc_ts_file_analyzer/tests/errors/conformance/types/assignmentCompatibility/assignmentCompatWithCallSignaturesWithRestParameters/1.swc-stderr diff --git a/crates/stc_ts_file_analyzer/tests/errors/conformance/types/assignmentCompatibility/assignmentCompatWithCallSignaturesWithRestParameters/1.swc-stderr b/crates/stc_ts_file_analyzer/tests/errors/conformance/types/assignmentCompatibility/assignmentCompatWithCallSignaturesWithRestParameters/1.swc-stderr new file mode 100644 index 0000000000..f63bacf53e --- /dev/null +++ b/crates/stc_ts_file_analyzer/tests/errors/conformance/types/assignmentCompatibility/assignmentCompatWithCallSignaturesWithRestParameters/1.swc-stderr @@ -0,0 +1,32 @@ +TS2322 + + x AssignFailed { + | span: Span { + | lo: BytePos( + | 199, + | ), + | hi: BytePos( + | 200, + | ), + | ctxt: #1, + | }, + | cause: [ + | SimpleAssignFailed { + | span: Span { + | lo: BytePos( + | 199, + | ), + | hi: BytePos( + | 200, + | ), + | ctxt: #1, + | }, + | cause: None, + | }, + | ], + | } + ,-[$DIR/tests/errors/conformance/types/assignmentCompatibility/assignmentCompatWithCallSignaturesWithRestParameters/1.ts:3:1] + 3 | declare var a: (...args: number[]) => number; // ok, same number of required params + 4 | a = (x?: string) => 1; // error, incompatible type + : ^ + `---- From f605d06c30b6e8c195829e2124df2dccd0061002 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Fri, 19 May 2023 23:35:47 +0900 Subject: [PATCH 6/7] `disallow_rest_pat_in_left` --- .../stc_ts_file_analyzer/src/analyzer/assign/function.rs | 8 ++++++-- crates/stc_ts_file_analyzer/src/analyzer/assign/mod.rs | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/crates/stc_ts_file_analyzer/src/analyzer/assign/function.rs b/crates/stc_ts_file_analyzer/src/analyzer/assign/function.rs index 07493fdef5..ccf97a62b5 100644 --- a/crates/stc_ts_file_analyzer/src/analyzer/assign/function.rs +++ b/crates/stc_ts_file_analyzer/src/analyzer/assign/function.rs @@ -937,9 +937,13 @@ impl Analyzer<'_, '_> { } (RPat::Rest(..), _) => { + if opts.disallow_rest_pat_in_left { + // TODO(kdy1): Implement correct logic + return Err(ErrorKind::SimpleAssignFailed { span, cause: None }.context("l is rest but r is not")); + } dbg!(); - // TODO(kdy1): Implement correct logic - return Err(ErrorKind::SimpleAssignFailed { span, cause: None }.context("l is rest but r is not")); + + return Ok(()); } (_, RPat::Rest(..)) => { diff --git a/crates/stc_ts_file_analyzer/src/analyzer/assign/mod.rs b/crates/stc_ts_file_analyzer/src/analyzer/assign/mod.rs index 8121e15e05..3ce5859a87 100644 --- a/crates/stc_ts_file_analyzer/src/analyzer/assign/mod.rs +++ b/crates/stc_ts_file_analyzer/src/analyzer/assign/mod.rs @@ -189,6 +189,8 @@ pub(crate) struct AssignOpts { /// If true, `assign` will fail if the params of the LHS is longer than the /// RHS. pub ensure_params_length: bool, + + pub disallow_rest_pat_in_left: bool, } #[derive(Default)] From e0174cf60eb98a5e832fd166f8c9d1bfbdd48ba4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Sat, 20 May 2023 13:01:54 +0900 Subject: [PATCH 7/7] WPI --- .../src/analyzer/assign/function.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/crates/stc_ts_file_analyzer/src/analyzer/assign/function.rs b/crates/stc_ts_file_analyzer/src/analyzer/assign/function.rs index ccf97a62b5..b1f101c049 100644 --- a/crates/stc_ts_file_analyzer/src/analyzer/assign/function.rs +++ b/crates/stc_ts_file_analyzer/src/analyzer/assign/function.rs @@ -382,6 +382,7 @@ impl Analyzer<'_, '_> { r_params, AssignOpts { is_params_of_method_definition: false, + disallow_rest_pat_in_left: true, ..opts }, ) @@ -836,6 +837,12 @@ impl Analyzer<'_, '_> { let _tracing = dev_span!("assign_params"); let span = opts.span; + let disallow_rest_in_lhs = opts.disallow_rest_pat_in_left; + + let opts = AssignOpts { + disallow_rest_pat_in_left: false, + ..opts + }; let mut li = l.iter().filter(|p| { !matches!( @@ -937,11 +944,12 @@ impl Analyzer<'_, '_> { } (RPat::Rest(..), _) => { - if opts.disallow_rest_pat_in_left { + if disallow_rest_in_lhs { + dbg!(); + print_backtrace(); // TODO(kdy1): Implement correct logic return Err(ErrorKind::SimpleAssignFailed { span, cause: None }.context("l is rest but r is not")); } - dbg!(); return Ok(()); } @@ -994,8 +1002,6 @@ impl Analyzer<'_, '_> { }, )?; - print_backtrace(); - dbg!(self.assign_param_type(data, &le, &re, opts).with_context(|| { format!( "tried to assign a rest parameter to parameters; r_ty = {}",