1
Fork 0

auto merge of #17130 : jakub-/rust/issue-17033, r=pcwalton

Fixes #17033.
Fixes #15965.

cc @nikomatsakis
This commit is contained in:
bors 2014-09-14 05:46:05 +00:00
commit 0f99abae9c
5 changed files with 69 additions and 6 deletions

View file

@ -348,6 +348,7 @@ struct Candidate {
pub enum RcvrMatchCondition { pub enum RcvrMatchCondition {
RcvrMatchesIfObject(ast::DefId), RcvrMatchesIfObject(ast::DefId),
RcvrMatchesIfSubtype(ty::t), RcvrMatchesIfSubtype(ty::t),
RcvrMatchesIfEqtype(ty::t)
} }
impl<'a, 'tcx> LookupContext<'a, 'tcx> { impl<'a, 'tcx> LookupContext<'a, 'tcx> {
@ -675,6 +676,14 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
} }
_ => {} _ => {}
} }
let condition = match m.explicit_self {
ByReferenceExplicitSelfCategory(_, mt) if mt == MutMutable =>
RcvrMatchesIfEqtype(self_ty),
_ =>
RcvrMatchesIfSubtype(self_ty)
};
debug!("found match: trait_ref={} substs={} m={}", debug!("found match: trait_ref={} substs={} m={}",
trait_ref.repr(this.tcx()), trait_ref.repr(this.tcx()),
trait_ref.substs.repr(this.tcx()), trait_ref.substs.repr(this.tcx()),
@ -688,7 +697,7 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
assert_eq!(m.generics.regions.get_slice(subst::SelfSpace).len(), assert_eq!(m.generics.regions.get_slice(subst::SelfSpace).len(),
trait_ref.substs.regions().get_slice(subst::SelfSpace).len()); trait_ref.substs.regions().get_slice(subst::SelfSpace).len());
Some(Candidate { Some(Candidate {
rcvr_match_condition: RcvrMatchesIfSubtype(self_ty), rcvr_match_condition: condition,
rcvr_substs: trait_ref.substs.clone(), rcvr_substs: trait_ref.substs.clone(),
method_ty: m, method_ty: m,
origin: MethodParam(MethodParam { origin: MethodParam(MethodParam {
@ -822,6 +831,13 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
ty: impl_ty ty: impl_ty
} = impl_self_ty(&vcx, span, impl_did); } = impl_self_ty(&vcx, span, impl_did);
let condition = match method.explicit_self {
ByReferenceExplicitSelfCategory(_, mt) if mt == MutMutable =>
RcvrMatchesIfEqtype(impl_ty),
_ =>
RcvrMatchesIfSubtype(impl_ty)
};
let candidates = if is_extension { let candidates = if is_extension {
&mut self.extension_candidates &mut self.extension_candidates
} else { } else {
@ -829,7 +845,7 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
}; };
candidates.push(Candidate { candidates.push(Candidate {
rcvr_match_condition: RcvrMatchesIfSubtype(impl_ty), rcvr_match_condition: condition,
rcvr_substs: impl_substs, rcvr_substs: impl_substs,
origin: MethodStatic(method.def_id), origin: MethodStatic(method.def_id),
method_ty: method, method_ty: method,
@ -1525,7 +1541,7 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
RcvrMatchesIfObject(desired_did) => { RcvrMatchesIfObject(desired_did) => {
self_did == desired_did self_did == desired_did
} }
RcvrMatchesIfSubtype(_) => { RcvrMatchesIfSubtype(_) | RcvrMatchesIfEqtype(_) => {
false false
} }
} }
@ -1541,6 +1557,9 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
RcvrMatchesIfSubtype(of_type) => { RcvrMatchesIfSubtype(of_type) => {
fcx.can_mk_subty(rcvr_ty, of_type).is_ok() fcx.can_mk_subty(rcvr_ty, of_type).is_ok()
} }
RcvrMatchesIfEqtype(of_type) => {
fcx.can_mk_eqty(rcvr_ty, of_type).is_ok()
}
} }
} }
@ -1656,9 +1675,9 @@ impl Repr for RcvrMatchCondition {
RcvrMatchesIfSubtype(t) => { RcvrMatchesIfSubtype(t) => {
format!("RcvrMatchesIfSubtype({})", t.repr(tcx)) format!("RcvrMatchesIfSubtype({})", t.repr(tcx))
} }
RcvrMatchesIfEqtype(t) => {
format!("RcvrMatchesIfEqtype({})", t.repr(tcx))
}
} }
} }
} }

View file

@ -1743,6 +1743,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
infer::can_mk_subty(self.infcx(), sub, sup) infer::can_mk_subty(self.infcx(), sub, sup)
} }
pub fn can_mk_eqty(&self, sub: ty::t, sup: ty::t)
-> Result<(), ty::type_err> {
infer::can_mk_eqty(self.infcx(), sub, sup)
}
pub fn mk_assignty(&self, pub fn mk_assignty(&self,
expr: &ast::Expr, expr: &ast::Expr,
sub: ty::t, sub: ty::t,

View file

@ -360,6 +360,17 @@ pub fn can_mk_subty(cx: &InferCtxt, a: ty::t, b: ty::t) -> ures {
}).to_ures() }).to_ures()
} }
pub fn can_mk_eqty(cx: &InferCtxt, a: ty::t, b: ty::t) -> ures {
debug!("can_mk_subty({} <: {})", a.repr(cx.tcx), b.repr(cx.tcx));
cx.probe(|| {
let trace = TypeTrace {
origin: Misc(codemap::DUMMY_SP),
values: Types(expected_found(true, a, b))
};
cx.equate(true, trace).tys(a, b)
}).to_ures()
}
pub fn mk_subr(cx: &InferCtxt, pub fn mk_subr(cx: &InferCtxt,
origin: SubregionOrigin, origin: SubregionOrigin,
a: ty::Region, a: ty::Region,

View file

@ -0,0 +1,13 @@
// 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.
fn main() {
return { return () } (); //~ ERROR expected function, found `!`
}

View file

@ -0,0 +1,15 @@
// 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.
fn f<'r>(p: &'r mut fn(p: &mut ())) {
p(()) //~ ERROR expected function, found `&'r mut fn(&mut ())`
}
fn main() {}