Browse Source

error on extra anonymous fields

Nicolas Cannasse 18 years ago
parent
commit
c912f3b267
4 changed files with 11 additions and 3 deletions
  1. 1 0
      doc/CHANGES.txt
  2. 1 1
      std/List.hx
  3. 6 1
      type.ml
  4. 3 1
      typer.ml

+ 1 - 0
doc/CHANGES.txt

@@ -4,6 +4,7 @@
 	haxedoc : fixed type parameters display
 	fix for JS and Flash9 XML parser : allow newlines in attributes
 	disable Flash9 resources with AS3Gen
+	error on extra anonymous fields
 
 2007-07-25: 1.14
 	fixed no error when invalid "catch" expression

+ 1 - 1
std/List.hx

@@ -153,7 +153,7 @@ class List<T> {
 		Returns an iterator on the elements of the list.
 	**/
 	public function iterator() : Iterator<T> {
-		return {
+		return cast {
 			h : h,
 			hasNext : function() {
 				return untyped (this.h != null);

+ 6 - 1
type.ml

@@ -171,6 +171,7 @@ type module_def = {
 let mk e t p = { eexpr = e; etype = t; epos = p }
 
 let not_opened = ref Closed
+let const_status = ref Closed
 let static_status = ref Statics
 let is_closed a = !(a.a_status) <> Opened
 let mk_anon fl = TAnon { a_fields = fl; a_status = not_opened; }
@@ -416,6 +417,7 @@ type unify_error =
 	| Cannot_unify of t * t
 	| Invalid_field_type of string
 	| Has_no_field of t * string
+	| Has_extra_field of t * string
 	| Invalid_access of string * bool * field_access * field_access
 	| Invalid_visibility of string
 	| Not_matching_optional of string
@@ -428,6 +430,7 @@ let invalid_field n = Invalid_field_type n
 let invalid_access n get a b = Invalid_access (n,get,a,b)
 let invalid_visibility n = Invalid_visibility n
 let has_no_field t n = Has_no_field (t,n)
+let has_extra_field t n = Has_extra_field (t,n)
 let error l = raise (Unify_error l)
 
 let unify_access a1 a2 =
@@ -648,9 +651,11 @@ let rec unify a b =
 			with
 				Not_found ->
 					if is_closed a1 then error [has_no_field a n];
-					if not (link (ref None) a f2.cf_type) then error [cannot_unify a b];
+					if not (link (ref None) a f2.cf_type) then error [];
 					a1.a_fields <- PMap.add n f2 a1.a_fields
 			) a2.a_fields;
+			if a1.a_status == const_status && not (PMap.is_empty a2.a_fields) then
+				PMap.iter (fun n _ -> if not (PMap.mem n a2.a_fields) then error [has_extra_field a n]) a1.a_fields;
 			if !(a1.a_status) = Opened then a1.a_status := Closed;
 			if !(a2.a_status) = Opened then a2.a_status := Closed;
 		with

+ 3 - 1
typer.ml

@@ -90,6 +90,8 @@ let unify_error_msg ctx = function
 		"Invalid type for field " ^ s ^ " :"
 	| Has_no_field (t,n) ->
 		s_type ctx t ^ " has no field " ^ n
+	| Has_extra_field (t,n) ->
+		s_type ctx t ^ " has extra field " ^ n
 	| Invalid_access (f,get,a,b) ->
 		"Inconsistent " ^ (if get then "getter" else "setter") ^ " for field " ^ f ^ " : " ^ access_str a ^ " should be " ^ access_str b
 	| Invalid_visibility n ->
@@ -1708,7 +1710,7 @@ and type_expr ctx ?(need_val=true) (e,p) =
 			((f,e) :: l, PMap.add f cf acc)
 		in
 		let fields , types = List.fold_left loop ([],PMap.empty) fl in
-		mk (TObjectDecl fields) (mk_anon types) p
+		mk (TObjectDecl fields) (TAnon { a_fields = types; a_status = const_status }) p
 	| EArrayDecl el ->
 		let t = ref (mk_mono()) in
 		let el = List.map (fun e ->