Skip to content

Commit 8681bc6

Browse files
jroeschJared Roesch
authored andcommitted
---
yaml --- r: 235829 b: refs/heads/stable c: bbcb13d h: refs/heads/master i: 235827: a860abe v: v3
1 parent 4440006 commit 8681bc6

File tree

17 files changed

+371
-95
lines changed

17 files changed

+371
-95
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ refs/heads/tmp: afae2ff723393b3ab4ccffef6ac7c6d1809e2da0
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f
3030
refs/tags/homu-tmp: f859507de8c410b648d934d8f5ec1c52daac971d
3131
refs/tags/1.0.0-beta: 8cbb92b53468ee2b0c2d3eeb8567005953d40828
32-
refs/heads/stable: 9a196aa173c7d08dc865c1814647b2c9f4d9f68a
32+
refs/heads/stable: bbcb13da88f7a4b25506ec85f2f170e6f78d5a58
3333
refs/tags/1.0.0: 55bd4f8ff2b323f317ae89e254ce87162d52a375
3434
refs/tags/1.1.0: bc3c16f09287e5545c1d3f76b7abd54f2eca868b
3535
refs/tags/1.2.0: f557861f822c34f07270347b94b5280de20a597e

branches/stable/src/librustc/middle/infer/mod.rs

Lines changed: 72 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ pub struct InferCtxt<'a, 'tcx: 'a> {
9595
normalize: bool,
9696

9797
err_count_on_creation: usize,
98+
99+
// Default Type Parameter fallbacks
100+
pub defaults: RefCell<FnvHashMap<Ty<'tcx>, Ty<'tcx>>>,
98101
}
99102

100103
/// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
@@ -350,7 +353,8 @@ pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
350353
parameter_environment: param_env.unwrap_or(tcx.empty_parameter_environment()),
351354
fulfillment_cx: RefCell::new(traits::FulfillmentContext::new(errors_will_be_reported)),
352355
normalize: false,
353-
err_count_on_creation: tcx.sess.err_count()
356+
err_count_on_creation: tcx.sess.err_count(),
357+
defaults: RefCell::new(FnvHashMap()),
354358
}
355359
}
356360

@@ -653,6 +657,30 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
653657
}
654658
}
655659

660+
pub fn unsolved_variables(&self) -> Vec<ty::Ty<'tcx>> {
661+
let mut variables = Vec::new();
662+
663+
let unbound_ty_vars = self.type_variables
664+
.borrow()
665+
.unsolved_variables()
666+
.into_iter().map(|t| self.tcx.mk_var(t));
667+
668+
let unbound_int_vars = self.int_unification_table
669+
.borrow_mut()
670+
.unsolved_variables()
671+
.into_iter().map(|v| self.tcx.mk_int_var(v));
672+
673+
let unbound_float_vars = self.float_unification_table
674+
.borrow_mut()
675+
.unsolved_variables()
676+
.into_iter().map(|v| self.tcx.mk_float_var(v));
677+
678+
variables.extend(unbound_ty_vars);
679+
variables.extend(unbound_int_vars);
680+
variables.extend(unbound_float_vars);
681+
return variables;
682+
}
683+
656684
fn combine_fields(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>)
657685
-> CombineFields<'a, 'tcx> {
658686
CombineFields {infcx: self,
@@ -996,16 +1024,36 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
9961024
.collect()
9971025
}
9981026

1027+
pub fn type_vars_for_defs(&self,
1028+
defs: &[ty::TypeParameterDef<'tcx>])
1029+
-> Vec<ty::Ty<'tcx>> {
1030+
let mut vars = Vec::with_capacity(defs.len());
1031+
1032+
for def in defs.iter() {
1033+
let ty_var = self.next_ty_var();
1034+
match def.default {
1035+
None => {},
1036+
Some(default) => { self.defaults.borrow_mut().insert(ty_var, default); }
1037+
}
1038+
vars.push(ty_var)
1039+
}
1040+
1041+
vars
1042+
}
1043+
9991044
/// Given a set of generics defined on a type or impl, returns a substitution mapping each
10001045
/// type/region parameter to a fresh inference variable.
10011046
pub fn fresh_substs_for_generics(&self,
10021047
span: Span,
10031048
generics: &ty::Generics<'tcx>)
10041049
-> subst::Substs<'tcx>
10051050
{
1006-
let type_params =
1007-
generics.types.map(
1008-
|_| self.next_ty_var());
1051+
let mut type_params = subst::VecPerParamSpace::empty();
1052+
1053+
for space in subst::ParamSpace::all().iter() {
1054+
type_params.replace(*space, self.type_vars_for_defs(generics.types.get_slice(*space)))
1055+
}
1056+
10091057
let region_params =
10101058
generics.regions.map(
10111059
|d| self.next_region_var(EarlyBoundRegion(span, d.name)));
@@ -1027,8 +1075,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
10271075
assert!(generics.regions.len(subst::SelfSpace) == 0);
10281076
assert!(generics.regions.len(subst::FnSpace) == 0);
10291077

1030-
let type_parameter_count = generics.types.len(subst::TypeSpace);
1031-
let type_parameters = self.next_ty_vars(type_parameter_count);
1078+
let type_parameter_defs = generics.types.get_slice(subst::TypeSpace);
1079+
let type_parameters = self.type_vars_for_defs(type_parameter_defs);
10321080

10331081
let region_param_defs = generics.regions.get_slice(subst::TypeSpace);
10341082
let regions = self.region_vars_for_defs(span, region_param_defs);
@@ -1268,6 +1316,24 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
12681316
self.report_and_explain_type_error(trace, err);
12691317
}
12701318

1319+
pub fn report_conflicting_default_types(&self,
1320+
span: Span,
1321+
expected: Ty<'tcx>,
1322+
actual: Ty<'tcx>) {
1323+
let trace = TypeTrace {
1324+
origin: Misc(span),
1325+
values: Types(ty::expected_found {
1326+
expected: expected,
1327+
found: actual
1328+
})
1329+
};
1330+
1331+
self.report_and_explain_type_error(trace, &ty::type_err::terr_ty_param_default_mismatch(ty::expected_found {
1332+
expected: expected,
1333+
found: actual
1334+
}));
1335+
}
1336+
12711337
pub fn replace_late_bound_regions_with_fresh_var<T>(
12721338
&self,
12731339
span: Span,

branches/stable/src/librustc/middle/infer/type_variable.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,15 @@ impl<'tcx> TypeVariableTable<'tcx> {
195195

196196
escaping_types
197197
}
198+
199+
pub fn unsolved_variables(&self) -> Vec<ty::TyVid> {
200+
self.values.iter().enumerate().filter_map(|(i, value)|
201+
match &value.value {
202+
&TypeVariableValue::Known(_) => None,
203+
&TypeVariableValue::Bounded(_) => Some(ty::TyVid { index: i as u32 })
204+
}
205+
).collect()
206+
}
198207
}
199208

200209
impl<'tcx> sv::SnapshotVecDelegate for Delegate<'tcx> {

branches/stable/src/librustc/middle/ty.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2068,6 +2068,7 @@ pub enum TypeError<'tcx> {
20682068
ConvergenceMismatch(ExpectedFound<bool>),
20692069
ProjectionNameMismatched(ExpectedFound<ast::Name>),
20702070
ProjectionBoundsLength(ExpectedFound<usize>),
2071+
terr_ty_param_default_mismatch(expected_found<Ty<'tcx>>)
20712072
}
20722073

20732074
/// Bounds suitable for an existentially quantified type parameter
@@ -5080,6 +5081,11 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
50805081
write!(f, "expected {} associated type bindings, found {}",
50815082
values.expected,
50825083
values.found)
5084+
},
5085+
terr_ty_param_default_mismatch(ref values) => {
5086+
write!(f, "conflicting type parameter defaults {} {}",
5087+
values.expected,
5088+
values.found)
50835089
}
50845090
}
50855091
}
@@ -5437,6 +5443,11 @@ impl<'tcx> ctxt<'tcx> {
54375443
&format!("consider boxing your closure and/or \
54385444
using it as a trait object"));
54395445
}
5446+
},
5447+
terr_ty_param_default_mismatch(expected) => {
5448+
self.sess.span_note(sp,
5449+
&format!("found conflicting defaults {:?} {:?}",
5450+
expected.expected, expected.found))
54405451
}
54415452
_ => {}
54425453
}

branches/stable/src/librustc_data_structures/unify/mod.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,5 +339,11 @@ impl<'tcx,K,V> UnificationTable<K>
339339
pub fn probe(&mut self, a_id: K) -> Option<V> {
340340
self.get(a_id).value.clone()
341341
}
342-
}
343342

343+
pub fn unsolved_variables(&mut self) -> Vec<K> {
344+
self.values
345+
.iter()
346+
.filter_map(|vv| if vv.value.is_some() { None } else { Some(vv.key()) })
347+
.collect()
348+
}
349+
}

branches/stable/src/librustc_typeck/astconv.rs

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ use middle::traits;
6060
use middle::ty::{self, RegionEscape, Ty, ToPredicate, HasTypeFlags};
6161
use middle::ty_fold;
6262
use require_c_abi_if_variadic;
63-
use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope,
63+
use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope, ExplicitRscope,
6464
ObjectLifetimeDefaultRscope, ShiftedRscope, BindingRscope,
6565
ElisionFailureInfo, ElidedLifetime};
6666
use util::common::{ErrorReported, FN_OUTPUT_NAME};
@@ -1208,33 +1208,40 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
12081208
(_, def::DefSelfTy(Some(trait_did), Some((impl_id, _)))) => {
12091209
// `Self` in an impl of a trait - we have a concrete self type and a
12101210
// trait reference.
1211-
let trait_ref = tcx.impl_trait_ref(ast_util::local_def(impl_id)).unwrap();
1212-
let trait_ref = if let Some(free_substs) = this.get_free_substs() {
1213-
trait_ref.subst(tcx, free_substs)
1214-
} else {
1215-
trait_ref
1216-
};
1217-
1218-
if this.ensure_super_predicates(span, trait_did).is_err() {
1219-
return (tcx.types.err, ty_path_def);
1220-
}
1211+
match tcx.map.expect_item(impl_id).node {
1212+
ast::ItemImpl(_, _, _, Some(ref trait_ref), _, _) => {
1213+
if this.ensure_super_predicates(span, trait_did).is_err() {
1214+
return (tcx.types.err, ty_path_def);
1215+
}
12211216

1222-
let candidates: Vec<ty::PolyTraitRef> =
1223-
traits::supertraits(tcx, ty::Binder(trait_ref))
1224-
.filter(|r| this.trait_defines_associated_type_named(r.def_id(),
1225-
assoc_name))
1226-
.collect();
1227-
1228-
match one_bound_for_assoc_type(tcx,
1229-
candidates,
1230-
"Self",
1231-
&token::get_name(assoc_name),
1232-
span) {
1233-
Ok(bound) => bound,
1234-
Err(ErrorReported) => return (tcx.types.err, ty_path_def),
1217+
let trait_segment = &trait_ref.path.segments.last().unwrap();
1218+
let trait_ref = ast_path_to_mono_trait_ref(this,
1219+
&ExplicitRscope,
1220+
span,
1221+
PathParamMode::Explicit,
1222+
trait_did,
1223+
Some(ty),
1224+
trait_segment);
1225+
1226+
let candidates: Vec<ty::PolyTraitRef> =
1227+
traits::supertraits(tcx, ty::Binder(trait_ref.clone()))
1228+
.filter(|r| this.trait_defines_associated_type_named(r.def_id(),
1229+
assoc_name))
1230+
.collect();
1231+
1232+
match one_bound_for_assoc_type(tcx,
1233+
candidates,
1234+
"Self",
1235+
&token::get_name(assoc_name),
1236+
span) {
1237+
Ok(bound) => bound,
1238+
Err(ErrorReported) => return (tcx.types.err, ty_path_def),
1239+
}
1240+
}
1241+
_ => unreachable!()
12351242
}
12361243
}
1237-
(&ty::TyParam(_), def::DefSelfTy(Some(trait_did), None)) => {
1244+
(&ty::TyParam(_), def::DefSelfTy(Some(trait_did), None)) => {
12381245
assert_eq!(trait_did.krate, ast::LOCAL_CRATE);
12391246
match find_bound_for_assoc_item(this,
12401247
trait_did.node,

branches/stable/src/librustc_typeck/check/method/confirm.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -309,15 +309,17 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
309309
// If they were not explicitly supplied, just construct fresh
310310
// variables.
311311
let num_supplied_types = supplied_method_types.len();
312-
let num_method_types = pick.item.as_opt_method().unwrap()
313-
.generics.types.len(subst::FnSpace);
312+
let method = pick.item.as_opt_method().unwrap();
313+
let method_types = method.generics.types.get_slice(subst::FnSpace);
314+
let num_method_types = method_types.len();
315+
314316
let method_types = {
315317
if num_supplied_types == 0 {
316-
self.fcx.infcx().next_ty_vars(num_method_types)
318+
self.fcx.infcx().type_vars_for_defs(method_types)
317319
} else if num_method_types == 0 {
318320
span_err!(self.tcx().sess, self.span, E0035,
319321
"does not take type parameters");
320-
self.fcx.infcx().next_ty_vars(num_method_types)
322+
self.fcx.infcx().type_vars_for_defs(method_types)
321323
} else if num_supplied_types != num_method_types {
322324
span_err!(self.tcx().sess, self.span, E0036,
323325
"incorrect number of type parameters given for this method");

branches/stable/src/librustc_typeck/check/method/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,15 +167,16 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
167167

168168
let trait_def = fcx.tcx().lookup_trait_def(trait_def_id);
169169

170-
let expected_number_of_input_types = trait_def.generics.types.len(subst::TypeSpace);
170+
let type_parameter_defs = trait_def.generics.types.get_slice(subst::TypeSpace);
171+
let expected_number_of_input_types = type_parameter_defs.len();
171172
let input_types = match opt_input_types {
172173
Some(input_types) => {
173174
assert_eq!(expected_number_of_input_types, input_types.len());
174175
input_types
175176
}
176177

177178
None => {
178-
fcx.inh.infcx.next_ty_vars(expected_number_of_input_types)
179+
fcx.inh.infcx.type_vars_for_defs(type_parameter_defs)
179180
}
180181
};
181182

branches/stable/src/librustc_typeck/check/method/probe.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,8 +1207,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
12071207
!method.generics.regions.is_empty_in(subst::FnSpace)
12081208
{
12091209
let method_types =
1210-
self.infcx().next_ty_vars(
1211-
method.generics.types.len(subst::FnSpace));
1210+
self.infcx().type_vars_for_defs(
1211+
method.generics.types.get_slice(subst::FnSpace));
12121212

12131213
// In general, during probe we erase regions. See
12141214
// `impl_self_ty()` for an explanation.

0 commit comments

Comments
 (0)