<commit_before>import syntax::print::pprust;

fn check_alt(fcx: @fn_ctxt,
             expr: @ast::expr,
             discrim: @ast::expr,
             arms: ~[ast::arm]) -> bool {
    let tcx = fcx.ccx.tcx;
    let mut bot;

    let pattern_ty = fcx.infcx.next_ty_var();
    bot = check_expr_with(fcx, discrim, pattern_ty);

    // Typecheck the patterns first, so that we get types for all the
    // bindings.
    for arms.each |arm| {
        let pcx = {
            fcx: fcx,
            map: pat_id_map(tcx.def_map, arm.pats[0]),
            alt_region: ty::re_scope(expr.id),
            block_region: ty::re_scope(arm.body.node.id),
            pat_region: ty::re_scope(expr.id)
        };

        for arm.pats.each |p| { check_pat(pcx, p, pattern_ty);}
    }
    // Now typecheck the blocks.
    let mut result_ty = fcx.infcx.next_ty_var();
    let mut arm_non_bot = false;
    for arms.each |arm| {
        match arm.guard {
          some(e) => { check_expr_with(fcx, e, ty::mk_bool(tcx)); },
          none => ()
        }
        if !check_block(fcx, arm.body) { arm_non_bot = true; }
        let bty = fcx.node_ty(arm.body.node.id);
        demand::suptype(fcx, arm.body.span, result_ty, bty);
    }
    bot |= !arm_non_bot;
    if !arm_non_bot { result_ty = ty::mk_bot(tcx); }
    fcx.write_ty(expr.id, result_ty);
    return bot;
}

type pat_ctxt = {
    fcx: @fn_ctxt,
    map: pat_id_map,
    alt_region: ty::region,
    block_region: ty::region,
    /* Equal to either alt_region or block_region. */
    pat_region: ty::region
};

fn check_pat_variant(pcx: pat_ctxt, pat: @ast::pat, path: @ast::path,
                     subpats: option<~[@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);

    // 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`.
    match structure_of(pcx.fcx, pat.span, expected) {
      ty::ty_enum(_, ref expected_substs) => {
        // 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::suptype(fcx, pat.span, pat_ty, expected);

        // Get the expected types of the arguments.
        let arg_types = {
            let vinfo =
                ty::enum_variant_with_id(
                    tcx, v_def_ids.enm, v_def_ids.var);
            vinfo.args.map(|t| { ty::subst(tcx, expected_substs, t) })
        };
        let arg_len = arg_types.len(), subpats_len = match subpats {
            none => arg_len,
            some(ps) => ps.len()
        };
        if arg_len > 0u {
            // N-ary variant.
            if arg_len != subpats_len {
                let s = fmt!{"this pattern has %u field%s, but the \
                              corresponding variant has %u field%s",
                             subpats_len,
                             if subpats_len == 1u { ~"" } else { ~"s" },
                             arg_len,
                             if arg_len == 1u { ~"" } else { ~"s" }};
                tcx.sess.span_fatal(pat.span, s);
            }

            do option::iter(subpats) |pats| {
                do vec::iter2(pats, arg_types) |subpat, arg_ty| {
                  check_pat(pcx, subpat, arg_ty);
                }
            };
        } else if subpats_len > 0u {
            tcx.sess.span_fatal
                (pat.span, fmt!{"this pattern has %u field%s, \
                                 but the corresponding variant has no fields",
                                subpats_len,
                                if subpats_len == 1u { ~"" }
                                else { ~"s" }});
        }
      }
      _ => {
        tcx.sess.span_fatal
            (pat.span,
             fmt!{"mismatched types: expected enum but found `%s`",
                  fcx.infcx.ty_to_str(expected)});
      }
    }
}

// Pattern checking is top-down rather than bottom-up so that bindings get
// their types immediately.
fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) {
    let fcx = pcx.fcx;
    let tcx = pcx.fcx.ccx.tcx;

    match pat.node {
      ast::pat_wild => {
        fcx.write_ty(pat.id, expected);
      }
      ast::pat_lit(lt) => {
        check_expr_with(fcx, lt, expected);
        fcx.write_ty(pat.id, fcx.expr_ty(lt));
      }
      ast::pat_range(begin, end) => {
        check_expr_with(fcx, begin, expected);
        check_expr_with(fcx, end, expected);
        let b_ty =
            fcx.infcx.resolve_type_vars_if_possible(fcx.expr_ty(begin));
        let e_ty =
            fcx.infcx.resolve_type_vars_if_possible(fcx.expr_ty(end));
        debug!{"pat_range beginning type: %?", b_ty};
        debug!{"pat_range ending type: %?", e_ty};
        if !require_same_types(
            tcx, some(fcx.infcx), pat.span, b_ty, e_ty,
            || ~"mismatched types in range") {
            // no-op
        } else if !ty::type_is_numeric(b_ty) {
            tcx.sess.span_err(pat.span, ~"non-numeric type used in range");
        } else if !valid_range_bounds(fcx.ccx, begin, end) {
            tcx.sess.span_err(begin.span, ~"lower range bound must be less \
                                           than upper");
        }
        fcx.write_ty(pat.id, b_ty);
      }
      ast::pat_ident(bm, name, sub) if !pat_is_variant(tcx.def_map, pat) => {
        let vid = lookup_local(fcx, pat.span, pat.id);
        let mut typ = ty::mk_var(tcx, vid);

        match bm {
          ast::bind_by_ref(mutbl) => {
            // if the binding is like
            //    ref x | ref const x | ref mut x
            // then the type of x is &M T where M is the mutability
            // and T is the expected type
            let region_var =
                fcx.infcx.next_region_var({lb: some(pcx.block_region),
                                           ub: none});
            let mt = {ty: expected, mutbl: mutbl};
            let region_ty = ty::mk_rptr(tcx, region_var, mt);
            demand::eqtype(fcx, pat.span, region_ty, typ);
          }
          ast::bind_by_value | ast::bind_by_implicit_ref => {
            // otherwise the type of x is the expected type T
            demand::eqtype(fcx, pat.span, expected, typ);
          }
        }

        let canon_id = pcx.map.get(ast_util::path_to_ident(name));
        if canon_id != pat.id {
            let tv_id = lookup_local(fcx, pat.span, canon_id);
            let ct = ty::mk_var(tcx, tv_id);
            demand::eqtype(fcx, pat.span, ct, typ);
        }
        fcx.write_ty(pat.id, typ);
        match sub {
          some(p) => check_pat(pcx, p, expected),
          _ => ()
        }
      }
      ast::pat_ident(_, path, c) => {
        check_pat_variant(pcx, pat, path, some(~[]), expected);
      }
      ast::pat_enum(path, subpats) => {
        check_pat_variant(pcx, pat, path, subpats, expected);
      }
      ast::pat_rec(fields, etc) => {
        let ex_fields = match structure_of(fcx, pat.span, expected) {
          ty::ty_rec(fields) => fields,
          _ => {
            tcx.sess.span_fatal
                (pat.span,
                fmt!{"mismatched types: expected `%s` but found record",
                     fcx.infcx.ty_to_str(expected)});
          }
        };
        let f_count = vec::len(fields);
        let ex_f_count = vec::len(ex_fields);
        if ex_f_count < f_count || !etc && ex_f_count > f_count {
            tcx.sess.span_fatal
                (pat.span, fmt!{"mismatched types: expected a record \
                      with %u fields, found one with %u \
                      fields",
                                ex_f_count, f_count});
        }
        fn matches(name: ast::ident, f: ty::field) -> bool {
            str::eq(name, f.ident)
        }
        for fields.each |f| {
            match vec::find(ex_fields, |a| matches(f.ident, a)) {
              some(field) => {
                check_pat(pcx, f.pat, field.mt.ty);
              }
              none => {
                tcx.sess.span_fatal(pat.span,
                                    fmt!{"mismatched types: did not \
                                          expect a record with a field `%s`",
                                         *f.ident});
              }
            }
        }
        fcx.write_ty(pat.id, expected);
      }
      ast::pat_struct(path, fields, etc) => {
        // Grab the class data that we care about.
        let class_fields, class_id, substitutions;
        match structure_of(fcx, pat.span, expected) {
            ty::ty_class(cid, ref substs) => {
                class_id = cid;
                substitutions = substs;
                class_fields = ty::lookup_class_fields(tcx, class_id);
            }
            _ => {
                // XXX: This should not be fatal.
                tcx.sess.span_fatal(pat.span,
                                    fmt!("mismatched types: expected `%s` \
                                          but found struct",
                                         fcx.infcx.ty_to_str(expected)));
            }
        }

        // Check to ensure that the struct is the one specified.
        match tcx.def_map.get(pat.id) {
            ast::def_class(supplied_def_id, _)
                    if supplied_def_id == class_id => {
                // OK.
            }
            ast::def_class(*) => {
                let name = syntax::print::pprust::path_to_str(path);
                tcx.sess.span_err(pat.span,
                                  fmt!("mismatched types: expected `%s` but \
                                        found `%s`",
                                       fcx.infcx.ty_to_str(expected),
                                       name));
            }
            _ => {
                tcx.sess.span_bug(pat.span, ~"resolve didn't write in class");
            }
        }

        // Index the class fields.
        let field_map = std::map::box_str_hash();
        for class_fields.eachi |i, class_field| {
            field_map.insert(class_field.ident, i);
        }

        // Typecheck each field.
        let found_fields = std::map::uint_hash();
        for fields.each |field| {
            match field_map.find(field.ident) {
                some(index) => {
                    let class_field = class_fields[index];
                    let field_type = ty::lookup_field_type(tcx,
                                                           class_id,
                                                           class_field.id,
                                                           substitutions);
                    check_pat(pcx, field.pat, field_type);
                    found_fields.insert(index, ());
                }
                none => {
                    let name = syntax::print::pprust::path_to_str(path);
                    tcx.sess.span_err(pat.span,
                                      fmt!("struct `%s` does not have a field
                                            named `%s`", name, *field.ident));
                }
            }
        }

        // Report an error if not all the fields were specified.
        if !etc {
            for class_fields.eachi |i, field| {
                if found_fields.contains_key(i) {
                    again;
                }
                tcx.sess.span_err(pat.span,
                                  fmt!("pattern does not mention field `%s`",
                                       *field.ident));
            }
        }

        // Finally, write in the type.
        fcx.write_ty(pat.id, expected);
      }
      ast::pat_tup(elts) => {
        let ex_elts = match structure_of(fcx, pat.span, expected) {
          ty::ty_tup(elts) => elts,
          _ => {
            tcx.sess.span_fatal
                (pat.span,
                 fmt!{"mismatched types: expected `%s`, found tuple",
                      fcx.infcx.ty_to_str(expected)});
          }
        };
        let e_count = vec::len(elts);
        if e_count != vec::len(ex_elts) {
            tcx.sess.span_fatal
                (pat.span, fmt!{"mismatched types: expected a tuple \
                      with %u fields, found one with %u \
                      fields", vec::len(ex_elts), e_count});
        }
        let mut i = 0u;
        for elts.each |elt| {
            check_pat(pcx, elt, ex_elts[i]);
            i += 1u;
        }

        fcx.write_ty(pat.id, expected);
      }
      ast::pat_box(inner) => {
        match structure_of(fcx, pat.span, expected) {
          ty::ty_box(e_inner) => {
            check_pat(pcx, inner, e_inner.ty);
            fcx.write_ty(pat.id, expected);
          }
          _ => {
            tcx.sess.span_fatal(
                pat.span,
                ~"mismatched types: expected `" +
                fcx.infcx.ty_to_str(expected) +
                ~"` found box");
          }
        }
      }
      ast::pat_uniq(inner) => {
        match structure_of(fcx, pat.span, expected) {
          ty::ty_uniq(e_inner) => {
            check_pat(pcx, inner, e_inner.ty);
            fcx.write_ty(pat.id, expected);
          }
          _ => {
            tcx.sess.span_fatal(
                pat.span,
                ~"mismatched types: expected `" +
                fcx.infcx.ty_to_str(expected) +
                ~"` found uniq");
          }
        }
      }
    }
}

<commit_msg>Work around #3215/#3217 use-after-free in typeck::check::alt<commit_after>import syntax::print::pprust;

fn check_alt(fcx: @fn_ctxt,
             expr: @ast::expr,
             discrim: @ast::expr,
             arms: ~[ast::arm]) -> bool {
    let tcx = fcx.ccx.tcx;
    let mut bot;

    let pattern_ty = fcx.infcx.next_ty_var();
    bot = check_expr_with(fcx, discrim, pattern_ty);

    // Typecheck the patterns first, so that we get types for all the
    // bindings.
    for arms.each |arm| {
        let pcx = {
            fcx: fcx,
            map: pat_id_map(tcx.def_map, arm.pats[0]),
            alt_region: ty::re_scope(expr.id),
            block_region: ty::re_scope(arm.body.node.id),
            pat_region: ty::re_scope(expr.id)
        };

        for arm.pats.each |p| { check_pat(pcx, p, pattern_ty);}
    }
    // Now typecheck the blocks.
    let mut result_ty = fcx.infcx.next_ty_var();
    let mut arm_non_bot = false;
    for arms.each |arm| {
        match arm.guard {
          some(e) => { check_expr_with(fcx, e, ty::mk_bool(tcx)); },
          none => ()
        }
        if !check_block(fcx, arm.body) { arm_non_bot = true; }
        let bty = fcx.node_ty(arm.body.node.id);
        demand::suptype(fcx, arm.body.span, result_ty, bty);
    }
    bot |= !arm_non_bot;
    if !arm_non_bot { result_ty = ty::mk_bot(tcx); }
    fcx.write_ty(expr.id, result_ty);
    return bot;
}

type pat_ctxt = {
    fcx: @fn_ctxt,
    map: pat_id_map,
    alt_region: ty::region,
    block_region: ty::region,
    /* Equal to either alt_region or block_region. */
    pat_region: ty::region
};

fn check_pat_variant(pcx: pat_ctxt, pat: @ast::pat, path: @ast::path,
                     subpats: option<~[@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);

    // 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`.
    match structure_of(pcx.fcx, pat.span, expected) {
      ty::ty_enum(_, ref expected_substs) => {
        // 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::suptype(fcx, pat.span, pat_ty, expected);

        // Get the expected types of the arguments.
        let arg_types = {
            let vinfo =
                ty::enum_variant_with_id(
                    tcx, v_def_ids.enm, v_def_ids.var);
            vinfo.args.map(|t| { ty::subst(tcx, expected_substs, t) })
        };
        let arg_len = arg_types.len(), subpats_len = match subpats {
            none => arg_len,
            some(ps) => ps.len()
        };
        if arg_len > 0u {
            // N-ary variant.
            if arg_len != subpats_len {
                let s = fmt!{"this pattern has %u field%s, but the \
                              corresponding variant has %u field%s",
                             subpats_len,
                             if subpats_len == 1u { ~"" } else { ~"s" },
                             arg_len,
                             if arg_len == 1u { ~"" } else { ~"s" }};
                tcx.sess.span_fatal(pat.span, s);
            }

            do option::iter(subpats) |pats| {
                do vec::iter2(pats, arg_types) |subpat, arg_ty| {
                  check_pat(pcx, subpat, arg_ty);
                }
            };
        } else if subpats_len > 0u {
            tcx.sess.span_fatal
                (pat.span, fmt!{"this pattern has %u field%s, \
                                 but the corresponding variant has no fields",
                                subpats_len,
                                if subpats_len == 1u { ~"" }
                                else { ~"s" }});
        }
      }
      _ => {
        tcx.sess.span_fatal
            (pat.span,
             fmt!{"mismatched types: expected enum but found `%s`",
                  fcx.infcx.ty_to_str(expected)});
      }
    }
}

// Pattern checking is top-down rather than bottom-up so that bindings get
// their types immediately.
fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) {
    let fcx = pcx.fcx;
    let tcx = pcx.fcx.ccx.tcx;

    match pat.node {
      ast::pat_wild => {
        fcx.write_ty(pat.id, expected);
      }
      ast::pat_lit(lt) => {
        check_expr_with(fcx, lt, expected);
        fcx.write_ty(pat.id, fcx.expr_ty(lt));
      }
      ast::pat_range(begin, end) => {
        check_expr_with(fcx, begin, expected);
        check_expr_with(fcx, end, expected);
        let b_ty =
            fcx.infcx.resolve_type_vars_if_possible(fcx.expr_ty(begin));
        let e_ty =
            fcx.infcx.resolve_type_vars_if_possible(fcx.expr_ty(end));
        debug!{"pat_range beginning type: %?", b_ty};
        debug!{"pat_range ending type: %?", e_ty};
        if !require_same_types(
            tcx, some(fcx.infcx), pat.span, b_ty, e_ty,
            || ~"mismatched types in range") {
            // no-op
        } else if !ty::type_is_numeric(b_ty) {
            tcx.sess.span_err(pat.span, ~"non-numeric type used in range");
        } else if !valid_range_bounds(fcx.ccx, begin, end) {
            tcx.sess.span_err(begin.span, ~"lower range bound must be less \
                                           than upper");
        }
        fcx.write_ty(pat.id, b_ty);
      }
      ast::pat_ident(bm, name, sub) if !pat_is_variant(tcx.def_map, pat) => {
        let vid = lookup_local(fcx, pat.span, pat.id);
        let mut typ = ty::mk_var(tcx, vid);

        match bm {
          ast::bind_by_ref(mutbl) => {
            // if the binding is like
            //    ref x | ref const x | ref mut x
            // then the type of x is &M T where M is the mutability
            // and T is the expected type
            let region_var =
                fcx.infcx.next_region_var({lb: some(pcx.block_region),
                                           ub: none});
            let mt = {ty: expected, mutbl: mutbl};
            let region_ty = ty::mk_rptr(tcx, region_var, mt);
            demand::eqtype(fcx, pat.span, region_ty, typ);
          }
          ast::bind_by_value | ast::bind_by_implicit_ref => {
            // otherwise the type of x is the expected type T
            demand::eqtype(fcx, pat.span, expected, typ);
          }
        }

        let canon_id = pcx.map.get(ast_util::path_to_ident(name));
        if canon_id != pat.id {
            let tv_id = lookup_local(fcx, pat.span, canon_id);
            let ct = ty::mk_var(tcx, tv_id);
            demand::eqtype(fcx, pat.span, ct, typ);
        }
        fcx.write_ty(pat.id, typ);
        match sub {
          some(p) => check_pat(pcx, p, expected),
          _ => ()
        }
      }
      ast::pat_ident(_, path, c) => {
        check_pat_variant(pcx, pat, path, some(~[]), expected);
      }
      ast::pat_enum(path, subpats) => {
        check_pat_variant(pcx, pat, path, subpats, expected);
      }
      ast::pat_rec(fields, etc) => {
        let ex_fields = match structure_of(fcx, pat.span, expected) {
          ty::ty_rec(fields) => fields,
          _ => {
            tcx.sess.span_fatal
                (pat.span,
                fmt!{"mismatched types: expected `%s` but found record",
                     fcx.infcx.ty_to_str(expected)});
          }
        };
        let f_count = vec::len(fields);
        let ex_f_count = vec::len(ex_fields);
        if ex_f_count < f_count || !etc && ex_f_count > f_count {
            tcx.sess.span_fatal
                (pat.span, fmt!{"mismatched types: expected a record \
                      with %u fields, found one with %u \
                      fields",
                                ex_f_count, f_count});
        }
        fn matches(name: ast::ident, f: ty::field) -> bool {
            str::eq(name, f.ident)
        }
        for fields.each |f| {
            match vec::find(ex_fields, |a| matches(f.ident, a)) {
              some(field) => {
                check_pat(pcx, f.pat, field.mt.ty);
              }
              none => {
                tcx.sess.span_fatal(pat.span,
                                    fmt!{"mismatched types: did not \
                                          expect a record with a field `%s`",
                                         *f.ident});
              }
            }
        }
        fcx.write_ty(pat.id, expected);
      }
      ast::pat_struct(path, fields, etc) => {
        // Grab the class data that we care about.
        let class_fields, class_id, substitutions;
        // FIXME(#3217) If this were "match structure_of...", this bug causes
        // it to not live long enough for 'substitutions'.
        let structure = structure_of(fcx, pat.span, expected);
        match structure {
            ty::ty_class(cid, ref substs) => {
                class_id = cid;
                substitutions = substs;
                class_fields = ty::lookup_class_fields(tcx, class_id);
            }
            _ => {
                // XXX: This should not be fatal.
                tcx.sess.span_fatal(pat.span,
                                    fmt!("mismatched types: expected `%s` \
                                          but found struct",
                                         fcx.infcx.ty_to_str(expected)));
            }
        }

        // Check to ensure that the struct is the one specified.
        match tcx.def_map.get(pat.id) {
            ast::def_class(supplied_def_id, _)
                    if supplied_def_id == class_id => {
                // OK.
            }
            ast::def_class(*) => {
                let name = syntax::print::pprust::path_to_str(path);
                tcx.sess.span_err(pat.span,
                                  fmt!("mismatched types: expected `%s` but \
                                        found `%s`",
                                       fcx.infcx.ty_to_str(expected),
                                       name));
            }
            _ => {
                tcx.sess.span_bug(pat.span, ~"resolve didn't write in class");
            }
        }

        // Index the class fields.
        let field_map = std::map::box_str_hash();
        for class_fields.eachi |i, class_field| {
            field_map.insert(class_field.ident, i);
        }

        // Typecheck each field.
        let found_fields = std::map::uint_hash();
        for fields.each |field| {
            match field_map.find(field.ident) {
                some(index) => {
                    let class_field = class_fields[index];
                    let field_type = ty::lookup_field_type(tcx,
                                                           class_id,
                                                           class_field.id,
                                                           substitutions);
                    check_pat(pcx, field.pat, field_type);
                    found_fields.insert(index, ());
                }
                none => {
                    let name = syntax::print::pprust::path_to_str(path);
                    tcx.sess.span_err(pat.span,
                                      fmt!("struct `%s` does not have a field
                                            named `%s`", name, *field.ident));
                }
            }
        }

        // Report an error if not all the fields were specified.
        if !etc {
            for class_fields.eachi |i, field| {
                if found_fields.contains_key(i) {
                    again;
                }
                tcx.sess.span_err(pat.span,
                                  fmt!("pattern does not mention field `%s`",
                                       *field.ident));
            }
        }

        // Finally, write in the type.
        fcx.write_ty(pat.id, expected);
      }
      ast::pat_tup(elts) => {
        let ex_elts = match structure_of(fcx, pat.span, expected) {
          ty::ty_tup(elts) => elts,
          _ => {
            tcx.sess.span_fatal
                (pat.span,
                 fmt!{"mismatched types: expected `%s`, found tuple",
                      fcx.infcx.ty_to_str(expected)});
          }
        };
        let e_count = vec::len(elts);
        if e_count != vec::len(ex_elts) {
            tcx.sess.span_fatal
                (pat.span, fmt!{"mismatched types: expected a tuple \
                      with %u fields, found one with %u \
                      fields", vec::len(ex_elts), e_count});
        }
        let mut i = 0u;
        for elts.each |elt| {
            check_pat(pcx, elt, ex_elts[i]);
            i += 1u;
        }

        fcx.write_ty(pat.id, expected);
      }
      ast::pat_box(inner) => {
        match structure_of(fcx, pat.span, expected) {
          ty::ty_box(e_inner) => {
            check_pat(pcx, inner, e_inner.ty);
            fcx.write_ty(pat.id, expected);
          }
          _ => {
            tcx.sess.span_fatal(
                pat.span,
                ~"mismatched types: expected `" +
                fcx.infcx.ty_to_str(expected) +
                ~"` found box");
          }
        }
      }
      ast::pat_uniq(inner) => {
        match structure_of(fcx, pat.span, expected) {
          ty::ty_uniq(e_inner) => {
            check_pat(pcx, inner, e_inner.ty);
            fcx.write_ty(pat.id, expected);
          }
          _ => {
            tcx.sess.span_fatal(
                pat.span,
                ~"mismatched types: expected `" +
                fcx.infcx.ty_to_str(expected) +
                ~"` found uniq");
          }
        }
      }
    }
}

<|endoftext|>


<commit_before>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use core::mem::*;
use test::Bencher;

#[test]
fn size_of_basic() {
    assert_eq!(size_of::<u8>(), 1u);
    assert_eq!(size_of::<u16>(), 2u);
    assert_eq!(size_of::<u32>(), 4u);
    assert_eq!(size_of::<u64>(), 8u);
}

#[test]
#[cfg(target_arch = "x86")]
#[cfg(target_arch = "arm")]
#[cfg(target_arch = "mips")]
#[cfg(target_arch = "mipsel")]
fn size_of_32() {
    assert_eq!(size_of::<uint>(), 4u);
    assert_eq!(size_of::<*const uint>(), 4u);
}

#[test]
#[cfg(target_arch = "x86_64")]
fn size_of_64() {
    assert_eq!(size_of::<uint>(), 8u);
    assert_eq!(size_of::<*const uint>(), 8u);
}

#[test]
fn size_of_val_basic() {
    assert_eq!(size_of_val(&1u8), 1);
    assert_eq!(size_of_val(&1u16), 2);
    assert_eq!(size_of_val(&1u32), 4);
    assert_eq!(size_of_val(&1u64), 8);
}

#[test]
fn align_of_basic() {
    assert_eq!(align_of::<u8>(), 1u);
    assert_eq!(align_of::<u16>(), 2u);
    assert_eq!(align_of::<u32>(), 4u);
}

#[test]
#[cfg(target_arch = "x86")]
#[cfg(target_arch = "arm")]
#[cfg(target_arch = "mips")]
#[cfg(target_arch = "mipsel")]
fn align_of_32() {
    assert_eq!(align_of::<uint>(), 4u);
    assert_eq!(align_of::<*const uint>(), 4u);
}

#[test]
#[cfg(target_arch = "x86_64")]
fn align_of_64() {
    assert_eq!(align_of::<uint>(), 8u);
    assert_eq!(align_of::<*const uint>(), 8u);
}

#[test]
fn align_of_val_basic() {
    assert_eq!(align_of_val(&1u8), 1u);
    assert_eq!(align_of_val(&1u16), 2u);
    assert_eq!(align_of_val(&1u32), 4u);
}

#[test]
fn test_swap() {
    let mut x = 31337i;
    let mut y = 42i;
    swap(&mut x, &mut y);
    assert_eq!(x, 42);
    assert_eq!(y, 31337);
}

#[test]
fn test_replace() {
    let mut x = Some("test".to_string());
    let y = replace(&mut x, None);
    assert!(x.is_none());
    assert!(y.is_some());
}

#[test]
fn test_transmute_copy() {
    assert_eq!(1u, unsafe { transmute_copy(&1i) });
}

#[test]
fn test_transmute() {
    trait Foo {}
    impl Foo for int {}

    let a = box 100i as Box<Foo>;
    unsafe {
        let x: ::core::raw::TraitObject = transmute(a);
        assert!(*(x.data as *const int) == 100);
        let _x: Box<Foo> = transmute(x);
    }

    unsafe {
        assert!(Vec::from_slice([76u8]) == transmute("L".to_string()));
    }
}

// FIXME #13642 (these benchmarks should be in another place)
/// Completely miscellaneous language-construct benchmarks.
// Static/dynamic method dispatch

struct Struct {
    field: int
}

trait Trait {
    fn method(&self) -> int;
}

impl Trait for Struct {
    fn method(&self) -> int {
        self.field
    }
}

#[bench]
fn trait_vtable_method_call(b: &mut Bencher) {
    let s = Struct { field: 10 };
    let t = &s as &Trait;
    b.iter(|| {
        t.method()
    });
}

#[bench]
fn trait_static_method_call(b: &mut Bencher) {
    let s = Struct { field: 10 };
    b.iter(|| {
        s.method()
    });
}

// Overhead of various match forms

#[bench]
fn match_option_some(b: &mut Bencher) {
    let x = Some(10i);
    b.iter(|| {
        match x {
            Some(y) => y,
            None => 11
        }
    });
}

#[bench]
fn match_vec_pattern(b: &mut Bencher) {
    let x = [1i,2,3,4,5,6];
    b.iter(|| {
        match x {
            [1,2,3,..] => 10i,
            _ => 11i,
        }
    });
}
<commit_msg>Fix cfg warnings in libcoretest<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use core::mem::*;
use test::Bencher;

#[test]
fn size_of_basic() {
    assert_eq!(size_of::<u8>(), 1u);
    assert_eq!(size_of::<u16>(), 2u);
    assert_eq!(size_of::<u32>(), 4u);
    assert_eq!(size_of::<u64>(), 8u);
}

#[test]
#[cfg(any(target_arch = "x86",
          target_arch = "arm",
          target_arch = "mips",
          target_arch = "mipsel"))]
fn size_of_32() {
    assert_eq!(size_of::<uint>(), 4u);
    assert_eq!(size_of::<*const uint>(), 4u);
}

#[test]
#[cfg(target_arch = "x86_64")]
fn size_of_64() {
    assert_eq!(size_of::<uint>(), 8u);
    assert_eq!(size_of::<*const uint>(), 8u);
}

#[test]
fn size_of_val_basic() {
    assert_eq!(size_of_val(&1u8), 1);
    assert_eq!(size_of_val(&1u16), 2);
    assert_eq!(size_of_val(&1u32), 4);
    assert_eq!(size_of_val(&1u64), 8);
}

#[test]
fn align_of_basic() {
    assert_eq!(align_of::<u8>(), 1u);
    assert_eq!(align_of::<u16>(), 2u);
    assert_eq!(align_of::<u32>(), 4u);
}

#[test]
#[cfg(any(target_arch = "x86",
          target_arch = "arm",
          target_arch = "mips",
          target_arch = "mipsel"))]
fn align_of_32() {
    assert_eq!(align_of::<uint>(), 4u);
    assert_eq!(align_of::<*const uint>(), 4u);
}

#[test]
#[cfg(target_arch = "x86_64")]
fn align_of_64() {
    assert_eq!(align_of::<uint>(), 8u);
    assert_eq!(align_of::<*const uint>(), 8u);
}

#[test]
fn align_of_val_basic() {
    assert_eq!(align_of_val(&1u8), 1u);
    assert_eq!(align_of_val(&1u16), 2u);
    assert_eq!(align_of_val(&1u32), 4u);
}

#[test]
fn test_swap() {
    let mut x = 31337i;
    let mut y = 42i;
    swap(&mut x, &mut y);
    assert_eq!(x, 42);
    assert_eq!(y, 31337);
}

#[test]
fn test_replace() {
    let mut x = Some("test".to_string());
    let y = replace(&mut x, None);
    assert!(x.is_none());
    assert!(y.is_some());
}

#[test]
fn test_transmute_copy() {
    assert_eq!(1u, unsafe { transmute_copy(&1i) });
}

#[test]
fn test_transmute() {
    trait Foo {}
    impl Foo for int {}

    let a = box 100i as Box<Foo>;
    unsafe {
        let x: ::core::raw::TraitObject = transmute(a);
        assert!(*(x.data as *const int) == 100);
        let _x: Box<Foo> = transmute(x);
    }

    unsafe {
        assert!(Vec::from_slice([76u8]) == transmute("L".to_string()));
    }
}

// FIXME #13642 (these benchmarks should be in another place)
/// Completely miscellaneous language-construct benchmarks.
// Static/dynamic method dispatch

struct Struct {
    field: int
}

trait Trait {
    fn method(&self) -> int;
}

impl Trait for Struct {
    fn method(&self) -> int {
        self.field
    }
}

#[bench]
fn trait_vtable_method_call(b: &mut Bencher) {
    let s = Struct { field: 10 };
    let t = &s as &Trait;
    b.iter(|| {
        t.method()
    });
}

#[bench]
fn trait_static_method_call(b: &mut Bencher) {
    let s = Struct { field: 10 };
    b.iter(|| {
        s.method()
    });
}

// Overhead of various match forms

#[bench]
fn match_option_some(b: &mut Bencher) {
    let x = Some(10i);
    b.iter(|| {
        match x {
            Some(y) => y,
            None => 11
        }
    });
}

#[bench]
fn match_vec_pattern(b: &mut Bencher) {
    let x = [1i,2,3,4,5,6];
    b.iter(|| {
        match x {
            [1,2,3,..] => 10i,
            _ => 11i,
        }
    });
}
<|endoftext|>


<commit_before>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Base64 binary-to-text encoding

/// Available encoding character sets
pub enum CharacterSet {
    /// The standard character set (uses '+' and '/')
    Standard,
    /// The URL safe character set (uses '-' and '_')
    UrlSafe
}

/// Contains configuration parameters for to_base64
pub struct Config {
    /// Character set to use
    char_set: CharacterSet,
    /// True to pad output with '=' characters
    pad: bool,
    /// Some(len) to wrap lines at len, None to disable line wrapping
    line_length: Option<uint>
}

/// Configuration for RFC 4648 standard base64 encoding
pub static standard: Config =
    Config {char_set: Standard, pad: true, line_length: None};

/// Configuration for RFC 4648 base64url encoding
pub static url_safe: Config =
    Config {char_set: UrlSafe, pad: false, line_length: None};

/// Configuration for RFC 2045 MIME base64 encoding
pub static mime: Config =
    Config {char_set: Standard, pad: true, line_length: Some(76)};

static STANDARD_CHARS: [char, ..64] = [
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
    'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
    'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
];

static URLSAFE_CHARS: [char, ..64] = [
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
    'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
    'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'
];

/// A trait for converting a value to base64 encoding.
pub trait ToBase64 {
    /// Converts the value of `self` to a base64 value following the specified
    /// format configuration, returning the owned string.
    fn to_base64(&self, config: Config) -> ~str;
}

impl<'self> ToBase64 for &'self [u8] {
    /**
     * Turn a vector of `u8` bytes into a base64 string.
     *
     * # Example
     *
     * ~~~ {.rust}
     * extern mod extra;
     * use extra::base64::{ToBase64, standard};
     *
     * fn main () {
     *     let str = [52,32].to_base64(standard);
     *     println(fmt!("%s", str));
     * }
     * ~~~
     */
    fn to_base64(&self, config: Config) -> ~str {
        let chars = match config.char_set {
            Standard => STANDARD_CHARS,
            UrlSafe => URLSAFE_CHARS
        };

        let mut s = ~"";
        let mut i = 0;
        let mut cur_length = 0;
        let len = self.len();
        while i < len - (len % 3) {
            match config.line_length {
                Some(line_length) =>
                    if cur_length >= line_length {
                        s.push_str("\r\n");
                        cur_length = 0;
                    },
                None => ()
            }

            let n = (self[i] as u32) << 16 |
                    (self[i + 1] as u32) << 8 |
                    (self[i + 2] as u32);

            // This 24-bit number gets separated into four 6-bit numbers.
            s.push_char(chars[(n >> 18) & 63]);
            s.push_char(chars[(n >> 12) & 63]);
            s.push_char(chars[(n >> 6 ) & 63]);
            s.push_char(chars[n & 63]);

            cur_length += 4;
            i += 3;
        }

        if len % 3 != 0 {
            match config.line_length {
                Some(line_length) =>
                    if cur_length >= line_length {
                        s.push_str("\r\n");
                    },
                None => ()
            }
        }

        // Heh, would be cool if we knew this was exhaustive
        // (the dream of bounded integer types)
        match len % 3 {
            0 => (),
            1 => {
                let n = (self[i] as u32) << 16;
                s.push_char(chars[(n >> 18) & 63]);
                s.push_char(chars[(n >> 12) & 63]);
                if config.pad {
                    s.push_str("==");
                }
            }
            2 => {
                let n = (self[i] as u32) << 16 |
                    (self[i + 1u] as u32) << 8;
                s.push_char(chars[(n >> 18) & 63]);
                s.push_char(chars[(n >> 12) & 63]);
                s.push_char(chars[(n >> 6 ) & 63]);
                if config.pad {
                    s.push_char('=');
                }
            }
            _ => fail!("Algebra is broken, please alert the math police")
        }
        s
    }
}

impl<'self> ToBase64 for &'self str {
    /**
     * Convert any string (literal, `@`, `&`, or `~`) to base64 encoding.
     *
     *
     * # Example
     *
     * ~~~ {.rust}
     * extern mod extra;
     * use extra::base64::{ToBase64, standard};
     *
     * fn main () {
     *     let str = "Hello, World".to_base64(standard);
     *     println(fmt!("%s",str));
     * }
     * ~~~
     *
     */
    fn to_base64(&self, config: Config) -> ~str {
        self.as_bytes().to_base64(config)
    }
}

/// A trait for converting from base64 encoded values.
pub trait FromBase64 {
    /// Converts the value of `self`, interpreted as base64 encoded data, into
    /// an owned vector of bytes, returning the vector.
    fn from_base64(&self) -> Result<~[u8], ~str>;
}

impl<'self> FromBase64 for &'self [u8] {
    /**
     * Convert base64 `u8` vector into u8 byte values.
     * Every 4 encoded characters is converted into 3 octets, modulo padding.
     *
     * # Example
     *
     * ~~~ {.rust}
     * extern mod extra;
     * use extra::base64::{ToBase64, FromBase64, standard};
     *
     * fn main () {
     *     let str = [52,32].to_base64(standard);
     *     println(fmt!("%s", str));
     *     let bytes = str.from_base64();
     *     println(fmt!("%?",bytes));
     * }
     * ~~~
     */
    fn from_base64(&self) -> Result<~[u8], ~str> {
        let mut r = ~[];
        let mut buf: u32 = 0;
        let mut modulus = 0;

        let mut it = self.iter();
        for it.advance |&byte| {
            let ch = byte as char;
            let val = byte as u32;

            match ch {
                'A'..'Z'  => buf |= val - 0x41,
                'a'..'z'  => buf |= val - 0x47,
                '0'..'9'  => buf |= val + 0x04,
                '+'|'-'   => buf |= 0x3E,
                '/'|'_'   => buf |= 0x3F,
                '\r'|'\n' => loop,
                '='       => break,
                _         => return Err(~"Invalid Base64 character")
            }

            buf <<= 6;
            modulus += 1;
            if modulus == 4 {
                modulus = 0;
                r.push((buf >> 22) as u8);
                r.push((buf >> 14) as u8);
                r.push((buf >> 6 ) as u8);
            }
        }

        if !it.all(|&byte| {byte as char == '='}) {
            return Err(~"Invalid Base64 character");
        }

        match modulus {
            2 => {
                r.push((buf >> 10) as u8);
            }
            3 => {
                r.push((buf >> 16) as u8);
                r.push((buf >> 8 ) as u8);
            }
            0 => (),
            _ => return Err(~"Invalid Base64 length")
        }

        Ok(r)
    }
}

impl<'self> FromBase64 for &'self str {
    /**
     * Convert any base64 encoded string (literal, `@`, `&`, or `~`)
     * to the byte values it encodes.
     *
     * You can use the `from_bytes` function in `std::str`
     * to turn a `[u8]` into a string with characters corresponding to those
     * values.
     *
     * # Example
     *
     * This converts a string literal to base64 and back.
     *
     * ~~~ {.rust}
     * extern mod extra;
     * use extra::base64::{ToBase64, FromBase64, standard};
     * use std::str;
     *
     * fn main () {
     *     let hello_str = "Hello, World".to_base64(standard);
     *     println(fmt!("%s",hello_str));
     *     let bytes = hello_str.from_base64();
     *     println(fmt!("%?",bytes));
     *     let result_str = str::from_bytes(bytes);
     *     println(fmt!("%s",result_str));
     * }
     * ~~~
     */
    fn from_base64(&self) -> Result<~[u8], ~str> {
        self.as_bytes().from_base64()
    }
}

#[test]
fn test_to_base64_basic() {
    assert_eq!("".to_base64(standard), ~"");
    assert_eq!("f".to_base64(standard), ~"Zg==");
    assert_eq!("fo".to_base64(standard), ~"Zm8=");
    assert_eq!("foo".to_base64(standard), ~"Zm9v");
    assert_eq!("foob".to_base64(standard), ~"Zm9vYg==");
    assert_eq!("fooba".to_base64(standard), ~"Zm9vYmE=");
    assert_eq!("foobar".to_base64(standard), ~"Zm9vYmFy");
}

#[test]
fn test_to_base64_line_break() {
    assert!(![0u8, 1000].to_base64(Config {line_length: None, ..standard})
        .contains("\r\n"));
    assert_eq!("foobar".to_base64(Config {line_length: Some(4), ..standard}),
        ~"Zm9v\r\nYmFy");
}

#[test]
fn test_to_base64_padding() {
    assert_eq!("f".to_base64(Config {pad: false, ..standard}), ~"Zg");
    assert_eq!("fo".to_base64(Config {pad: false, ..standard}), ~"Zm8");
}

#[test]
fn test_to_base64_url_safe() {
    assert_eq!([251, 255].to_base64(url_safe), ~"-_8");
    assert_eq!([251, 255].to_base64(standard), ~"+/8=");
}

#[test]
fn test_from_base64_basic() {
    assert_eq!("".from_base64().get(), "".as_bytes().to_owned());
    assert_eq!("Zg==".from_base64().get(), "f".as_bytes().to_owned());
    assert_eq!("Zm8=".from_base64().get(), "fo".as_bytes().to_owned());
    assert_eq!("Zm9v".from_base64().get(), "foo".as_bytes().to_owned());
    assert_eq!("Zm9vYg==".from_base64().get(), "foob".as_bytes().to_owned());
    assert_eq!("Zm9vYmE=".from_base64().get(), "fooba".as_bytes().to_owned());
    assert_eq!("Zm9vYmFy".from_base64().get(), "foobar".as_bytes().to_owned());
}

#[test]
fn test_from_base64_newlines() {
    assert_eq!("Zm9v\r\nYmFy".from_base64().get(),
        "foobar".as_bytes().to_owned());
}

#[test]
fn test_from_base64_urlsafe() {
    assert_eq!("-_8".from_base64().get(), "+/8=".from_base64().get());
}

#[test]
fn test_from_base64_invalid_char() {
    assert!("Zm$=".from_base64().is_err())
    assert!("Zg==$".from_base64().is_err());
}

#[test]
fn test_from_base64_invalid_padding() {
    assert!("Z===".from_base64().is_err());
}

#[test]
fn test_base64_random() {
    use std::rand::{task_rng, random, RngUtil};
    use std::vec;

    for 1000.times {
        let v: ~[u8] = do vec::build |push| {
            for task_rng().gen_uint_range(1, 100).times {
                push(random());
            }
        };
        assert_eq!(v.to_base64(standard).from_base64().get(), v);
    }
}
<commit_msg>Upper-cased exported statics<commit_after>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Base64 binary-to-text encoding

/// Available encoding character sets
pub enum CharacterSet {
    /// The standard character set (uses '+' and '/')
    Standard,
    /// The URL safe character set (uses '-' and '_')
    UrlSafe
}

/// Contains configuration parameters for to_base64
pub struct Config {
    /// Character set to use
    char_set: CharacterSet,
    /// True to pad output with '=' characters
    pad: bool,
    /// Some(len) to wrap lines at len, None to disable line wrapping
    line_length: Option<uint>
}

/// Configuration for RFC 4648 standard base64 encoding
pub static STANDARD: Config =
    Config {char_set: Standard, pad: true, line_length: None};

/// Configuration for RFC 4648 base64url encoding
pub static URL_SAFE: Config =
    Config {char_set: UrlSafe, pad: false, line_length: None};

/// Configuration for RFC 2045 MIME base64 encoding
pub static MIME: Config =
    Config {char_set: Standard, pad: true, line_length: Some(76)};

static STANDARD_CHARS: [char, ..64] = [
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
    'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
    'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
];

static URLSAFE_CHARS: [char, ..64] = [
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
    'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
    'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'
];

/// A trait for converting a value to base64 encoding.
pub trait ToBase64 {
    /// Converts the value of `self` to a base64 value following the specified
    /// format configuration, returning the owned string.
    fn to_base64(&self, config: Config) -> ~str;
}

impl<'self> ToBase64 for &'self [u8] {
    /**
     * Turn a vector of `u8` bytes into a base64 string.
     *
     * # Example
     *
     * ~~~ {.rust}
     * extern mod extra;
     * use extra::base64::{ToBase64, standard};
     *
     * fn main () {
     *     let str = [52,32].to_base64(standard);
     *     println(fmt!("%s", str));
     * }
     * ~~~
     */
    fn to_base64(&self, config: Config) -> ~str {
        let chars = match config.char_set {
            Standard => STANDARD_CHARS,
            UrlSafe => URLSAFE_CHARS
        };

        let mut s = ~"";
        let mut i = 0;
        let mut cur_length = 0;
        let len = self.len();
        while i < len - (len % 3) {
            match config.line_length {
                Some(line_length) =>
                    if cur_length >= line_length {
                        s.push_str("\r\n");
                        cur_length = 0;
                    },
                None => ()
            }

            let n = (self[i] as u32) << 16 |
                    (self[i + 1] as u32) << 8 |
                    (self[i + 2] as u32);

            // This 24-bit number gets separated into four 6-bit numbers.
            s.push_char(chars[(n >> 18) & 63]);
            s.push_char(chars[(n >> 12) & 63]);
            s.push_char(chars[(n >> 6 ) & 63]);
            s.push_char(chars[n & 63]);

            cur_length += 4;
            i += 3;
        }

        if len % 3 != 0 {
            match config.line_length {
                Some(line_length) =>
                    if cur_length >= line_length {
                        s.push_str("\r\n");
                    },
                None => ()
            }
        }

        // Heh, would be cool if we knew this was exhaustive
        // (the dream of bounded integer types)
        match len % 3 {
            0 => (),
            1 => {
                let n = (self[i] as u32) << 16;
                s.push_char(chars[(n >> 18) & 63]);
                s.push_char(chars[(n >> 12) & 63]);
                if config.pad {
                    s.push_str("==");
                }
            }
            2 => {
                let n = (self[i] as u32) << 16 |
                    (self[i + 1u] as u32) << 8;
                s.push_char(chars[(n >> 18) & 63]);
                s.push_char(chars[(n >> 12) & 63]);
                s.push_char(chars[(n >> 6 ) & 63]);
                if config.pad {
                    s.push_char('=');
                }
            }
            _ => fail!("Algebra is broken, please alert the math police")
        }
        s
    }
}

impl<'self> ToBase64 for &'self str {
    /**
     * Convert any string (literal, `@`, `&`, or `~`) to base64 encoding.
     *
     *
     * # Example
     *
     * ~~~ {.rust}
     * extern mod extra;
     * use extra::base64::{ToBase64, standard};
     *
     * fn main () {
     *     let str = "Hello, World".to_base64(standard);
     *     println(fmt!("%s",str));
     * }
     * ~~~
     *
     */
    fn to_base64(&self, config: Config) -> ~str {
        self.as_bytes().to_base64(config)
    }
}

/// A trait for converting from base64 encoded values.
pub trait FromBase64 {
    /// Converts the value of `self`, interpreted as base64 encoded data, into
    /// an owned vector of bytes, returning the vector.
    fn from_base64(&self) -> Result<~[u8], ~str>;
}

impl<'self> FromBase64 for &'self [u8] {
    /**
     * Convert base64 `u8` vector into u8 byte values.
     * Every 4 encoded characters is converted into 3 octets, modulo padding.
     *
     * # Example
     *
     * ~~~ {.rust}
     * extern mod extra;
     * use extra::base64::{ToBase64, FromBase64, standard};
     *
     * fn main () {
     *     let str = [52,32].to_base64(standard);
     *     println(fmt!("%s", str));
     *     let bytes = str.from_base64();
     *     println(fmt!("%?",bytes));
     * }
     * ~~~
     */
    fn from_base64(&self) -> Result<~[u8], ~str> {
        let mut r = ~[];
        let mut buf: u32 = 0;
        let mut modulus = 0;

        let mut it = self.iter();
        for it.advance |&byte| {
            let ch = byte as char;
            let val = byte as u32;

            match ch {
                'A'..'Z'  => buf |= val - 0x41,
                'a'..'z'  => buf |= val - 0x47,
                '0'..'9'  => buf |= val + 0x04,
                '+'|'-'   => buf |= 0x3E,
                '/'|'_'   => buf |= 0x3F,
                '\r'|'\n' => loop,
                '='       => break,
                _         => return Err(~"Invalid Base64 character")
            }

            buf <<= 6;
            modulus += 1;
            if modulus == 4 {
                modulus = 0;
                r.push((buf >> 22) as u8);
                r.push((buf >> 14) as u8);
                r.push((buf >> 6 ) as u8);
            }
        }

        if !it.all(|&byte| {byte as char == '='}) {
            return Err(~"Invalid Base64 character");
        }

        match modulus {
            2 => {
                r.push((buf >> 10) as u8);
            }
            3 => {
                r.push((buf >> 16) as u8);
                r.push((buf >> 8 ) as u8);
            }
            0 => (),
            _ => return Err(~"Invalid Base64 length")
        }

        Ok(r)
    }
}

impl<'self> FromBase64 for &'self str {
    /**
     * Convert any base64 encoded string (literal, `@`, `&`, or `~`)
     * to the byte values it encodes.
     *
     * You can use the `from_bytes` function in `std::str`
     * to turn a `[u8]` into a string with characters corresponding to those
     * values.
     *
     * # Example
     *
     * This converts a string literal to base64 and back.
     *
     * ~~~ {.rust}
     * extern mod extra;
     * use extra::base64::{ToBase64, FromBase64, standard};
     * use std::str;
     *
     * fn main () {
     *     let hello_str = "Hello, World".to_base64(standard);
     *     println(fmt!("%s",hello_str));
     *     let bytes = hello_str.from_base64();
     *     println(fmt!("%?",bytes));
     *     let result_str = str::from_bytes(bytes);
     *     println(fmt!("%s",result_str));
     * }
     * ~~~
     */
    fn from_base64(&self) -> Result<~[u8], ~str> {
        self.as_bytes().from_base64()
    }
}

#[test]
fn test_to_base64_basic() {
    assert_eq!("".to_base64(STANDARD), ~"");
    assert_eq!("f".to_base64(STANDARD), ~"Zg==");
    assert_eq!("fo".to_base64(STANDARD), ~"Zm8=");
    assert_eq!("foo".to_base64(STANDARD), ~"Zm9v");
    assert_eq!("foob".to_base64(STANDARD), ~"Zm9vYg==");
    assert_eq!("fooba".to_base64(STANDARD), ~"Zm9vYmE=");
    assert_eq!("foobar".to_base64(STANDARD), ~"Zm9vYmFy");
}

#[test]
fn test_to_base64_line_break() {
    assert!(![0u8, 1000].to_base64(Config {line_length: None, ..STANDARD})
        .contains("\r\n"));
    assert_eq!("foobar".to_base64(Config {line_length: Some(4), ..STANDARD}),
        ~"Zm9v\r\nYmFy");
}

#[test]
fn test_to_base64_padding() {
    assert_eq!("f".to_base64(Config {pad: false, ..STANDARD}), ~"Zg");
    assert_eq!("fo".to_base64(Config {pad: false, ..STANDARD}), ~"Zm8");
}

#[test]
fn test_to_base64_url_safe() {
    assert_eq!([251, 255].to_base64(URL_SAFE), ~"-_8");
    assert_eq!([251, 255].to_base64(STANDARD), ~"+/8=");
}

#[test]
fn test_from_base64_basic() {
    assert_eq!("".from_base64().get(), "".as_bytes().to_owned());
    assert_eq!("Zg==".from_base64().get(), "f".as_bytes().to_owned());
    assert_eq!("Zm8=".from_base64().get(), "fo".as_bytes().to_owned());
    assert_eq!("Zm9v".from_base64().get(), "foo".as_bytes().to_owned());
    assert_eq!("Zm9vYg==".from_base64().get(), "foob".as_bytes().to_owned());
    assert_eq!("Zm9vYmE=".from_base64().get(), "fooba".as_bytes().to_owned());
    assert_eq!("Zm9vYmFy".from_base64().get(), "foobar".as_bytes().to_owned());
}

#[test]
fn test_from_base64_newlines() {
    assert_eq!("Zm9v\r\nYmFy".from_base64().get(),
        "foobar".as_bytes().to_owned());
}

#[test]
fn test_from_base64_urlsafe() {
    assert_eq!("-_8".from_base64().get(), "+/8=".from_base64().get());
}

#[test]
fn test_from_base64_invalid_char() {
    assert!("Zm$=".from_base64().is_err())
    assert!("Zg==$".from_base64().is_err());
}

#[test]
fn test_from_base64_invalid_padding() {
    assert!("Z===".from_base64().is_err());
}

#[test]
fn test_base64_random() {
    use std::rand::{task_rng, random, RngUtil};
    use std::vec;

    for 1000.times {
        let v: ~[u8] = do vec::build |push| {
            for task_rng().gen_uint_range(1, 100).times {
                push(random());
            }
        };
        assert_eq!(v.to_base64(STANDARD).from_base64().get(), v);
    }
}
<|endoftext|>


<commit_before>// xfail-test #2587
// error-pattern: copying a noncopyable value

struct r {
  let i:int;
  new(i:int) {self.i = i;}
}

impl r : Drop {
    fn finalize() {}
}

fn main() {
    // This can't make sense as it would copy the classes
    let i = move ~[r(0)];
    let j = move ~[r(1)];
    let k = i + j;
    log(debug, j);
}
<commit_msg>Update test and un-xfail it<commit_after>// error-pattern: copying a noncopyable value

struct r {
  i:int
}

fn r(i:int) -> r { r { i: i } }

impl r : Drop {
    fn finalize() {}
}

fn main() {
    // This can't make sense as it would copy the classes
    let i = move ~[r(0)];
    let j = move ~[r(1)];
    let k = i + j;
    log(debug, j);
}
<|endoftext|>


<commit_before><commit_msg>Refactor(config): reduce verbosity in config<commit_after><|endoftext|>


<commit_before>use std::default::Default;
use error::Error;

#[derive(Debug, PartialEq, RustcDecodable, RustcEncodable)]
pub struct Header {
    pub typ: HeaderType,
    pub alg: Option<Algorithm>,
}

#[derive(Debug, PartialEq, RustcDecodable, RustcEncodable)]
pub enum HeaderType {
    JWT,
}

#[derive(Debug, PartialEq, RustcDecodable, RustcEncodable)]
pub enum Algorithm {
    HS256,
}

impl Default for Header {
    fn default() -> Header {
        Header {
            typ: HeaderType::JWT,
            alg: Some(Algorithm::HS256),
        }
    }
}

#[cfg(test)]
mod tests {
    use header::{
        Algorithm,
        Header,
        HeaderType,
    };

    #[test]
    fn parse() {
        let enc = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9";
        let header = Header::parse(enc).unwrap();

        assert_eq!(header.typ, HeaderType::JWT);
        assert_eq!(header.alg.unwrap(), Algorithm::HS256);
    }

    #[test]
    fn roundtrip() {
        let header: Header = Default::default();
        let enc = header.encode().unwrap();
        assert_eq!(header, Header::parse(&*enc).unwrap());
    }
}
<commit_msg>Fix tests<commit_after>use std::default::Default;
use error::Error;

#[derive(Debug, PartialEq, RustcDecodable, RustcEncodable)]
pub struct Header {
    pub typ: HeaderType,
    pub alg: Option<Algorithm>,
}

#[derive(Debug, PartialEq, RustcDecodable, RustcEncodable)]
pub enum HeaderType {
    JWT,
}

#[derive(Debug, PartialEq, RustcDecodable, RustcEncodable)]
pub enum Algorithm {
    HS256,
}

impl Default for Header {
    fn default() -> Header {
        Header {
            typ: HeaderType::JWT,
            alg: Some(Algorithm::HS256),
        }
    }
}

#[cfg(test)]
mod tests {
    use Component;
    use header::{
        Algorithm,
        Header,
        HeaderType,
    };

    #[test]
    fn parse() {
        let enc = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9";
        let header = Header::parse(enc).unwrap();

        assert_eq!(header.typ, HeaderType::JWT);
        assert_eq!(header.alg.unwrap(), Algorithm::HS256);
    }

    #[test]
    fn roundtrip() {
        let header: Header = Default::default();
        let enc = Component::encode(&header).unwrap();
        assert_eq!(header, Header::parse(&*enc).unwrap());
    }
}
<|endoftext|>


<commit_before>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use container::MutableSet;
use hashmap::HashSet;
use option::{Some, None, Option};
use vec::ImmutableVector;

/// Imports for old crate map versions
use cast::transmute;
use libc::c_char;
use ptr;
use str::raw::from_c_str;
use vec;

// Need to tell the linker on OS X to not barf on undefined symbols
// and instead look them up at runtime, which we need to resolve
// the crate_map properly.
#[cfg(target_os = "macos")]
#[link_args = "-undefined dynamic_lookup"]
extern {}

#[cfg(not(windows))]
extern {
    #[weak_linkage]
    #[link_name = "_rust_crate_map_toplevel"]
    static CRATE_MAP: CrateMap<'static>;
}

/// structs for old crate map versions
pub struct ModEntryV0 {
    name: *c_char,
    log_level: *mut u32
}
pub struct CrateMapV0 {
    entries: *ModEntryV0,
    children: [*CrateMapV0, ..1]
}

pub struct CrateMapV1 {
    version: i32,
    entries: *ModEntryV0,
    /// a dynamically sized struct, where all pointers to children are listed adjacent
    /// to the struct, terminated with NULL
    children: [*CrateMapV1, ..1]
}

pub struct ModEntry<'self> {
    name: &'self str,
    log_level: *mut u32
}

pub struct CrateMap<'self> {
    version: i32,
    entries: &'self [ModEntry<'self>],
    children: &'self [&'self CrateMap<'self>]
}

#[cfg(not(windows))]
pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
    let ptr: (*CrateMap) = &'static CRATE_MAP;
    if ptr.is_null() {
        return None;
    } else {
        return Some(&'static CRATE_MAP);
    }
}

#[cfg(windows)]
#[fixed_stack_segment]
#[inline(never)]
pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
    use c_str::ToCStr;
    use unstable::dynamic_lib::dl;

    let sym = unsafe {
        let module = dl::open_internal();
        let sym = do "__rust_crate_map_toplevel".with_c_str |buf| {
            dl::symbol(module, buf)
        };
        dl::close(module);
        sym
    };
    let ptr: (*CrateMap) = sym as *CrateMap;
    if ptr.is_null() {
        return None;
    } else {
        unsafe {
            return Some(transmute(sym));
        }
    }
}

fn version(crate_map: &CrateMap) -> i32 {
    match crate_map.version {
        2 => return 2,
        1 => return 1,
        _ => return 0
    }
}

fn iter_module_map(mod_entries: &[ModEntry], f: &fn(&ModEntry)) {
    for entry in mod_entries.iter() {
        f(entry);
    }
}

unsafe fn iter_module_map_v0(entries: *ModEntryV0, f: &fn(&ModEntry)) {
    let mut curr = entries;
    while !(*curr).name.is_null() {
        let mod_entry = ModEntry { name: from_c_str((*curr).name), log_level: (*curr).log_level };
        f(&mod_entry);
        curr = curr.offset(1);
    }
}

fn do_iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: &fn(&ModEntry),
                            visited: &mut HashSet<*CrateMap<'a>>) {
    if visited.insert(crate_map as *CrateMap) {
        match version(crate_map) {
            2 => {
                let (entries, children) = (crate_map.entries, crate_map.children);
                iter_module_map(entries, |x| f(x));
                for child in children.iter() {
                    do_iter_crate_map(*child, |x| f(x), visited);
                }
            },
            // code for old crate map versions
            1 => unsafe {
                let v1: *CrateMapV1 = transmute(crate_map);
                iter_module_map_v0((*v1).entries, |x| f(x));
                let children = vec::raw::to_ptr((*v1).children);
                do ptr::array_each(children) |child| {
                    do_iter_crate_map(transmute(child), |x| f(x), visited);
                }
            },
            0 => unsafe {
                let v0: *CrateMapV0 = transmute(crate_map);
                iter_module_map_v0((*v0).entries, |x| f(x));
                let children = vec::raw::to_ptr((*v0).children);
                do ptr::array_each(children) |child| {
                    do_iter_crate_map(transmute(child), |x| f(x), visited);
                }
            },
            _ => fail2!("invalid crate map version")
        }
    }
}

/// Iterates recursively over `crate_map` and all child crate maps
pub fn iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: &fn(&ModEntry)) {
    // XXX: use random numbers as keys from the OS-level RNG when there is a nice
    //        way to do this
    let mut v: HashSet<*CrateMap<'a>> = HashSet::with_capacity_and_keys(0, 0, 32);
    do_iter_crate_map(crate_map, f, &mut v);
}

#[cfg(test)]
mod tests {
    use rt::crate_map::{CrateMap, ModEntry, iter_crate_map};

    #[test]
    fn iter_crate_map_duplicates() {
        let mut level3: u32 = 3;

        let entries = [
            ModEntry { name: "c::m1", log_level: &mut level3},
        ];

        let child_crate = CrateMap {
            version: 2,
            entries: entries,
            children: []
        };

        let root_crate = CrateMap {
            version: 2,
            entries: [],
            children: [&child_crate, &child_crate]
        };

        let mut cnt = 0;
        unsafe {
            do iter_crate_map(&root_crate) |entry| {
                assert!(*entry.log_level == 3);
                cnt += 1;
            }
            assert!(cnt == 1);
        }
    }

    #[test]
    fn iter_crate_map_follow_children() {
        let mut level2: u32 = 2;
        let mut level3: u32 = 3;
        let child_crate2 = CrateMap {
            version: 2,
            entries: [
                ModEntry { name: "c::m1", log_level: &mut level2},
                ModEntry { name: "c::m2", log_level: &mut level3},
            ],
            children: []
        };

        let child_crate1 = CrateMap {
            version: 2,
            entries: [
                ModEntry { name: "t::f1", log_level: &mut 1},
            ],
            children: [&child_crate2]
        };

        let root_crate = CrateMap {
            version: 2,
            entries: [
                ModEntry { name: "t::f2", log_level: &mut 0},
            ],
            children: [&child_crate1]
        };

        let mut cnt = 0;
        unsafe {
            do iter_crate_map(&root_crate) |entry| {
                assert!(*entry.log_level == cnt);
                cnt += 1;
            }
            assert!(cnt == 4);
        }
    }

    /// Tests for old crate map versions
    #[test]
    fn iter_crate_map_duplicates_v1() {
        use c_str::ToCStr;
        use cast::transmute;
        use ptr;
        use rt::crate_map::{CrateMapV1, ModEntryV0, iter_crate_map};
        use vec;

        struct CrateMapT3 {
            version: i32,
            entries: *ModEntryV0,
            children: [*CrateMapV1, ..3]
        }

        unsafe {
            let mod_name1 = "c::m1".to_c_str();
            let mut level3: u32 = 3;

            let entries: ~[ModEntryV0] = ~[
                ModEntryV0 { name: mod_name1.with_ref(|buf| buf), log_level: &mut level3},
                ModEntryV0 { name: ptr::null(), log_level: ptr::mut_null()}
            ];
            let child_crate = CrateMapV1 {
                version: 1,
                entries: vec::raw::to_ptr(entries),
                children: [ptr::null()]
            };

            let root_crate = CrateMapT3 {
                version: 1,
                entries: vec::raw::to_ptr([
                    ModEntryV0 { name: ptr::null(), log_level: ptr::mut_null()}
                ]),
                children: [&child_crate as *CrateMapV1, &child_crate as *CrateMapV1, ptr::null()]
            };

            let mut cnt = 0;
            do iter_crate_map(transmute(&root_crate)) |entry| {
                assert!(*(*entry).log_level == 3);
                cnt += 1;
            }
            assert!(cnt == 1);
        }
    }

    #[test]
    fn iter_crate_map_follow_children_v1() {
        use c_str::ToCStr;
        use cast::transmute;
        use ptr;
        use rt::crate_map::{CrateMapV1, ModEntryV0, iter_crate_map};
        use vec;

        struct CrateMapT2 {
            version: i32,
            entries: *ModEntryV0,
            children: [*CrateMapV1, ..2]
        }

        unsafe {
            let mod_name1 = "c::m1".to_c_str();
            let mod_name2 = "c::m2".to_c_str();
            let mut level2: u32 = 2;
            let mut level3: u32 = 3;
            let child_crate2 = CrateMapV1 {
                version: 1,
                entries: vec::raw::to_ptr([
                    ModEntryV0 { name: mod_name1.with_ref(|buf| buf), log_level: &mut level2},
                    ModEntryV0 { name: mod_name2.with_ref(|buf| buf), log_level: &mut level3},
                    ModEntryV0 { name: ptr::null(), log_level: ptr::mut_null()}
                ]),
                children: [ptr::null()]
            };

            let child_crate1 = CrateMapT2 {
                version: 1,
                entries: vec::raw::to_ptr([
                    ModEntryV0 { name: "t::f1".with_c_str(|buf| buf), log_level: &mut 1},
                    ModEntryV0 { name: ptr::null(), log_level: ptr::mut_null()}
                ]),
                children: [&child_crate2 as *CrateMapV1, ptr::null()]
            };

            let child_crate1_ptr: *CrateMapV1 = transmute(&child_crate1);
            let root_crate = CrateMapT2 {
                version: 1,
                entries: vec::raw::to_ptr([
                    ModEntryV0 { name: "t::f1".with_c_str(|buf| buf), log_level: &mut 0},
                    ModEntryV0 { name: ptr::null(), log_level: ptr::mut_null()}
                ]),
                children: [child_crate1_ptr, ptr::null()]
            };

            let mut cnt = 0;
            do iter_crate_map(transmute(&root_crate)) |entry| {
                assert!(*(*entry).log_level == cnt);
                cnt += 1;
            }
            assert!(cnt == 4);
        }
    }
}
<commit_msg>Remove support for older CrateMap versions<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use container::MutableSet;
use hashmap::HashSet;
use option::{Some, None, Option};
use vec::ImmutableVector;

// Need to tell the linker on OS X to not barf on undefined symbols
// and instead look them up at runtime, which we need to resolve
// the crate_map properly.
#[cfg(target_os = "macos")]
#[link_args = "-undefined dynamic_lookup"]
extern {}

pub struct ModEntry<'self> {
    name: &'self str,
    log_level: *mut u32
}

pub struct CrateMap<'self> {
    version: i32,
    entries: &'self [ModEntry<'self>],
    children: &'self [&'self CrateMap<'self>]
}

#[cfg(not(windows))]
pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
    extern {
        #[weak_linkage]
        #[link_name = "_rust_crate_map_toplevel"]
        static CRATE_MAP: CrateMap<'static>;
    }

    let ptr: (*CrateMap) = &'static CRATE_MAP;
    if ptr.is_null() {
        return None;
    } else {
        return Some(&'static CRATE_MAP);
    }
}

#[cfg(windows)]
#[fixed_stack_segment]
#[inline(never)]
pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
    use cast::transmute;
    use c_str::ToCStr;
    use unstable::dynamic_lib::dl;

    let sym = unsafe {
        let module = dl::open_internal();
        let sym = do "__rust_crate_map_toplevel".with_c_str |buf| {
            dl::symbol(module, buf)
        };
        dl::close(module);
        sym
    };
    let ptr: (*CrateMap) = sym as *CrateMap;
    if ptr.is_null() {
        return None;
    } else {
        unsafe {
            return Some(transmute(sym));
        }
    }
}

fn version(crate_map: &CrateMap) -> i32 {
    match crate_map.version {
        2 => return 2,
        _ => return 0
    }
}

fn do_iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: &fn(&ModEntry),
                            visited: &mut HashSet<*CrateMap<'a>>) {
    if visited.insert(crate_map as *CrateMap) {
        match version(crate_map) {
            2 => {
                let (entries, children) = (crate_map.entries, crate_map.children);
                for entry in entries.iter() {
                    f(entry);
                }
                for child in children.iter() {
                    do_iter_crate_map(*child, |x| f(x), visited);
                }
            },
            _ => fail2!("invalid crate map version")
        }
    }
}

/// Iterates recursively over `crate_map` and all child crate maps
pub fn iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: &fn(&ModEntry)) {
    // XXX: use random numbers as keys from the OS-level RNG when there is a nice
    //        way to do this
    let mut v: HashSet<*CrateMap<'a>> = HashSet::with_capacity_and_keys(0, 0, 32);
    do_iter_crate_map(crate_map, f, &mut v);
}

#[cfg(test)]
mod tests {
    use rt::crate_map::{CrateMap, ModEntry, iter_crate_map};

    #[test]
    fn iter_crate_map_duplicates() {
        let mut level3: u32 = 3;

        let entries = [
            ModEntry { name: "c::m1", log_level: &mut level3},
        ];

        let child_crate = CrateMap {
            version: 2,
            entries: entries,
            children: []
        };

        let root_crate = CrateMap {
            version: 2,
            entries: [],
            children: [&child_crate, &child_crate]
        };

        let mut cnt = 0;
        unsafe {
            do iter_crate_map(&root_crate) |entry| {
                assert!(*entry.log_level == 3);
                cnt += 1;
            }
            assert!(cnt == 1);
        }
    }

    #[test]
    fn iter_crate_map_follow_children() {
        let mut level2: u32 = 2;
        let mut level3: u32 = 3;
        let child_crate2 = CrateMap {
            version: 2,
            entries: [
                ModEntry { name: "c::m1", log_level: &mut level2},
                ModEntry { name: "c::m2", log_level: &mut level3},
            ],
            children: []
        };

        let child_crate1 = CrateMap {
            version: 2,
            entries: [
                ModEntry { name: "t::f1", log_level: &mut 1},
            ],
            children: [&child_crate2]
        };

        let root_crate = CrateMap {
            version: 2,
            entries: [
                ModEntry { name: "t::f2", log_level: &mut 0},
            ],
            children: [&child_crate1]
        };

        let mut cnt = 0;
        unsafe {
            do iter_crate_map(&root_crate) |entry| {
                assert!(*entry.log_level == cnt);
                cnt += 1;
            }
            assert!(cnt == 4);
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Inlined accessor functions for chunk<commit_after><|endoftext|>


<commit_before><commit_msg>Fix binop parsing<commit_after><|endoftext|>


<commit_before>//! Window abstraction

use std::cell::RefCell;
use input::InputEvent;
use current::{ Get, Usage };

use GenericEvent;

/// Whether window should close or not.
pub struct ShouldClose(pub bool);

/// The size of the window.
pub struct Size(pub [u32, ..2]);

/// Implemented by windows that can swap buffers.
pub trait SwapBuffers {
    /// Swaps the buffers.
    fn swap_buffers(&mut self);
}

impl<'a, W: 'a + SwapBuffers> SwapBuffers for Usage<'a, W> {
    #[inline(always)]
    fn swap_buffers(&mut self) {
        self.with_unwrap(|window: &RefCell<W>| {
            window.borrow_mut().deref_mut().swap_buffers()
        })
    }
}

impl<'a, W: 'a + SwapBuffers> SwapBuffers for &'a RefCell<W> {
    #[inline(always)]
    fn swap_buffers(&mut self) {
        self.borrow_mut().deref_mut().swap_buffers()
    }
}

/// Implemented by windows that can pull events.
pub trait PollEvent<E: GenericEvent> {
    /// Polls event from window.
    fn poll_event(&mut self) -> Option<E>;
}

impl<'a, W: 'a + PollEvent<I>, I: GenericEvent> PollEvent<I> for Usage<'a, W> {
    #[inline(always)]
    fn poll_event(&mut self) -> Option<I> {
        self.with_unwrap(|window: &RefCell<W>| {
            window.borrow_mut().deref_mut().poll_event()
        })
    }
}

impl<'a, W: 'a + PollEvent<I>, I: GenericEvent> PollEvent<I> for &'a RefCell<W> {
    #[inline(always)]
    fn poll_event(&mut self) -> Option<I> {
        self.borrow_mut().deref_mut().poll_event()
    }
}

/// Settings for window behavior.
pub struct WindowSettings {
    /// Title of the window.
    pub title: String,
    /// The size of the window.
    pub size: [u32, ..2],
    /// Number samples per pixel (anti-aliasing).
    pub samples: u8,
    /// If true, the window is fullscreen.
    pub fullscreen: bool,
    /// If true, exit when pressing Esc.
    pub exit_on_esc: bool,
}

impl WindowSettings {
    /// Gets default settings.
    ///
    /// This exits the window when pressing `Esc`.
    /// The background color is set to black.
    pub fn default() -> WindowSettings {
        WindowSettings {
            title: "Piston".to_string(),
            size: [640, 480],
            samples: 0,
            fullscreen: false,
            exit_on_esc: true,
        }
    }
}

/// Work-around trait for `Get<ShouldClose>`.
/// Used to support generic constraints.
pub trait GetShouldClose: Get<ShouldClose> {
    /// Returns whether window should close.
    fn get_should_close(&self) -> ShouldClose {
        self.get()
    }
}

impl<T: Get<ShouldClose>> GetShouldClose for T {}

/// Work-around trait for `Get<Size>`.
/// Used to support generic constraints.
pub trait GetSize: Get<Size> {
    /// Returns the size of window.
    fn get_size(&self) -> Size {
        self.get()
    }
}

impl<T: Get<Size>> GetSize for T {}

/// Implemented by window back-end.
pub trait Window<E: GenericEvent = InputEvent>:
    SwapBuffers
  + PollEvent<E>
  + GetShouldClose
  + GetSize {
    /// Get the window's settings.
    fn get_settings<'a>(&'a self) -> &'a WindowSettings;

    /// Inform the window that it should close.
    fn close(&mut self);

    /// Get the size in drawing coordinates.
    fn get_draw_size(&self) -> (u32, u32);

    /// When the cursor is captured,
    /// it is hidden and the cursor position does not change.
    /// Only relative mouse motion is registered.
    fn capture_cursor(&mut self, _enabled: bool);
}

/// An implementation of Window that runs without a window at all.
pub struct NoWindow {
    settings: WindowSettings,
    should_close: bool
}

impl NoWindow {
    /// Returns a new `NoWindow`.
    pub fn new(settings: WindowSettings) -> NoWindow {
         NoWindow {
             settings: settings,
             should_close: false
         }
    }
}

impl SwapBuffers for NoWindow {
    fn swap_buffers(&mut self) {}
}

impl PollEvent<InputEvent> for NoWindow {
    fn poll_event(&mut self) -> Option<InputEvent> { None }
}

impl Get<ShouldClose> for NoWindow {
    fn get(&self) -> ShouldClose {
        ShouldClose(self.should_close)
    }
}

impl Get<Size> for NoWindow {
    fn get(&self) -> Size {
        Size([0, 0])
    }
}

impl Window<InputEvent> for NoWindow {
     fn get_settings<'a>(&'a self) -> &'a WindowSettings {
        &self.settings
     }

    fn close(&mut self) {
        self.should_close = true
    }

    fn get_draw_size(&self) -> (u32, u32) {
        let Size([w, h]) = self.get_size();
        (w, h)
    }

    fn capture_cursor(&mut self, _enabled: bool) {}
}
<commit_msg>Added SetShouldClose and SetSize<commit_after>//! Window abstraction

use std::cell::RefCell;
use input::InputEvent;
use current::{ Get, Set, Usage };

use GenericEvent;

/// Whether window should close or not.
pub struct ShouldClose(pub bool);

/// Work-around trait for `Get<ShouldClose>`.
/// Used to support generic constraints.
pub trait GetShouldClose: Get<ShouldClose> {
    /// Returns whether window should close.
    fn get_should_close(&self) -> ShouldClose {
        self.get()
    }
}

impl<T: Get<ShouldClose>> GetShouldClose for T {}

/// Work-around trait for `Set<ShouldClose>`.
/// Used to support generic constraints.
/// This must be implemented for every `Modifier` impl.
pub trait SetShouldClose: Set<ShouldClose> {
    /// Sets whether window should close.
    fn set_should_close(&mut self, val: ShouldClose);
}

/// The size of the window.
pub struct Size(pub [u32, ..2]);

/// Work-around trait for `Get<Size>`.
/// Used to support generic constraints.
pub trait GetSize: Get<Size> {
    /// Returns the size of window.
    fn get_size(&self) -> Size {
        self.get()
    }
}

impl<T: Get<Size>> GetSize for T {}

/// Work-around trait for `Get<Size>`.
/// Used to support generic constraints.
/// This must be implemented for every `Modifier` impl.
pub trait SetSize: Set<Size> {
    /// Sets size of window.
    fn set_size(&mut self, val: Size);
}

#[test]
fn test_methods() {
    use current::Modifier;

    struct Obj;

    impl Get<ShouldClose> for Obj {
        fn get(&self) -> ShouldClose { ShouldClose(false) }
    }

    impl Modifier<Obj> for ShouldClose {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl SetShouldClose for Obj {
        fn set_should_close(&mut self, val: ShouldClose) {
            self.set_mut(val);
        }
    }

    impl Get<Size> for Obj {
        fn get(&self) -> Size { Size([0, 0]) }
    }

    impl Modifier<Obj> for Size {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl SetSize for Obj {
        fn set_size(&mut self, val: Size) {
            self.set_mut(val);
        }
    }

    fn foo<T: GetShouldClose
            + GetSize
            + SetShouldClose
            + SetSize>(_obj: T) {}

    foo(Obj);
}

/// Implemented by windows that can swap buffers.
pub trait SwapBuffers {
    /// Swaps the buffers.
    fn swap_buffers(&mut self);
}

impl<'a, W: 'a + SwapBuffers> SwapBuffers for Usage<'a, W> {
    #[inline(always)]
    fn swap_buffers(&mut self) {
        self.with_unwrap(|window: &RefCell<W>| {
            window.borrow_mut().deref_mut().swap_buffers()
        })
    }
}

impl<'a, W: 'a + SwapBuffers> SwapBuffers for &'a RefCell<W> {
    #[inline(always)]
    fn swap_buffers(&mut self) {
        self.borrow_mut().deref_mut().swap_buffers()
    }
}

/// Implemented by windows that can pull events.
pub trait PollEvent<E: GenericEvent> {
    /// Polls event from window.
    fn poll_event(&mut self) -> Option<E>;
}

impl<'a, W: 'a + PollEvent<I>, I: GenericEvent> PollEvent<I> for Usage<'a, W> {
    #[inline(always)]
    fn poll_event(&mut self) -> Option<I> {
        self.with_unwrap(|window: &RefCell<W>| {
            window.borrow_mut().deref_mut().poll_event()
        })
    }
}

impl<'a, W: 'a + PollEvent<I>, I: GenericEvent> PollEvent<I> for &'a RefCell<W> {
    #[inline(always)]
    fn poll_event(&mut self) -> Option<I> {
        self.borrow_mut().deref_mut().poll_event()
    }
}

/// Settings for window behavior.
pub struct WindowSettings {
    /// Title of the window.
    pub title: String,
    /// The size of the window.
    pub size: [u32, ..2],
    /// Number samples per pixel (anti-aliasing).
    pub samples: u8,
    /// If true, the window is fullscreen.
    pub fullscreen: bool,
    /// If true, exit when pressing Esc.
    pub exit_on_esc: bool,
}

impl WindowSettings {
    /// Gets default settings.
    ///
    /// This exits the window when pressing `Esc`.
    /// The background color is set to black.
    pub fn default() -> WindowSettings {
        WindowSettings {
            title: "Piston".to_string(),
            size: [640, 480],
            samples: 0,
            fullscreen: false,
            exit_on_esc: true,
        }
    }
}

/// Implemented by window back-end.
pub trait Window<E: GenericEvent = InputEvent>:
    SwapBuffers
  + PollEvent<E>
  + GetShouldClose
  + GetSize {
    /// Get the window's settings.
    fn get_settings<'a>(&'a self) -> &'a WindowSettings;

    /// Inform the window that it should close.
    fn close(&mut self);

    /// Get the size in drawing coordinates.
    fn get_draw_size(&self) -> (u32, u32);

    /// When the cursor is captured,
    /// it is hidden and the cursor position does not change.
    /// Only relative mouse motion is registered.
    fn capture_cursor(&mut self, _enabled: bool);
}

/// An implementation of Window that runs without a window at all.
pub struct NoWindow {
    settings: WindowSettings,
    should_close: bool
}

impl NoWindow {
    /// Returns a new `NoWindow`.
    pub fn new(settings: WindowSettings) -> NoWindow {
         NoWindow {
             settings: settings,
             should_close: false
         }
    }
}

impl SwapBuffers for NoWindow {
    fn swap_buffers(&mut self) {}
}

impl PollEvent<InputEvent> for NoWindow {
    fn poll_event(&mut self) -> Option<InputEvent> { None }
}

impl Get<ShouldClose> for NoWindow {
    fn get(&self) -> ShouldClose {
        ShouldClose(self.should_close)
    }
}

impl Get<Size> for NoWindow {
    fn get(&self) -> Size {
        Size([0, 0])
    }
}

impl Window<InputEvent> for NoWindow {
     fn get_settings<'a>(&'a self) -> &'a WindowSettings {
        &self.settings
     }

    fn close(&mut self) {
        self.should_close = true
    }

    fn get_draw_size(&self) -> (u32, u32) {
        let Size([w, h]) = self.get_size();
        (w, h)
    }

    fn capture_cursor(&mut self, _enabled: bool) {}
}
<|endoftext|>


<commit_before>use std::fmt;
use std::ascii::AsciiExt;

use header::{Header, Raw, parsing};

/// `Referrer-Policy` header, part of
/// [Referrer Policy](https://www.w3.org/TR/referrer-policy/#referrer-policy-header)
///
/// The `Referrer-Policy` HTTP header specifies the referrer
/// policy that the user agent applies when determining what
/// referrer information should be included with requests made,
/// and with browsing contexts created from the context of the
/// protected resource.
///
/// # ABNF
/// ```plain
/// Referrer-Policy: 1#policy-token
/// policy-token   = "no-referrer" / "no-referrer-when-downgrade"
///                  / "same-origin" / "origin"
///                  / "origin-when-cross-origin" / "unsafe-url"
/// ```
///
/// # Example values
/// * `no-referrer`
///
/// # Example
/// ```
/// use hyper::header::{Headers, ReferrerPolicy};
///
/// let mut headers = Headers::new();
/// headers.set(ReferrerPolicy::NoReferrer);
/// ```
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum ReferrerPolicy {
    /// `no-referrer`
    NoReferrer,
    /// `no-referrer-when-downgrade`
    NoReferrerWhenDowngrade,
    /// `same-origin`
    SameOrigin,
    /// `origin`
    Origin,
    /// `origin-when-cross-origin`
    OriginWhenCrossOrigin,
    /// `unsafe-url`
    UnsafeUrl,
}

impl Header for ReferrerPolicy {
    fn header_name() -> &'static str {
        static NAME: &'static str = "Referrer-Policy";
        NAME
    }

    fn parse_header(raw: &Raw) -> ::Result<ReferrerPolicy> {
        use self::ReferrerPolicy::*;
        // See https://www.w3.org/TR/referrer-policy/#determine-policy-for-token
        let headers: Vec<String> = try!(parsing::from_comma_delimited(raw));

        for h in headers.iter().rev() {
            let slice = &h.to_ascii_lowercase()[..];
            match slice {
                "no-referrer" | "never" => return Ok(NoReferrer),
                "no-referrer-when-downgrade" | "default" => return Ok(NoReferrerWhenDowngrade),
                "same-origin" => return Ok(SameOrigin),
                "origin" => return Ok(Origin),
                "origin-when-cross-origin" => return Ok(OriginWhenCrossOrigin),
                "unsafe-url" | "always" => return Ok(UnsafeUrl),
                _ => continue,
            }
        }

        Err(::Error::Header)
    }

    fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::ReferrerPolicy::*;
        f.write_str(match *self {
            NoReferrer => "no-referrer",
            NoReferrerWhenDowngrade => "no-referrer-when-downgrade",
            SameOrigin => "same-origin",
            Origin => "origin",
            OriginWhenCrossOrigin => "origin-when-cross-origin",
            UnsafeUrl => "unsafe-url",
        })
    }
}

#[test]
fn test_parse_header() {
    let a: ReferrerPolicy = Header::parse_header(&"origin".into()).unwrap();
    let b = ReferrerPolicy::Origin;
    assert_eq!(a, b);
    let e: ::Result<ReferrerPolicy> = Header::parse_header(&"foobar".into());
    assert!(e.is_err());
}

#[test]
fn test_rightmost_header() {
    let a: ReferrerPolicy = Header::parse_header(&"same-origin, origin, foobar".into()).unwrap();
    let b = ReferrerPolicy::Origin;
    assert_eq!(a, b);
}
<commit_msg>feat(headers): Add strict-origin and strict-origin-when-cross-origin referer policy<commit_after>use std::fmt;
use std::ascii::AsciiExt;

use header::{Header, Raw, parsing};

/// `Referrer-Policy` header, part of
/// [Referrer Policy](https://www.w3.org/TR/referrer-policy/#referrer-policy-header)
///
/// The `Referrer-Policy` HTTP header specifies the referrer
/// policy that the user agent applies when determining what
/// referrer information should be included with requests made,
/// and with browsing contexts created from the context of the
/// protected resource.
///
/// # ABNF
/// ```plain
/// Referrer-Policy: 1#policy-token
/// policy-token   = "no-referrer" / "no-referrer-when-downgrade"
///                  / "same-origin" / "origin"
///                  / "origin-when-cross-origin" / "unsafe-url"
/// ```
///
/// # Example values
/// * `no-referrer`
///
/// # Example
/// ```
/// use hyper::header::{Headers, ReferrerPolicy};
///
/// let mut headers = Headers::new();
/// headers.set(ReferrerPolicy::NoReferrer);
/// ```
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum ReferrerPolicy {
    /// `no-referrer`
    NoReferrer,
    /// `no-referrer-when-downgrade`
    NoReferrerWhenDowngrade,
    /// `same-origin`
    SameOrigin,
    /// `origin`
    Origin,
    /// `origin-when-cross-origin`
    OriginWhenCrossOrigin,
    /// `unsafe-url`
    UnsafeUrl,
     /// `strict-origin`
    StrictOrigin,
    ///`strict-origin-when-cross-origin`
    StrictOriginWhenCrossOrigin,
}

impl Header for ReferrerPolicy {
    fn header_name() -> &'static str {
        static NAME: &'static str = "Referrer-Policy";
        NAME
    }

    fn parse_header(raw: &Raw) -> ::Result<ReferrerPolicy> {
        use self::ReferrerPolicy::*;
        // See https://www.w3.org/TR/referrer-policy/#determine-policy-for-token
        let headers: Vec<String> = try!(parsing::from_comma_delimited(raw));

        for h in headers.iter().rev() {
            let slice = &h.to_ascii_lowercase()[..];
            match slice {
                "no-referrer" | "never" => return Ok(NoReferrer),
                "no-referrer-when-downgrade" | "default" => return Ok(NoReferrerWhenDowngrade),
                "same-origin" => return Ok(SameOrigin),
                "origin" => return Ok(Origin),
                "origin-when-cross-origin" => return Ok(OriginWhenCrossOrigin),
                "strict-origin" => return Ok(StrictOrigin),
                "strict-origin-when-cross-origin" => return Ok(StrictOriginWhenCrossOrigin),
                "unsafe-url" | "always" => return Ok(UnsafeUrl),
                _ => continue,
            }
        }

        Err(::Error::Header)
    }

    fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::ReferrerPolicy::*;
        f.write_str(match *self {
            NoReferrer => "no-referrer",
            NoReferrerWhenDowngrade => "no-referrer-when-downgrade",
            SameOrigin => "same-origin",
            Origin => "origin",
            OriginWhenCrossOrigin => "origin-when-cross-origin",
            StrictOrigin => "strict-origin",
            StrictOriginWhenCrossOrigin => "strict-origin-when-cross-origin",
            UnsafeUrl => "unsafe-url",
        })
    }
}

#[test]
fn test_parse_header() {
    let a: ReferrerPolicy = Header::parse_header(&"origin".into()).unwrap();
    let b = ReferrerPolicy::Origin;
    assert_eq!(a, b);
    let e: ::Result<ReferrerPolicy> = Header::parse_header(&"foobar".into());
    assert!(e.is_err());
}

#[test]
fn test_rightmost_header() {
    let a: ReferrerPolicy = Header::parse_header(&"same-origin, origin, foobar".into()).unwrap();
    let b = ReferrerPolicy::Origin;
    assert_eq!(a, b);
}
<|endoftext|>


<commit_before><commit_msg>Test for incorrect remote type deserializing<commit_after>#[macro_use]
extern crate serde_derive;

mod remote {
    pub struct S(pub u16);
}

#[derive(Deserialize)] //~ ERROR: mismatched types
#[serde(remote = "remote::S")]
struct S(u8); //~^^ expected u16, found u8

fn main() {}
<|endoftext|>


<commit_before><commit_msg>How does merge conflict?<commit_after><|endoftext|>


<commit_before><commit_msg>box place study<commit_after>#![feature(box_syntax)]
#![feature(box_heap)]
#![feature(placement_in_syntax)]
#![feature(placement_new_protocol)]
#![feature(collection_placement)]

struct A(u32);

use std::boxed::HEAP;

fn main() {
    let mut map = std::collections::HashMap::new();

    let k = 8;
    let v = 10;

    map.entry(k) <- v;

    let b = box 1234;

    let b = Box::new(5);

    println!("{}", b);

    let mut vec = vec![A(1),A(2)];
    {
        let a = (vec.place_back() <- A(3));
        a.0 = 4;
    }
    let b = (vec.place_back() <- A(3));
}<|endoftext|>


<commit_before><commit_msg>Final piece to the puzzle<commit_after><|endoftext|>