-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
auto merge of #18694 : nikomatsakis/rust/issue-18208-method-dispatch-…
…2, r=nrc This is a pretty major refactoring of the method dispatch infrastructure. It is intended to avoid gross inefficiencies and enable caching and other optimizations (e.g. #17995), though it itself doesn't seem to execute particularly faster yet. It also solves some cases where we were failing to resolve methods that we theoretically should have succeeded with. Fixes #18674. cc #18208
- Loading branch information
Showing
25 changed files
with
2,643 additions
and
2,074 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
// 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 middle::ty; | ||
use syntax::ast; | ||
|
||
use self::SimplifiedType::*; | ||
|
||
/** See `simplify_type */ | ||
#[deriving(Clone, PartialEq, Eq, Hash)] | ||
pub enum SimplifiedType { | ||
BoolSimplifiedType, | ||
CharSimplifiedType, | ||
IntSimplifiedType(ast::IntTy), | ||
UintSimplifiedType(ast::UintTy), | ||
FloatSimplifiedType(ast::FloatTy), | ||
EnumSimplifiedType(ast::DefId), | ||
StrSimplifiedType, | ||
VecSimplifiedType, | ||
PtrSimplifiedType, | ||
TupleSimplifiedType(uint), | ||
TraitSimplifiedType(ast::DefId), | ||
StructSimplifiedType(ast::DefId), | ||
UnboxedClosureSimplifiedType(ast::DefId), | ||
FunctionSimplifiedType(uint), | ||
ParameterSimplifiedType, | ||
} | ||
|
||
pub fn simplify_type(tcx: &ty::ctxt, | ||
ty: ty::t, | ||
can_simplify_params: bool) | ||
-> Option<SimplifiedType> | ||
{ | ||
/*! | ||
* Tries to simplify a type by dropping type parameters, deref'ing | ||
* away any reference types, etc. The idea is to get something | ||
* simple that we can use to quickly decide if two types could | ||
* unify during method lookup. | ||
* | ||
* If `can_simplify_params` is false, then we will fail to | ||
* simplify type parameters entirely. This is useful when those | ||
* type parameters would be instantiated with fresh type | ||
* variables, since then we can't say much about whether two types | ||
* would unify. Put another way, `can_simplify_params` should be | ||
* true if type parameters appear free in `ty` and `false` if they | ||
* are to be considered bound. | ||
*/ | ||
|
||
match ty::get(ty).sty { | ||
ty::ty_bool => Some(BoolSimplifiedType), | ||
ty::ty_char => Some(CharSimplifiedType), | ||
ty::ty_int(int_type) => Some(IntSimplifiedType(int_type)), | ||
ty::ty_uint(uint_type) => Some(UintSimplifiedType(uint_type)), | ||
ty::ty_float(float_type) => Some(FloatSimplifiedType(float_type)), | ||
ty::ty_enum(def_id, _) => Some(EnumSimplifiedType(def_id)), | ||
ty::ty_str => Some(StrSimplifiedType), | ||
ty::ty_vec(..) => Some(VecSimplifiedType), | ||
ty::ty_ptr(_) => Some(PtrSimplifiedType), | ||
ty::ty_trait(ref trait_info) => { | ||
Some(TraitSimplifiedType(trait_info.principal.def_id)) | ||
} | ||
ty::ty_struct(def_id, _) => { | ||
Some(StructSimplifiedType(def_id)) | ||
} | ||
ty::ty_rptr(_, mt) => { | ||
// since we introduce auto-refs during method lookup, we | ||
// just treat &T and T as equivalent from the point of | ||
// view of possibly unifying | ||
simplify_type(tcx, mt.ty, can_simplify_params) | ||
} | ||
ty::ty_uniq(_) => { | ||
// treat like we would treat `Box` | ||
let def_id = tcx.lang_items.owned_box().unwrap(); | ||
Some(StructSimplifiedType(def_id)) | ||
} | ||
ty::ty_unboxed_closure(def_id, _, _) => { | ||
Some(UnboxedClosureSimplifiedType(def_id)) | ||
} | ||
ty::ty_tup(ref tys) => { | ||
Some(TupleSimplifiedType(tys.len())) | ||
} | ||
ty::ty_closure(ref f) => { | ||
Some(FunctionSimplifiedType(f.sig.inputs.len())) | ||
} | ||
ty::ty_bare_fn(ref f) => { | ||
Some(FunctionSimplifiedType(f.sig.inputs.len())) | ||
} | ||
ty::ty_param(_) => { | ||
if can_simplify_params { | ||
Some(ParameterSimplifiedType) | ||
} else { | ||
None | ||
} | ||
} | ||
ty::ty_open(_) | ty::ty_infer(_) | ty::ty_err => None, | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.