Skip to content

Commit 0a22a4e

Browse files
committed
rustc: Factor out path type instantiation so that tag patterns can use it as well
1 parent e64085b commit 0a22a4e

File tree

1 file changed

+108
-103
lines changed

1 file changed

+108
-103
lines changed

src/comp/middle/typeck.rs

Lines changed: 108 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,112 @@ fn substitute_ty_params(&@crate_ctxt ccx,
128128
ret ty.fold_ty(substituter, typ);
129129
}
130130

131+
// Instantiates the given path, which must refer to an item with the given
132+
// definition.
133+
fn instantiate_path(@fn_ctxt fcx, &ast.path pth, &ast.def defn, &span sp)
134+
-> ast.ann {
135+
auto t;
136+
auto ty_params;
137+
alt (defn) {
138+
case (ast.def_arg(?id)) {
139+
check (fcx.locals.contains_key(id));
140+
t = fcx.locals.get(id);
141+
ty_params = none[vec[ast.def_id]];
142+
}
143+
case (ast.def_local(?id)) {
144+
alt (fcx.locals.find(id)) {
145+
case (some[@ty.t](?t1)) { t = t1; }
146+
case (none[@ty.t]) { t = plain_ty(ty.ty_local(id)); }
147+
}
148+
ty_params = none[vec[ast.def_id]];
149+
}
150+
case (ast.def_obj_field(?id)) {
151+
check (fcx.locals.contains_key(id));
152+
t = fcx.locals.get(id);
153+
ty_params = none[vec[ast.def_id]];
154+
}
155+
case (ast.def_fn(?id)) {
156+
check (fcx.ccx.item_types.contains_key(id));
157+
t = fcx.ccx.item_types.get(id);
158+
ty_params = some(fcx.ccx.item_ty_params.get(id));
159+
}
160+
case (ast.def_native_fn(?id)) {
161+
check (fcx.ccx.item_types.contains_key(id));
162+
t = fcx.ccx.item_types.get(id);
163+
ty_params = some(fcx.ccx.item_ty_params.get(id));
164+
}
165+
case (ast.def_const(?id)) {
166+
check (fcx.ccx.item_types.contains_key(id));
167+
t = fcx.ccx.item_types.get(id);
168+
ty_params = none[vec[ast.def_id]];
169+
}
170+
case (ast.def_variant(?tag_id, ?variant_id)) {
171+
check (fcx.ccx.item_types.contains_key(variant_id));
172+
t = fcx.ccx.item_types.get(variant_id);
173+
ty_params = some(fcx.ccx.item_ty_params.get(tag_id));
174+
}
175+
case (ast.def_binding(?id)) {
176+
check (fcx.locals.contains_key(id));
177+
t = fcx.locals.get(id);
178+
ty_params = none[vec[ast.def_id]];
179+
}
180+
case (ast.def_obj(?id)) {
181+
check (fcx.ccx.item_types.contains_key(id));
182+
t = fcx.ccx.item_types.get(id);
183+
ty_params = some(fcx.ccx.item_ty_params.get(id));
184+
}
185+
186+
case (ast.def_mod(_)) {
187+
// Hopefully part of a path.
188+
t = plain_ty(ty.ty_nil); // TODO: something more poisonous?
189+
ty_params = none[vec[ast.def_id]];
190+
}
191+
192+
case (_) {
193+
// FIXME: handle other names.
194+
fcx.ccx.sess.unimpl("definition variant for: "
195+
+ _str.connect(pth.node.idents, "."));
196+
fail;
197+
}
198+
}
199+
200+
auto ty_substs_opt;
201+
auto ty_substs_len = _vec.len[@ast.ty](pth.node.types);
202+
if (ty_substs_len > 0u) {
203+
let vec[@ty.t] ty_substs = vec();
204+
auto i = 0u;
205+
while (i < ty_substs_len) {
206+
ty_substs += vec(ast_ty_to_ty_crate(fcx.ccx, pth.node.types.(i)));
207+
i += 1u;
208+
}
209+
ty_substs_opt = some[vec[@ty.t]](ty_substs);
210+
211+
alt (ty_params) {
212+
case (none[vec[ast.def_id]]) {
213+
fcx.ccx.sess.span_err(sp, "this kind of item may not take " +
214+
"type parameters");
215+
fail;
216+
}
217+
case (some[vec[ast.def_id]](?tps)) {
218+
t = substitute_ty_params(fcx.ccx, t, tps, ty_substs, sp);
219+
}
220+
}
221+
} else {
222+
ty_substs_opt = none[vec[@ty.t]];
223+
224+
alt (ty_params) {
225+
case (none[vec[ast.def_id]]) { /* nothing */ }
226+
case (some[vec[ast.def_id]](_)) {
227+
// We will acquire the type parameters through
228+
// unification.
229+
t = generalize_ty(fcx.ccx, t);
230+
}
231+
}
232+
}
233+
234+
ret ast.ann_type(t, ty_substs_opt);
235+
}
236+
131237
// Returns the type parameters and polytype of an item, if it's an item that
132238
// supports type parameters.
133239
fn ty_params_for_item(@crate_ctxt ccx, &ast.def d)
@@ -1561,109 +1667,8 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
15611667
case (ast.expr_path(?pth, ?defopt, _)) {
15621668
auto t = plain_ty(ty.ty_nil);
15631669
check (defopt != none[ast.def]);
1564-
1565-
auto ty_params;
1566-
alt (option.get[ast.def](defopt)) {
1567-
case (ast.def_arg(?id)) {
1568-
check (fcx.locals.contains_key(id));
1569-
t = fcx.locals.get(id);
1570-
ty_params = none[vec[ast.def_id]];
1571-
}
1572-
case (ast.def_local(?id)) {
1573-
alt (fcx.locals.find(id)) {
1574-
case (some[@ty.t](?t1)) { t = t1; }
1575-
case (none[@ty.t]) { t = plain_ty(ty.ty_local(id)); }
1576-
}
1577-
ty_params = none[vec[ast.def_id]];
1578-
}
1579-
case (ast.def_obj_field(?id)) {
1580-
check (fcx.locals.contains_key(id));
1581-
t = fcx.locals.get(id);
1582-
ty_params = none[vec[ast.def_id]];
1583-
}
1584-
case (ast.def_fn(?id)) {
1585-
check (fcx.ccx.item_types.contains_key(id));
1586-
t = fcx.ccx.item_types.get(id);
1587-
ty_params = some(fcx.ccx.item_ty_params.get(id));
1588-
}
1589-
case (ast.def_native_fn(?id)) {
1590-
check (fcx.ccx.item_types.contains_key(id));
1591-
t = fcx.ccx.item_types.get(id);
1592-
ty_params = some(fcx.ccx.item_ty_params.get(id));
1593-
}
1594-
case (ast.def_const(?id)) {
1595-
check (fcx.ccx.item_types.contains_key(id));
1596-
t = fcx.ccx.item_types.get(id);
1597-
ty_params = none[vec[ast.def_id]];
1598-
}
1599-
case (ast.def_variant(?tag_id, ?variant_id)) {
1600-
check (fcx.ccx.item_types.contains_key(variant_id));
1601-
t = fcx.ccx.item_types.get(variant_id);
1602-
ty_params = some(fcx.ccx.item_ty_params.get(tag_id));
1603-
}
1604-
case (ast.def_binding(?id)) {
1605-
check (fcx.locals.contains_key(id));
1606-
t = fcx.locals.get(id);
1607-
ty_params = none[vec[ast.def_id]];
1608-
}
1609-
case (ast.def_obj(?id)) {
1610-
check (fcx.ccx.item_types.contains_key(id));
1611-
t = fcx.ccx.item_types.get(id);
1612-
ty_params = some(fcx.ccx.item_ty_params.get(id));
1613-
}
1614-
1615-
case (ast.def_mod(_)) {
1616-
// Hopefully part of a path.
1617-
ty_params = none[vec[ast.def_id]];
1618-
}
1619-
1620-
case (_) {
1621-
// FIXME: handle other names.
1622-
fcx.ccx.sess.unimpl("definition variant for: "
1623-
+ _str.connect(pth.node.idents, "."));
1624-
fail;
1625-
}
1626-
}
1627-
1628-
// Substitute type parameters if the user provided some.
1629-
auto ty_substs_opt;
1630-
auto ty_substs_len = _vec.len[@ast.ty](pth.node.types);
1631-
if (ty_substs_len > 0u) {
1632-
let vec[@ty.t] ty_substs = vec();
1633-
auto i = 0u;
1634-
while (i < ty_substs_len) {
1635-
ty_substs += vec(ast_ty_to_ty_crate(fcx.ccx,
1636-
pth.node.types.(i)));
1637-
i += 1u;
1638-
}
1639-
ty_substs_opt = some[vec[@ty.t]](ty_substs);
1640-
1641-
alt (ty_params) {
1642-
case (none[vec[ast.def_id]]) {
1643-
fcx.ccx.sess.span_err(expr.span, "this kind of " +
1644-
"item may not take type " +
1645-
"parameters");
1646-
fail;
1647-
}
1648-
case (some[vec[ast.def_id]](?tps)) {
1649-
t = substitute_ty_params(fcx.ccx, t, tps, ty_substs,
1650-
expr.span);
1651-
}
1652-
}
1653-
} else {
1654-
ty_substs_opt = none[vec[@ty.t]];
1655-
1656-
alt (ty_params) {
1657-
case (none[vec[ast.def_id]]) { /* nothing */ }
1658-
case (some[vec[ast.def_id]](_)) {
1659-
// We will acquire the type parameters through
1660-
// unification.
1661-
t = generalize_ty(fcx.ccx, t);
1662-
}
1663-
}
1664-
}
1665-
1666-
auto ann = ast.ann_type(t, ty_substs_opt);
1670+
auto defn = option.get[ast.def](defopt);
1671+
auto ann = instantiate_path(fcx, pth, defn, expr.span);
16671672
ret @fold.respan[ast.expr_](expr.span,
16681673
ast.expr_path(pth, defopt, ann));
16691674
}

0 commit comments

Comments
 (0)