From 8967c4b409396edf610967b329f0bf6cbcee4a2f Mon Sep 17 00:00:00 2001 From: Niko Matsakis <niko@alum.mit.edu> Date: Wed, 11 Apr 2012 09:14:09 -0700 Subject: [PATCH] simplify demand module --- src/rustc/middle/typeck.rs | 87 ++++++++++---------------------------- 1 file changed, 23 insertions(+), 64 deletions(-) diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs index b3a07cb2114..add63e357e2 100644 --- a/src/rustc/middle/typeck.rs +++ b/src/rustc/middle/typeck.rs @@ -1402,59 +1402,13 @@ fn require_same_types( } mod demand { - fn simple(fcx: @fn_ctxt, sp: span, expected: ty::t, actual: ty::t) -> - ty::t { - full(fcx, sp, unify::unify, expected, actual, []).ty - } - - // n.b.: order of arguments is reversed. - fn subty(fcx: @fn_ctxt, sp: span, actual: ty::t, expected: ty::t) { - full(fcx, sp, unify::unify, expected, actual, []); - } - - fn with_substs(fcx: @fn_ctxt, sp: span, expected: ty::t, actual: ty::t, - ty_param_substs_0: [ty::t]) -> ty_param_substs_and_ty { - full(fcx, sp, unify::unify, expected, actual, ty_param_substs_0) - } - // Requires that the two types unify, and prints an error message if they - // don't. Returns the unified type and the type parameter substitutions. - fn full(fcx: @fn_ctxt, - sp: span, - unifier: fn@(@fn_ctxt, ty::t, ty::t) - -> result<(), ty::type_err>, - expected: ty::t, - actual: ty::t, - ty_param_substs_0: [ty::t]) -> - ty_param_substs_and_ty { + // don't. + fn simple(fcx: @fn_ctxt, sp: span, + expected: ty::t, actual: ty::t) { - let mut ty_param_substs: [mut ty::t] = [mut]; - let mut ty_param_subst_var_ids: [ty_vid] = []; - for ty_param_substs_0.each {|ty_param_subst| - // Generate a type variable and unify it with the type parameter - // substitution. We will then pull out these type variables. - let t_0 = next_ty_var(fcx); - ty_param_substs += [mut t_0]; - ty_param_subst_var_ids += [ty::ty_var_id(t_0)]; - simple(fcx, sp, ty_param_subst, t_0); - } - - fn mk_result(fcx: @fn_ctxt, result_ty: ty::t, - ty_param_subst_var_ids: [ty_vid]) -> - ty_param_substs_and_ty { - let mut result_ty_param_substs: [ty::t] = []; - for ty_param_subst_var_ids.each {|var_id| - let tp_subst = ty::mk_var(fcx.ccx.tcx, var_id); - result_ty_param_substs += [tp_subst]; - } - ret {substs: result_ty_param_substs, ty: result_ty}; - } - - - alt unifier(fcx, expected, actual) { - result::ok(()) { - ret mk_result(fcx, expected, ty_param_subst_var_ids); - } + alt infer::mk_subty(fcx.infcx, actual, expected) { + result::ok(()) { /* ok */ } result::err(err) { fcx.ccx.tcx.sess.span_err(sp, "mismatched types: expected `" + @@ -1465,7 +1419,6 @@ mod demand { ty::type_err_to_str( fcx.ccx.tcx, err) + ")"); - ret mk_result(fcx, expected, ty_param_subst_var_ids); } } } @@ -1938,20 +1891,27 @@ fn universally_quantify_before_call( fn check_pat_variant(pcx: pat_ctxt, pat: @ast::pat, path: @ast::path, subpats: [@ast::pat], expected: ty::t) { + // Typecheck the path. let fcx = pcx.fcx; let tcx = pcx.fcx.ccx.tcx; + + // Lookup the enum and variant def ids: let v_def = lookup_def(pcx.fcx, path.span, pat.id); let v_def_ids = ast_util::variant_def_ids(v_def); - let ctor_tpt = ty::lookup_item_type(tcx, v_def_ids.enm); - instantiate_path(pcx.fcx, path, ctor_tpt, pat.span, pat.id); + + // Assign the pattern the type of the *enum*, not the variant. + let enum_tpt = ty::lookup_item_type(tcx, v_def_ids.enm); + instantiate_path(pcx.fcx, path, enum_tpt, pat.span, pat.id); // Take the enum type params out of `expected`. alt structure_of(pcx.fcx, pat.span, expected) { ty::ty_enum(_, expected_tps) { - let ctor_ty = fcx.node_ty(pat.id); - demand::with_substs(pcx.fcx, pat.span, expected, ctor_ty, - expected_tps); + // check that the type of the value being matched is a subtype + // of the type of the pattern: + let pat_ty = fcx.node_ty(pat.id); + demand::simple(fcx, pat.span, pat_ty, expected); + // Get the number of arguments in this enum variant. let arg_types = variant_arg_types(pcx.fcx.ccx, pat.span, v_def_ids.var, expected_tps); @@ -2029,12 +1989,12 @@ fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) { if !pat_util::pat_is_variant(tcx.def_map, pat) { let vid = lookup_local(pcx.fcx, pat.span, pat.id); let mut typ = ty::mk_var(tcx, vid); - typ = demand::simple(pcx.fcx, pat.span, expected, typ); + demand::simple(pcx.fcx, pat.span, expected, typ); let canon_id = pcx.map.get(path_to_ident(name)); if canon_id != pat.id { let tv_id = lookup_local(pcx.fcx, pat.span, canon_id); let ct = ty::mk_var(tcx, tv_id); - typ = demand::simple(pcx.fcx, pat.span, ct, typ); + demand::simple(pcx.fcx, pat.span, ct, typ); } fcx.write_ty(pat.id, typ); alt sub { @@ -2203,12 +2163,11 @@ fn require_pure_call(ccx: @crate_ctxt, caller_purity: ast::purity, } } -type unifier = fn@(@fn_ctxt, span, ty::t, ty::t) -> ty::t; +type unifier = fn@(@fn_ctxt, span, ty::t, ty::t); fn check_expr(fcx: @fn_ctxt, expr: @ast::expr) -> bool { - fn dummy_unify(_fcx: @fn_ctxt, _sp: span, _expected: ty::t, actual: ty::t) - -> ty::t { - actual + fn dummy_unify(_fcx: @fn_ctxt, _sp: span, + _expected: ty::t, _actual: ty::t) { } ret check_expr_with_unifier(fcx, expr, dummy_unify, ty::mk_nil(fcx.ccx.tcx)); @@ -3139,7 +3098,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier, } if !check_block(fcx, arm.body) { arm_non_bot = true; } let bty = fcx.node_ty(arm.body.node.id); - result_ty = demand::simple(fcx, arm.body.span, result_ty, bty); + demand::simple(fcx, arm.body.span, result_ty, bty); } bot |= !arm_non_bot; if !arm_non_bot { result_ty = ty::mk_bot(tcx); }