Skip to content

Commit 1788203

Browse files
committed
---
yaml --- r: 185851 b: refs/heads/auto c: 8501c9d h: refs/heads/master i: 185849: 126fd55 185847: e6efa13 v: v3
1 parent 8a1b8ae commit 1788203

File tree

2 files changed

+33
-8
lines changed

2 files changed

+33
-8
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503
1010
refs/tags/release-0.3.1: 495bae036dfe5ec6ceafd3312b4dca48741e845b
1111
refs/tags/release-0.4: e828ea2080499553b97dfe33b3f4d472b4562ad7
1212
refs/tags/release-0.5: 7e3bcfbf21278251ee936ad53e92e9b719702d73
13-
refs/heads/auto: f0efa2d84347ed0081476f04f42efe4be85ae4d6
13+
refs/heads/auto: 8501c9dee53b78f5027ca215cd8b6711184fe9c3
1414
refs/heads/servo: af82457af293e2a842ba6b7759b70288da276167
1515
refs/tags/release-0.6: b4ebcfa1812664df5e142f0134a5faea3918544c
1616
refs/tags/0.1: b19db808c2793fe2976759b85a355c3ad8c8b336

branches/auto/src/librustc_typeck/check/mod.rs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4748,9 +4748,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
47484748

47494749
assert!(segments.len() >= 1);
47504750

4751-
// In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory.
4752-
let mut require_type_space = opt_self_ty.is_some();
4753-
4751+
let mut ufcs_method = None;
47544752
let mut segment_spaces: Vec<_>;
47554753
match def {
47564754
// Case 1 and 1b. Reference to a *type* or *enum variant*.
@@ -4777,8 +4775,8 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
47774775
}
47784776

47794777
// Case 3. Reference to a method.
4780-
def::DefMethod(_, providence) => {
4781-
match providence {
4778+
def::DefMethod(_, provenance) => {
4779+
match provenance {
47824780
def::FromTrait(trait_did) => {
47834781
callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
47844782
}
@@ -4791,9 +4789,9 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
47914789
segment_spaces.push(Some(subst::FnSpace));
47924790
} else {
47934791
// `<T>::method` will end up here, and so can `T::method`.
4794-
assert!(opt_self_ty.is_some());
4795-
require_type_space = false;
4792+
let self_ty = opt_self_ty.expect("UFCS sugared method missing Self");
47964793
segment_spaces = vec![Some(subst::FnSpace)];
4794+
ufcs_method = Some((provenance, self_ty));
47974795
}
47984796
}
47994797

@@ -4812,6 +4810,11 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
48124810
}
48134811
assert_eq!(segment_spaces.len(), segments.len());
48144812

4813+
// In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
4814+
// `opt_self_ty` can also be Some for `Foo::method`, where Foo's
4815+
// type parameters are not mandatory.
4816+
let require_type_space = opt_self_ty.is_some() && ufcs_method.is_none();
4817+
48154818
debug!("segment_spaces={:?}", segment_spaces);
48164819

48174820
// Next, examine the definition, and determine how many type
@@ -4879,6 +4882,28 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
48794882
// the referenced item.
48804883
let ty_substituted = fcx.instantiate_type_scheme(span, &substs, &type_scheme.ty);
48814884

4885+
4886+
if let Some((def::FromImpl(impl_def_id), self_ty)) = ufcs_method {
4887+
// In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4888+
// is inherent, there is no `Self` parameter, instead, the impl needs
4889+
// type parameters, which we can infer by unifying the provided `Self`
4890+
// with the substituted impl type.
4891+
let impl_scheme = ty::lookup_item_type(fcx.tcx(), impl_def_id);
4892+
assert_eq!(substs.types.len(subst::TypeSpace),
4893+
impl_scheme.generics.types.len(subst::TypeSpace));
4894+
assert_eq!(substs.regions().len(subst::TypeSpace),
4895+
impl_scheme.generics.regions.len(subst::TypeSpace));
4896+
4897+
let impl_ty = fcx.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
4898+
if fcx.mk_subty(false, infer::Misc(span), self_ty, impl_ty).is_err() {
4899+
fcx.tcx().sess.span_bug(span,
4900+
&format!(
4901+
"instantiate_path: (UFCS) {} was a subtype of {} but now is not?",
4902+
self_ty.repr(fcx.tcx()),
4903+
impl_ty.repr(fcx.tcx())));
4904+
}
4905+
}
4906+
48824907
fcx.write_ty(node_id, ty_substituted);
48834908
fcx.write_substs(node_id, ty::ItemSubsts { substs: substs });
48844909
return;

0 commit comments

Comments
 (0)