patch 8.2.3117: Vim9: type not properly checked in for loop

Problem:    Vim9: type not properly checked in for loop.
Solution:   Have items() return a list of lists.  Add runtime type checks.
            (closes #8515)
diff --git a/src/evalfunc.c b/src/evalfunc.c
index ec74fde..34eac69 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -522,6 +522,11 @@
     return &t_list_dict_any;
 }
     static type_T *
+ret_list_items(int argcount, type_T **argtypes UNUSED)
+{
+    return &t_list_list_any;
+}
+    static type_T *
 ret_dict_any(int argcount UNUSED, type_T **argtypes UNUSED)
 {
     return &t_dict_any;
@@ -1166,7 +1171,7 @@
     {"isnan",		1, 1, FEARG_1,	    arg1_float_or_nr,
 			ret_number_bool,    MATH_FUNC(f_isnan)},
     {"items",		1, 1, FEARG_1,	    arg1_dict,
-			ret_list_any,	    f_items},
+			ret_list_items,	    f_items},
     {"job_getchannel",	1, 1, FEARG_1,	    NULL,
 			ret_channel,	    JOB_FUNC(f_job_getchannel)},
     {"job_info",	0, 1, FEARG_1,	    NULL,
@@ -3687,6 +3692,7 @@
 {
     if (argcount == 1 && argtypes[0]->tt_type == VAR_STRING)
 	return &t_func_any;
+    // Need to check the type at runtime, the function may be defined later.
     return &t_func_unknown;
 }
 
diff --git a/src/globals.h b/src/globals.h
index b6076df..54ecb8e 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -441,6 +441,7 @@
 EXTERN type_T t_list_string INIT6(VAR_LIST, 0, 0, TTFLAG_STATIC, &t_string, NULL);
 EXTERN type_T t_list_job INIT6(VAR_LIST, 0, 0, TTFLAG_STATIC, &t_job, NULL);
 EXTERN type_T t_list_dict_any INIT6(VAR_LIST, 0, 0, TTFLAG_STATIC, &t_dict_any, NULL);
+EXTERN type_T t_list_list_any INIT6(VAR_LIST, 0, 0, TTFLAG_STATIC, &t_list_any, NULL);
 
 EXTERN type_T t_dict_bool INIT6(VAR_DICT, 0, 0, TTFLAG_STATIC, &t_bool, NULL);
 EXTERN type_T t_dict_number INIT6(VAR_DICT, 0, 0, TTFLAG_STATIC, &t_number, NULL);
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index f5dc26e..4abe401 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -2573,6 +2573,14 @@
       endfor
   END
   CheckDefAndScriptFailure(lines, 'E1059:', 1)
+
+  lines =<< trim END
+      var d: dict<number> = {a: 1, b: 2}
+      for [k: job, v: job] in d->items()
+        echo k v
+      endfor
+  END
+  CheckDefExecAndScriptFailure(lines, 'E1012: Type mismatch; expected job but got string', 2)
 enddef
 
 def Test_for_loop_script_var()
diff --git a/src/version.c b/src/version.c
index 1deb3e4..e1774a4 100644
--- a/src/version.c
+++ b/src/version.c
@@ -756,6 +756,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    3117,
+/**/
     3116,
 /**/
     3115,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index d630736..3a717e4 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -7932,8 +7932,11 @@
 	    if (lhs_type == &t_any)
 		lhs_type = item_type;
 	    else if (item_type != &t_unknown
-		       && !(var_list && item_type == &t_any)
-		       && check_type(lhs_type, item_type, TRUE, where) == FAIL)
+			&& ((var_list && item_type == &t_any)
+			  ? need_type(item_type, lhs_type,
+						     -1, 0, cctx, FALSE, FALSE)
+			  : check_type(lhs_type, item_type, TRUE, where))
+			== FAIL)
 		goto failed;
 	    var_lvar = reserve_local(cctx, arg, varlen, TRUE, lhs_type);
 	    if (var_lvar == NULL)