From a38ccf12547b1bdb37dce3c7edca5b95a898326a Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 13 Mar 2012 14:41:18 -0700 Subject: [PATCH] rustc: Thread the use site around in ast_ty_to_ty --- src/rustc/middle/typeck.rs | 305 ++++++++++++++++++++----------------- 1 file changed, 161 insertions(+), 144 deletions(-) diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs index 337b22663856..8341c8f2e7b3 100644 --- a/src/rustc/middle/typeck.rs +++ b/src/rustc/middle/typeck.rs @@ -247,8 +247,9 @@ enum mode { m_collect, m_check, m_check_tyvar(@fn_ctxt), } // internal notion of a type. `getter` is a function that returns the type // corresponding to a definition ID: fn ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty) -> ty::t { - fn getter(tcx: ty::ctxt, mode: mode, id: ast::def_id) - -> ty::ty_param_bounds_and_ty { + fn getter(tcx: ty::ctxt, _use_site: ast::node_id, mode: mode, + id: ast::def_id) -> ty::ty_param_bounds_and_ty { + // FIXME (pcwalton): Doesn't work with region inference. alt mode { m_check | m_check_tyvar(_) { ty::lookup_item_type(tcx, id) } m_collect { @@ -269,23 +270,14 @@ fn ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty) -> ty::t { } } } - alt tcx.ast_ty_to_ty_cache.find(ast_ty) { - some(ty::atttce_resolved(ty)) { ret ty; } - some(ty::atttce_unresolved) { - tcx.sess.span_fatal(ast_ty.span, "illegal recursive type. \ - insert a enum in the cycle, \ - if this is desired)"); - } - some(ty::atttce_has_regions) | none { /* go on */ } + fn ast_mt_to_mt(tcx: ty::ctxt, use_site: ast::node_id, mode: mode, + mt: ast::mt) -> ty::mt { + ret {ty: do_ast_ty_to_ty(tcx, use_site, mode, mt.ty), + mutbl: mt.mutbl}; } - - tcx.ast_ty_to_ty_cache.insert(ast_ty, ty::atttce_unresolved); - fn ast_mt_to_mt(tcx: ty::ctxt, mode: mode, mt: ast::mt) -> ty::mt { - ret {ty: ast_ty_to_ty(tcx, mode, mt.ty), mutbl: mt.mutbl}; - } - fn instantiate(tcx: ty::ctxt, sp: span, mode: mode, - id: ast::def_id, args: [@ast::ty]) -> ty::t { - let ty_param_bounds_and_ty = getter(tcx, mode, id); + fn instantiate(tcx: ty::ctxt, use_site: ast::node_id, sp: span, + mode: mode, id: ast::def_id, args: [@ast::ty]) -> ty::t { + let ty_param_bounds_and_ty = getter(tcx, use_site, mode, id); if vec::len(*ty_param_bounds_and_ty.bounds) == 0u { ret ty_param_bounds_and_ty.ty; } @@ -297,142 +289,167 @@ fn ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty) -> ty::t { polymorphic type"); } for ast_ty: @ast::ty in args { - param_bindings += [ast_ty_to_ty(tcx, mode, ast_ty)]; + param_bindings += [do_ast_ty_to_ty(tcx, use_site, mode, ast_ty)]; } let typ = ty::substitute_type_params(tcx, param_bindings, ty_param_bounds_and_ty.ty); ret typ; } - let typ = alt ast_ty.node { - ast::ty_nil { ty::mk_nil(tcx) } - ast::ty_bot { ty::mk_bot(tcx) } - ast::ty_box(mt) { - ty::mk_box(tcx, ast_mt_to_mt(tcx, mode, mt)) - } - ast::ty_uniq(mt) { - ty::mk_uniq(tcx, ast_mt_to_mt(tcx, mode, mt)) - } - ast::ty_vec(mt) { - ty::mk_vec(tcx, ast_mt_to_mt(tcx, mode, mt)) - } - ast::ty_ptr(mt) { - ty::mk_ptr(tcx, ast_mt_to_mt(tcx, mode, mt)) - } - ast::ty_rptr(region, mt) { - let region = alt region.node { - ast::re_inferred | ast::re_self { - tcx.region_map.ast_type_to_inferred_region.get(ast_ty.id) - } - ast::re_named(_) { - tcx.region_map.ast_type_to_region.get(region.id) - } - }; - ty::mk_rptr(tcx, region, ast_mt_to_mt(tcx, mode, mt)) - } - ast::ty_tup(fields) { - let flds = vec::map(fields, bind ast_ty_to_ty(tcx, mode, _)); - ty::mk_tup(tcx, flds) - } - ast::ty_rec(fields) { - let flds: [field] = []; - for f: ast::ty_field in fields { - let tm = ast_mt_to_mt(tcx, mode, f.node.mt); - flds += [{ident: f.node.ident, mt: tm}]; + fn do_ast_ty_to_ty(tcx: ty::ctxt, use_site: ast::node_id, mode: mode, + &&ast_ty: @ast::ty) -> ty::t { + alt tcx.ast_ty_to_ty_cache.find(ast_ty) { + some(ty::atttce_resolved(ty)) { ret ty; } + some(ty::atttce_unresolved) { + tcx.sess.span_fatal(ast_ty.span, "illegal recursive type. \ + insert a enum in the cycle, \ + if this is desired)"); + } + some(ty::atttce_has_regions) | none { /* go on */ } } - ty::mk_rec(tcx, flds) - } - ast::ty_fn(proto, decl) { - ty::mk_fn(tcx, ty_of_fn_decl(tcx, mode, proto, decl)) - } - ast::ty_path(path, id) { - let a_def = alt tcx.def_map.find(id) { - none { tcx.sess.span_fatal(ast_ty.span, #fmt("unbound path %s", - path_to_str(path))); } - some(d) { d }}; - alt a_def { - ast::def_ty(id) { - instantiate(tcx, ast_ty.span, mode, id, path.node.types) - } - ast::def_prim_ty(nty) { - alt nty { - ast::ty_bool { ty::mk_bool(tcx) } - ast::ty_int(it) { ty::mk_mach_int(tcx, it) } - ast::ty_uint(uit) { ty::mk_mach_uint(tcx, uit) } - ast::ty_float(ft) { ty::mk_mach_float(tcx, ft) } - ast::ty_str { ty::mk_str(tcx) } - } - } - ast::def_ty_param(id, n) { - if vec::len(path.node.types) > 0u { - tcx.sess.span_err(ast_ty.span, "provided type parameters to \ - a type parameter"); - } - ty::mk_param(tcx, n, id) - } - ast::def_self(self_id) { - alt check tcx.items.get(self_id) { - ast_map::node_item(@{node: ast::item_iface(tps, _), _}, _) { - if vec::len(tps) != vec::len(path.node.types) { - tcx.sess.span_err(ast_ty.span, "incorrect number of type \ - parameter to self type"); - } - ty::mk_self(tcx, vec::map(path.node.types, {|ast_ty| - ast_ty_to_ty(tcx, mode, ast_ty) - })) - } - } - } - ast::def_class(class_id) { - alt tcx.items.find(class_id.node) { - some(ast_map::node_item( - @{node: ast::item_class(tps, _, _), _}, _)) { - if vec::len(tps) != vec::len(path.node.types) { - tcx.sess.span_err(ast_ty.span, "incorrect number of \ - type parameters to object type"); - } - ty::mk_class(tcx, class_id, vec::map(path.node.types, - {|ast_ty| ast_ty_to_ty(tcx, mode, ast_ty)})) - } - _ { - tcx.sess.span_bug(ast_ty.span, "class id is unbound \ - in items"); - } - } - } - _ { - tcx.sess.span_fatal(ast_ty.span, - "found type name used as a variable"); - } - } - } - ast::ty_constr(t, cs) { - let out_cs = []; - for constr: @ast::ty_constr in cs { - out_cs += [ty::ast_constr_to_constr(tcx, constr)]; - } - ty::mk_constr(tcx, ast_ty_to_ty(tcx, mode, t), out_cs) - } - ast::ty_infer { - alt mode { - m_check_tyvar(fcx) { ret next_ty_var(fcx); } - _ { tcx.sess.span_bug(ast_ty.span, - "found `ty_infer` in unexpected place"); } - } - } - ast::ty_mac(_) { - tcx.sess.span_bug(ast_ty.span, - "found `ty_mac` in unexpected place"); - } - }; - if ty::type_has_rptrs(typ) { - tcx.ast_ty_to_ty_cache.insert(ast_ty, ty::atttce_has_regions); - } else { - tcx.ast_ty_to_ty_cache.insert(ast_ty, ty::atttce_resolved(typ)); + tcx.ast_ty_to_ty_cache.insert(ast_ty, ty::atttce_unresolved); + let typ = alt ast_ty.node { + ast::ty_nil { ty::mk_nil(tcx) } + ast::ty_bot { ty::mk_bot(tcx) } + ast::ty_box(mt) { + ty::mk_box(tcx, ast_mt_to_mt(tcx, use_site, mode, mt)) + } + ast::ty_uniq(mt) { + ty::mk_uniq(tcx, ast_mt_to_mt(tcx, use_site, mode, mt)) + } + ast::ty_vec(mt) { + ty::mk_vec(tcx, ast_mt_to_mt(tcx, use_site, mode, mt)) + } + ast::ty_ptr(mt) { + ty::mk_ptr(tcx, ast_mt_to_mt(tcx, use_site, mode, mt)) + } + ast::ty_rptr(region, mt) { + let region = alt region.node { + ast::re_inferred | ast::re_self { + tcx.region_map.ast_type_to_inferred_region.get(ast_ty.id) + } + ast::re_named(_) { + tcx.region_map.ast_type_to_region.get(region.id) + } + }; + ty::mk_rptr(tcx, region, ast_mt_to_mt(tcx, use_site, mode, mt)) + } + ast::ty_tup(fields) { + let flds = vec::map(fields, + bind do_ast_ty_to_ty(tcx, use_site, mode, _)); + ty::mk_tup(tcx, flds) + } + ast::ty_rec(fields) { + let flds: [field] = []; + for f: ast::ty_field in fields { + let tm = ast_mt_to_mt(tcx, use_site, mode, f.node.mt); + flds += [{ident: f.node.ident, mt: tm}]; + } + ty::mk_rec(tcx, flds) + } + ast::ty_fn(proto, decl) { + ty::mk_fn(tcx, ty_of_fn_decl(tcx, mode, proto, decl)) + } + ast::ty_path(path, id) { + let a_def = alt tcx.def_map.find(id) { + none { tcx.sess.span_fatal(ast_ty.span, #fmt("unbound path %s", + path_to_str(path))); } + some(d) { d }}; + alt a_def { + ast::def_ty(id) { + instantiate(tcx, use_site, ast_ty.span, mode, id, + path.node.types) + } + ast::def_prim_ty(nty) { + alt nty { + ast::ty_bool { ty::mk_bool(tcx) } + ast::ty_int(it) { ty::mk_mach_int(tcx, it) } + ast::ty_uint(uit) { ty::mk_mach_uint(tcx, uit) } + ast::ty_float(ft) { ty::mk_mach_float(tcx, ft) } + ast::ty_str { ty::mk_str(tcx) } + } + } + ast::def_ty_param(id, n) { + if vec::len(path.node.types) > 0u { + tcx.sess.span_err(ast_ty.span, "provided type parameters \ + to a type parameter"); + } + ty::mk_param(tcx, n, id) + } + ast::def_self(self_id) { + alt check tcx.items.get(self_id) { + ast_map::node_item(@{node: ast::item_iface(tps, _), _}, _) { + if vec::len(tps) != vec::len(path.node.types) { + tcx.sess.span_err(ast_ty.span, "incorrect number of \ + type parameters to \ + self type"); + } + ty::mk_self(tcx, vec::map(path.node.types, {|ast_ty| + do_ast_ty_to_ty(tcx, use_site, mode, ast_ty) + })) + } + } + } + ast::def_class(class_id) { + alt tcx.items.find(class_id.node) { + some(ast_map::node_item( + @{node: ast::item_class(tps, _, _), _}, _)) { + if vec::len(tps) != vec::len(path.node.types) { + tcx.sess.span_err(ast_ty.span, "incorrect number \ + of type parameters to object type"); + } + ty::mk_class(tcx, class_id, + vec::map(path.node.types, {|ast_ty| + do_ast_ty_to_ty(tcx, + use_site, + mode, + ast_ty) + })) + } + _ { + tcx.sess.span_bug(ast_ty.span, "class id is unbound \ + in items"); + } + } + } + _ { + tcx.sess.span_fatal(ast_ty.span, + "found type name used as a variable"); + } + } + } + ast::ty_constr(t, cs) { + let out_cs = []; + for constr: @ast::ty_constr in cs { + out_cs += [ty::ast_constr_to_constr(tcx, constr)]; + } + ty::mk_constr(tcx, do_ast_ty_to_ty(tcx, use_site, mode, t), + out_cs) + } + ast::ty_infer { + alt mode { + m_check_tyvar(fcx) { ret next_ty_var(fcx); } + _ { tcx.sess.span_bug(ast_ty.span, + "found `ty_infer` in unexpected place"); } + } + } + ast::ty_mac(_) { + tcx.sess.span_bug(ast_ty.span, + "found `ty_mac` in unexpected place"); + } + }; + + if ty::type_has_rptrs(typ) { + tcx.ast_ty_to_ty_cache.insert(ast_ty, ty::atttce_has_regions); + } else { + tcx.ast_ty_to_ty_cache.insert(ast_ty, ty::atttce_resolved(typ)); + } + + ret typ; } - ret typ; + ret do_ast_ty_to_ty(tcx, ast_ty.id, mode, ast_ty); } fn ty_of_item(tcx: ty::ctxt, mode: mode, it: @ast::item)