@@ -3,8 +3,9 @@ import syntax::visit;
3
3
4
4
fn check_crate ( tcx : & ty:: ctxt , crate : & @crate ) {
5
5
let v =
6
- @{ visit_expr: bind check_expr ( tcx , _, _, _)
7
- with * visit:: default_visitor [ ( ) ] ( ) } ;
6
+ @{ visit_expr: bind check_expr ( tcx , _, _, _) ,
7
+ visit_local : bind check_local ( tcx , _, _, _)
8
+ with * visit:: default_visitor [ ( ) ] ( ) } ;
8
9
visit:: visit_crate ( * crate, ( ) , visit:: mk_vt ( v ) ) ;
9
10
tcx. sess . abort_if_errors ( ) ;
10
11
}
@@ -92,6 +93,38 @@ fn pattern_supersedes(tcx: &ty::ctxt, a: &@pat, b: &@pat) -> bool {
92
93
}
93
94
}
94
95
96
+ fn check_local ( tcx : & ty:: ctxt , loc : & @local , s : & ( ) , v : & visit:: vt [ ( ) ] ) {
97
+ visit:: visit_local ( loc, s, v) ;
98
+ if is_refutable ( tcx, loc. node . pat ) {
99
+ tcx. sess . span_err ( loc. node . pat . span ,
100
+ "refutable pattern in local binding" ) ;
101
+ }
102
+ }
103
+
104
+ fn is_refutable ( tcx : & ty:: ctxt , pat: & @pat) -> bool {
105
+ alt pat. node {
106
+ pat_wild. | pat_bind ( _) { ret false ; }
107
+ pat_lit ( _) { ret true ; }
108
+ pat_box ( sub) { ret is_refutable ( tcx, sub) ; }
109
+ pat_rec ( fields, _) {
110
+ for field: field_pat in fields {
111
+ if is_refutable ( tcx, field. pat ) { ret true ; }
112
+ }
113
+ ret false;
114
+ }
115
+ pat_tag ( _, args) {
116
+ let vdef = variant_def_ids ( tcx. def_map . get ( pat. id ) ) ;
117
+ if std:: ivec:: len ( ty:: tag_variants ( tcx, vdef. tg ) ) != 1 u {
118
+ ret true ;
119
+ }
120
+ for p: @pat in args {
121
+ if is_refutable ( tcx, p) { ret true ; }
122
+ }
123
+ ret false;
124
+ }
125
+ }
126
+ }
127
+
95
128
// Local Variables:
96
129
// mode: rust
97
130
// fill-column: 78;
0 commit comments