Skip to content

Commit db94efa

Browse files
committed
Refactor mod/check (part vii)
1 parent 9bb40b0 commit db94efa

File tree

1 file changed

+67
-38
lines changed
  • src/librustc_typeck/check

1 file changed

+67
-38
lines changed

src/librustc_typeck/check/mod.rs

Lines changed: 67 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ use rustc::infer::anon_types::AnonTypeDecl;
9595
use rustc::infer::type_variable::{TypeVariableOrigin};
9696
use rustc::middle::region;
9797
use rustc::mir::interpret::{GlobalId};
98-
use rustc::ty::subst::{UnpackedKind, Subst, Substs};
98+
use rustc::ty::subst::{Kind, UnpackedKind, Subst, Substs};
9999
use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
100100
use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind, Visibility, ToPredicate, RegionKind};
101101
use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
@@ -4967,7 +4967,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
49674967
let def_id = def.def_id();
49684968
let mut parent_defs = self.tcx.generics_of(def_id);
49694969
let count = parent_defs.count();
4970-
let mut substs = if count <= 8 {
4970+
let mut substs: AccumulateVec<[Kind<'tcx>; 8]> = if count <= 8 {
49714971
AccumulateVec::Array(ArrayVec::new())
49724972
} else {
49734973
AccumulateVec::Heap(Vec::with_capacity(count))
@@ -4977,74 +4977,103 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
49774977
parent_defs = self.tcx.generics_of(def_id);
49784978
stack.push((def_id, parent_defs));
49794979
}
4980+
macro_rules! push_to_substs {
4981+
($kind:expr) => {
4982+
let k = $kind;
4983+
match substs {
4984+
AccumulateVec::Array(ref mut arr) => arr.push(k),
4985+
AccumulateVec::Heap(ref mut vec) => vec.push(k),
4986+
}
4987+
}
4988+
};
49804989
while let Some((def_id, defs)) = stack.pop() {
4981-
Substs::fill_single(&mut substs, defs, &mut |param: &ty::GenericParamDef, substs| {
4982-
if param.index == 0 && has_self {
4983-
if let GenericParamDefKind::Type { .. } = param.kind {
4984-
// Handle `Self` first, so we can adjust the index to match the AST.
4985-
return opt_self_ty.map(|ty| ty.into()).unwrap_or_else(|| {
4986-
self.var_for_def(span, param)
4987-
});
4990+
let mut params = defs.params.iter().peekable();
4991+
let mut remove_self = false;
4992+
if has_self {
4993+
if let Some(param) = params.peek() {
4994+
if param.index == 0 {
4995+
if let GenericParamDefKind::Type { .. } = param.kind {
4996+
// Handle `Self` first, so we can adjust the index to match the AST.
4997+
push_to_substs!(opt_self_ty.map(|ty| ty.into()).unwrap_or_else(|| {
4998+
self.var_for_def(span, param)
4999+
}));
5000+
remove_self = true;
5001+
}
49885002
}
49895003
}
5004+
}
5005+
if remove_self {
5006+
params.next();
5007+
}
49905008

4991-
let infer_types = if let Some(&PathSeg(_, index)) = path_segs
4992-
.iter()
4993-
.find(|&PathSeg(did, _)| *did == def_id) {
4994-
4995-
if supress_errors[&index] {
4996-
true
4997-
} else {
4998-
if let Some(ref data) = segments[index].args {
4999-
let self_offset = (defs.parent_count == 0 && has_self) as usize;
5000-
let param_idx =
5001-
(param.index as usize - defs.parent_count - self_offset)
5002-
.saturating_sub(infer_lifetimes[&index]);
5003-
if let Some(arg) = data.args.get(param_idx) {
5009+
let mut infer_types = true;
5010+
if let Some(&PathSeg(_, index)) = path_segs
5011+
.iter()
5012+
.find(|&PathSeg(did, _)| *did == def_id) {
5013+
if !supress_errors[&index] {
5014+
infer_types = segments[index].infer_types;
5015+
if let Some(ref data) = segments[index].args {
5016+
let args = &data.args;
5017+
'args: for arg in args {
5018+
while let Some(param) = params.next() {
50045019
match param.kind {
50055020
GenericParamDefKind::Lifetime => match arg {
50065021
GenericArg::Lifetime(lt) => {
5007-
return AstConv::ast_region_to_region(self,
5008-
lt, Some(param)).into();
5022+
push_to_substs!(AstConv::ast_region_to_region(self,
5023+
lt, Some(param)).into());
5024+
continue 'args;
5025+
}
5026+
GenericArg::Type(_) => {
5027+
// We're inferring a lifetime.
5028+
push_to_substs!(
5029+
self.re_infer(span, Some(param)).unwrap().into());
50095030
}
5010-
_ => {}
50115031
}
50125032
GenericParamDefKind::Type { .. } => match arg {
5013-
GenericArg::Type(ty) => return self.to_ty(ty).into(),
5014-
_ => {}
5033+
GenericArg::Type(ty) => {
5034+
push_to_substs!(self.to_ty(ty).into());
5035+
continue 'args;
5036+
}
5037+
GenericArg::Lifetime(_) => {
5038+
self.tcx.sess.delay_span_bug(span,
5039+
"found a GenericArg::Lifetime where a \
5040+
GenericArg::Type was expected");
5041+
}
50155042
}
50165043
}
50175044
}
5045+
// If we get to this point, we have a GenericArg that is not matched
5046+
// by a GenericParamDef: i.e. the user supplied too many generic args.
5047+
self.tcx.sess.delay_span_bug(span,
5048+
"GenericArg did not have matching GenericParamDef");
50185049
}
5019-
5020-
segments[index].infer_types
50215050
}
5022-
} else {
5023-
true
5024-
};
5051+
}
5052+
}
50255053

5054+
while let Some(param) = params.next() {
50265055
match param.kind {
50275056
GenericParamDefKind::Lifetime => {
5028-
self.re_infer(span, Some(param)).unwrap().into()
5057+
push_to_substs!(self.re_infer(span, Some(param)).unwrap().into());
50295058
}
50305059
GenericParamDefKind::Type { has_default, .. } => {
50315060
if !infer_types && has_default {
50325061
// No type parameter provided, but a default exists.
50335062
let default = self.tcx.type_of(param.def_id);
5034-
self.normalize_ty(
5063+
push_to_substs!(self.normalize_ty(
50355064
span,
5036-
default.subst_spanned(self.tcx, substs, Some(span))
5037-
).into()
5065+
default.subst_spanned(self.tcx, &substs, Some(span))
5066+
).into());
50385067
} else {
50395068
// No type parameters were provided, we can infer all.
50405069
// This can also be reached in some error cases:
50415070
// We prefer to use inference variables instead of
50425071
// TyError to let type inference recover somewhat.
5043-
self.var_for_def(span, param)
5072+
push_to_substs!(self.var_for_def(span, param));
50445073
}
50455074
}
50465075
}
5047-
});
5076+
}
50485077
}
50495078
let substs = self.tcx.intern_substs(&substs);
50505079

0 commit comments

Comments
 (0)