@@ -17,8 +17,9 @@ import syntax::ast::{ident, trait_ref, impure_fn, instance_var, item};
17
17
import syntax:: ast:: { item_class, item_const, item_enum, item_fn, item_mac} ;
18
18
import syntax:: ast:: { item_foreign_mod, item_trait, item_impl, item_mod} ;
19
19
import syntax:: ast:: { item_ty, local, local_crate, method, node_id, pat} ;
20
- import syntax:: ast:: { pat_enum, pat_ident, pat_lit, pat_range, path, prim_ty} ;
21
- import syntax:: ast:: { stmt_decl, ty} ;
20
+ import syntax:: ast:: { pat_enum, pat_ident, path, prim_ty, stmt_decl, ty,
21
+ pat_box, pat_uniq, pat_lit, pat_range, pat_rec,
22
+ pat_tup, pat_wild} ;
22
23
import syntax:: ast:: { ty_bool, ty_char, ty_constr, ty_f, ty_f32, ty_f64} ;
23
24
import syntax:: ast:: { ty_float, ty_i, ty_i16, ty_i32, ty_i64, ty_i8, ty_int} ;
24
25
import syntax:: ast:: { ty_param, ty_path, ty_str, ty_u, ty_u16, ty_u32, ty_u64} ;
@@ -28,6 +29,7 @@ import syntax::ast::{view_path_list, view_path_simple};
28
29
import syntax:: ast_util:: { def_id_of_def, dummy_sp, local_def, new_def_hash} ;
29
30
import syntax:: ast_util:: { walk_pat} ;
30
31
import syntax:: attr:: { attr_metas, contains_name} ;
32
+ import syntax:: print:: pprust:: path_to_str;
31
33
import syntax:: codemap:: span;
32
34
import syntax:: visit:: { default_visitor, fk_method, mk_vt, visit_block} ;
33
35
import syntax:: visit:: { visit_crate, visit_expr, visit_expr_opt, visit_fn} ;
@@ -3384,6 +3386,40 @@ class Resolver {
3384
3386
none, visitor) ;
3385
3387
}
3386
3388
3389
+ fn num_bindings( pat: @pat) -> uint {
3390
+ pat_util:: pat_binding_ids( self . def_map, pat) . len( )
3391
+ }
3392
+
3393
+ fn warn_var_patterns( arm: arm) {
3394
+ /*
3395
+ The idea here is that an arm like:
3396
+ alpha | beta
3397
+ where alpha is a variant and beta is an identifier that
3398
+ might refer to a variant that's not in scope will result
3399
+ in a confusing error message. Showing that beta actually binds a
3400
+ new variable might help.
3401
+ */
3402
+ for arm. pats. each |p| {
3403
+ do pat_util:: pat_bindings( self . def_map, p) |_id, sp, pth| {
3404
+ self . session. span_note( sp, #fmt( "Treating %s as a variable \
3405
+ binding, because it does not denote any variant in scope",
3406
+ path_to_str( pth) ) ) ;
3407
+ }
3408
+ } ;
3409
+ }
3410
+ fn check_consistent_bindings( arm: arm) {
3411
+ if arm. pats. len( ) == 0 { ret; }
3412
+ let good = self . num_bindings( arm. pats[ 0 ] ) ;
3413
+ for arm. pats. each( ) |p: @pat| {
3414
+ if self . num_bindings( p) != good {
3415
+ self. session. span_err( p. span,
3416
+ "inconsistent number of bindings" ) ;
3417
+ self . warn_var_patterns( arm) ;
3418
+ break ;
3419
+ } ;
3420
+ } ;
3421
+ }
3422
+
3387
3423
fn resolve_arm( arm: arm, visitor: ResolveVisitor ) {
3388
3424
( * self . value_ribs) . push( @Rib ( NormalRibKind ) ) ;
3389
3425
@@ -3393,6 +3429,10 @@ class Resolver {
3393
3429
some( bindings_list) , visitor) ;
3394
3430
}
3395
3431
3432
+ // This has to happen *after* we determine which
3433
+ // pat_idents are variants
3434
+ self . check_consistent_bindings( arm) ;
3435
+
3396
3436
visit_expr_opt( arm. guard, ( ) , visitor) ;
3397
3437
self . resolve_block( arm. body, visitor) ;
3398
3438
0 commit comments