diff -r 11d40fc82f11 src/buffer.c
--- a/src/buffer.c	Thu Jul 12 22:00:46 2012 +0200
+++ b/src/buffer.c	Sun Jul 15 11:50:08 2012 +0400
@@ -1747,7 +1747,7 @@
     buf->b_wininfo->wi_win = curwin;
 
 #ifdef FEAT_EVAL
-    init_var_dict(&buf->b_vars, &buf->b_bufvar);    /* init b: variables */
+    init_var_dict(&buf->b_vars, &buf->b_bufvar, 0);    /* init b: variables */
 #endif
 #ifdef FEAT_SYN_HL
     hash_init(&buf->b_s.b_keywtab);
diff -r 11d40fc82f11 src/eval.c
--- a/src/eval.c	Thu Jul 12 22:00:46 2012 +0200
+++ b/src/eval.c	Sun Jul 15 11:50:08 2012 +0400
@@ -850,8 +850,8 @@
     int		    i;
     struct vimvar   *p;
 
-    init_var_dict(&globvardict, &globvars_var);
-    init_var_dict(&vimvardict, &vimvars_var);
+    init_var_dict(&globvardict, &globvars_var, 1);
+    init_var_dict(&vimvardict, &vimvars_var, 0);
     vimvardict.dv_lock = VAR_FIXED;
     hash_init(&compat_hashtab);
     hash_init(&func_hashtab);
@@ -2725,15 +2725,26 @@
 	    lp->ll_dict = lp->ll_tv->vval.v_dict;
 	    lp->ll_di = dict_find(lp->ll_dict, key, len);
 
-	    /* When assigning to g: check that a function and variable name is
-	     * valid. */
-	    if (rettv != NULL && lp->ll_dict == &globvardict)
-	    {
-		if (rettv->v_type == VAR_FUNC
+	    /* When assigning to scope dictionary check that a function and 
+	     * variable name is valid (only variable name unless it is l: or g: 
+	     * dictionary). */
+	    if (rettv != NULL && lp->ll_dict->dv_scope)
+	    {
+		char_u prevval = key[len];
+		key[len] = NUL;
+		if (lp->ll_dict->dv_scope == VAR_DEF_SCOPE
+			       && rettv->v_type == VAR_FUNC
 			       && var_check_func_name(key, lp->ll_di == NULL))
+		{
+		    key[len] = prevval;
 		    return NULL;
+		}
 		if (!valid_varname(key))
+		{
+		    key[len] = prevval;
 		    return NULL;
+		}
+		key[len] = prevval;
 	    }
 
 	    if (lp->ll_di == NULL)
@@ -6960,6 +6971,7 @@
 
 	hash_init(&d->dv_hashtab);
 	d->dv_lock = 0;
+	d->dv_scope = 0;
 	d->dv_refcount = 0;
 	d->dv_copyID = 0;
     }
@@ -10203,6 +10215,15 @@
 		{
 		    --todo;
 		    di1 = dict_find(d1, hi2->hi_key, -1);
+		    if (d1->dv_scope)
+		    {
+		        if (d1->dv_scope == VAR_DEF_SCOPE
+				&& HI2DI(hi2)->di_tv.v_type == VAR_FUNC
+				&& !var_check_func_name(hi2->hi_key, di1 == NULL))
+			    break;
+			if (!valid_varname(hi2->hi_key))
+			    break;
+		    }
 		    if (di1 == NULL)
 		    {
 			di1 = dictitem_copy(HI2DI(hi2));
@@ -20027,7 +20048,7 @@
 	{
 	    sv = SCRIPT_SV(ga_scripts.ga_len + 1) =
 		(scriptvar_T *)alloc_clear(sizeof(scriptvar_T));
-	    init_var_dict(&sv->sv_dict, &sv->sv_var);
+	    init_var_dict(&sv->sv_dict, &sv->sv_var, 0);
 	    ++ga_scripts.ga_len;
 	}
     }
@@ -20038,12 +20059,14 @@
  * point to it.
  */
     void
-init_var_dict(dict, dict_var)
+init_var_dict(dict, dict_var, default_scope)
     dict_T	*dict;
     dictitem_T	*dict_var;
+    int		default_scope;
 {
     hash_init(&dict->dv_hashtab);
     dict->dv_lock = 0;
+    dict->dv_scope = default_scope ? VAR_DEF_SCOPE : VAR_SCOPE;
     dict->dv_refcount = DO_NOT_FREE_CNT;
     dict->dv_copyID = 0;
     dict_var->di_tv.vval.v_dict = dict;
@@ -22304,7 +22327,7 @@
     /*
      * Init l: variables.
      */
-    init_var_dict(&fc->l_vars, &fc->l_vars_var);
+    init_var_dict(&fc->l_vars, &fc->l_vars_var, 1);
     if (selfdict != NULL)
     {
 	/* Set l:self to "selfdict".  Use "name" to avoid a warning from
@@ -22325,7 +22348,7 @@
      * Set a:0 to "argcount".
      * Set a:000 to a list with room for the "..." arguments.
      */
-    init_var_dict(&fc->l_avars, &fc->l_avars_var);
+    init_var_dict(&fc->l_avars, &fc->l_avars_var, 0);
     add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "0",
 				(varnumber_T)(argcount - fp->uf_args.ga_len));
     /* Use "name" to avoid a warning from some compiler that checks the
diff -r 11d40fc82f11 src/proto/eval.pro
--- a/src/proto/eval.pro	Thu Jul 12 22:00:46 2012 +0200
+++ b/src/proto/eval.pro	Sun Jul 15 11:50:08 2012 +0400
@@ -93,7 +93,7 @@
 char_u *get_tv_string_chk __ARGS((typval_T *varp));
 char_u *get_var_value __ARGS((char_u *name));
 void new_script_vars __ARGS((scid_T id));
-void init_var_dict __ARGS((dict_T *dict, dictitem_T *dict_var));
+void init_var_dict __ARGS((dict_T *dict, dictitem_T *dict_var, int default_scope));
 void vars_clear __ARGS((hashtab_T *ht));
 void copy_tv __ARGS((typval_T *from, typval_T *to));
 void ex_echo __ARGS((exarg_T *eap));
diff -r 11d40fc82f11 src/structs.h
--- a/src/structs.h	Thu Jul 12 22:00:46 2012 +0200
+++ b/src/structs.h	Sun Jul 15 11:50:08 2012 +0400
@@ -1106,6 +1106,11 @@
 #define VAR_DICT    5	/* "v_dict" is used */
 #define VAR_FLOAT   6	/* "v_float" is used */
 
+/* Values for "v_scope". */
+#define VAR_SCOPE     1	/* a:, v:, s:, … scope dictionaries */
+#define VAR_DEF_SCOPE 2	/* l:, g: scope dictionaries: here funcrefs may mask 
+                           existing functions */
+
 /* Values for "v_lock". */
 #define VAR_LOCKED  1	/* locked with lock(), can use unlock() */
 #define VAR_FIXED   2	/* locked forever */
@@ -1181,6 +1186,7 @@
     int		dv_copyID;	/* ID used by deepcopy() */
     dict_T	*dv_copydict;	/* copied dict used by deepcopy() */
     char	dv_lock;	/* zero, VAR_LOCKED, VAR_FIXED */
+    char	dv_scope;	/* zero, 1 */
     dict_T	*dv_used_next;	/* next dict in used dicts list */
     dict_T	*dv_used_prev;	/* previous dict in used dicts list */
 };
diff -r 11d40fc82f11 src/window.c
--- a/src/window.c	Thu Jul 12 22:00:46 2012 +0200
+++ b/src/window.c	Sun Jul 15 11:50:08 2012 +0400
@@ -3468,7 +3468,7 @@
 # endif
 #ifdef FEAT_EVAL
 	/* init t: variables */
-	init_var_dict(&tp->tp_vars, &tp->tp_winvar);
+	init_var_dict(&tp->tp_vars, &tp->tp_winvar, 0);
 #endif
 	tp->tp_ch_used = p_ch;
     }
@@ -4410,7 +4410,7 @@
 #endif
 #ifdef FEAT_EVAL
 	/* init w: variables */
-	init_var_dict(&new_wp->w_vars, &new_wp->w_winvar);
+	init_var_dict(&new_wp->w_vars, &new_wp->w_winvar, 0);
 #endif
 #ifdef FEAT_FOLDING
 	foldInitWin(new_wp);
