]> git.proxmox.com Git - rustc.git/blame - src/librustc/middle/fast_reject.rs
Imported Upstream version 1.3.0+dfsg1
[rustc.git] / src / librustc / middle / fast_reject.rs
CommitLineData
1a4d82fc
JJ
1// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11use middle::ty::{self, Ty};
12use syntax::ast;
13
14use self::SimplifiedType::*;
15
16/// See `simplify_type
17#[derive(Clone, Copy, PartialEq, Eq, Hash)]
18pub enum SimplifiedType {
19 BoolSimplifiedType,
20 CharSimplifiedType,
21 IntSimplifiedType(ast::IntTy),
22 UintSimplifiedType(ast::UintTy),
23 FloatSimplifiedType(ast::FloatTy),
24 EnumSimplifiedType(ast::DefId),
25 StrSimplifiedType,
26 VecSimplifiedType,
27 PtrSimplifiedType,
c34b1796 28 TupleSimplifiedType(usize),
1a4d82fc
JJ
29 TraitSimplifiedType(ast::DefId),
30 StructSimplifiedType(ast::DefId),
85aaf69f 31 ClosureSimplifiedType(ast::DefId),
c34b1796 32 FunctionSimplifiedType(usize),
1a4d82fc
JJ
33 ParameterSimplifiedType,
34}
35
36/// Tries to simplify a type by dropping type parameters, deref'ing away any reference types, etc.
37/// The idea is to get something simple that we can use to quickly decide if two types could unify
38/// during method lookup.
39///
40/// If `can_simplify_params` is false, then we will fail to simplify type parameters entirely. This
41/// is useful when those type parameters would be instantiated with fresh type variables, since
42/// then we can't say much about whether two types would unify. Put another way,
43/// `can_simplify_params` should be true if type parameters appear free in `ty` and `false` if they
44/// are to be considered bound.
45pub fn simplify_type(tcx: &ty::ctxt,
46 ty: Ty,
47 can_simplify_params: bool)
48 -> Option<SimplifiedType>
49{
50 match ty.sty {
62682a34
SL
51 ty::TyBool => Some(BoolSimplifiedType),
52 ty::TyChar => Some(CharSimplifiedType),
53 ty::TyInt(int_type) => Some(IntSimplifiedType(int_type)),
54 ty::TyUint(uint_type) => Some(UintSimplifiedType(uint_type)),
55 ty::TyFloat(float_type) => Some(FloatSimplifiedType(float_type)),
56 ty::TyEnum(def_id, _) => Some(EnumSimplifiedType(def_id)),
57 ty::TyStr => Some(StrSimplifiedType),
58 ty::TyArray(..) | ty::TySlice(_) => Some(VecSimplifiedType),
59 ty::TyRawPtr(_) => Some(PtrSimplifiedType),
60 ty::TyTrait(ref trait_info) => {
1a4d82fc
JJ
61 Some(TraitSimplifiedType(trait_info.principal_def_id()))
62 }
62682a34 63 ty::TyStruct(def_id, _) => {
1a4d82fc
JJ
64 Some(StructSimplifiedType(def_id))
65 }
62682a34 66 ty::TyRef(_, mt) => {
1a4d82fc
JJ
67 // since we introduce auto-refs during method lookup, we
68 // just treat &T and T as equivalent from the point of
69 // view of possibly unifying
70 simplify_type(tcx, mt.ty, can_simplify_params)
71 }
62682a34 72 ty::TyBox(_) => {
1a4d82fc 73 // treat like we would treat `Box`
c1a9b12d
SL
74 match tcx.lang_items.require_owned_box() {
75 Ok(def_id) => Some(StructSimplifiedType(def_id)),
76 Err(msg) => tcx.sess.fatal(&msg),
77 }
1a4d82fc 78 }
62682a34 79 ty::TyClosure(def_id, _) => {
85aaf69f 80 Some(ClosureSimplifiedType(def_id))
1a4d82fc 81 }
62682a34 82 ty::TyTuple(ref tys) => {
1a4d82fc
JJ
83 Some(TupleSimplifiedType(tys.len()))
84 }
62682a34 85 ty::TyBareFn(_, ref f) => {
1a4d82fc
JJ
86 Some(FunctionSimplifiedType(f.sig.0.inputs.len()))
87 }
62682a34 88 ty::TyProjection(_) => {
1a4d82fc
JJ
89 None
90 }
62682a34 91 ty::TyParam(_) => {
1a4d82fc
JJ
92 if can_simplify_params {
93 Some(ParameterSimplifiedType)
94 } else {
95 None
96 }
97 }
62682a34 98 ty::TyInfer(_) | ty::TyError => None,
1a4d82fc
JJ
99 }
100}