rustc: Avoid free functions taking &TyCtxt and &InferCtxt.
This commit is contained in:
parent
d7ee56e862
commit
f8ea24edc8
@ -25,7 +25,7 @@
|
||||
//! In particular, it might be enough to say (A,B) are bivariant for
|
||||
//! all (A,B).
|
||||
|
||||
use super::combine::{self, CombineFields};
|
||||
use super::combine::CombineFields;
|
||||
use super::type_variable::{BiTo};
|
||||
|
||||
use ty::{self, Ty, TyCtxt};
|
||||
@ -96,7 +96,7 @@ impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Bivariate<'a, 'tcx> {
|
||||
}
|
||||
|
||||
_ => {
|
||||
combine::super_combine_tys(self.fields.infcx, self, a, b)
|
||||
self.fields.infcx.super_combine_tys(self, a, b)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,11 +60,12 @@ pub struct CombineFields<'a, 'tcx: 'a> {
|
||||
pub obligations: PredicateObligations<'tcx>,
|
||||
}
|
||||
|
||||
pub fn super_combine_tys<'a,'tcx:'a,R>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
relation: &mut R,
|
||||
a: Ty<'tcx>,
|
||||
b: Ty<'tcx>)
|
||||
-> RelateResult<'tcx, Ty<'tcx>>
|
||||
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
pub fn super_combine_tys<R>(&self,
|
||||
relation: &mut R,
|
||||
a: Ty<'tcx>,
|
||||
b: Ty<'tcx>)
|
||||
-> RelateResult<'tcx, Ty<'tcx>>
|
||||
where R: TypeRelation<'a,'tcx>
|
||||
{
|
||||
let a_is_expected = relation.a_is_expected();
|
||||
@ -72,38 +73,38 @@ pub fn super_combine_tys<'a,'tcx:'a,R>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
match (&a.sty, &b.sty) {
|
||||
// Relate integral variables to other types
|
||||
(&ty::TyInfer(ty::IntVar(a_id)), &ty::TyInfer(ty::IntVar(b_id))) => {
|
||||
infcx.int_unification_table
|
||||
.borrow_mut()
|
||||
.unify_var_var(a_id, b_id)
|
||||
.map_err(|e| int_unification_error(a_is_expected, e))?;
|
||||
self.int_unification_table
|
||||
.borrow_mut()
|
||||
.unify_var_var(a_id, b_id)
|
||||
.map_err(|e| int_unification_error(a_is_expected, e))?;
|
||||
Ok(a)
|
||||
}
|
||||
(&ty::TyInfer(ty::IntVar(v_id)), &ty::TyInt(v)) => {
|
||||
unify_integral_variable(infcx, a_is_expected, v_id, IntType(v))
|
||||
self.unify_integral_variable(a_is_expected, v_id, IntType(v))
|
||||
}
|
||||
(&ty::TyInt(v), &ty::TyInfer(ty::IntVar(v_id))) => {
|
||||
unify_integral_variable(infcx, !a_is_expected, v_id, IntType(v))
|
||||
self.unify_integral_variable(!a_is_expected, v_id, IntType(v))
|
||||
}
|
||||
(&ty::TyInfer(ty::IntVar(v_id)), &ty::TyUint(v)) => {
|
||||
unify_integral_variable(infcx, a_is_expected, v_id, UintType(v))
|
||||
self.unify_integral_variable(a_is_expected, v_id, UintType(v))
|
||||
}
|
||||
(&ty::TyUint(v), &ty::TyInfer(ty::IntVar(v_id))) => {
|
||||
unify_integral_variable(infcx, !a_is_expected, v_id, UintType(v))
|
||||
self.unify_integral_variable(!a_is_expected, v_id, UintType(v))
|
||||
}
|
||||
|
||||
// Relate floating-point variables to other types
|
||||
(&ty::TyInfer(ty::FloatVar(a_id)), &ty::TyInfer(ty::FloatVar(b_id))) => {
|
||||
infcx.float_unification_table
|
||||
.borrow_mut()
|
||||
.unify_var_var(a_id, b_id)
|
||||
.map_err(|e| float_unification_error(relation.a_is_expected(), e))?;
|
||||
self.float_unification_table
|
||||
.borrow_mut()
|
||||
.unify_var_var(a_id, b_id)
|
||||
.map_err(|e| float_unification_error(relation.a_is_expected(), e))?;
|
||||
Ok(a)
|
||||
}
|
||||
(&ty::TyInfer(ty::FloatVar(v_id)), &ty::TyFloat(v)) => {
|
||||
unify_float_variable(infcx, a_is_expected, v_id, v)
|
||||
self.unify_float_variable(a_is_expected, v_id, v)
|
||||
}
|
||||
(&ty::TyFloat(v), &ty::TyInfer(ty::FloatVar(v_id))) => {
|
||||
unify_float_variable(infcx, !a_is_expected, v_id, v)
|
||||
self.unify_float_variable(!a_is_expected, v_id, v)
|
||||
}
|
||||
|
||||
// All other cases of inference are errors
|
||||
@ -119,33 +120,34 @@ pub fn super_combine_tys<'a,'tcx:'a,R>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
}
|
||||
}
|
||||
|
||||
fn unify_integral_variable<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
|
||||
vid_is_expected: bool,
|
||||
vid: ty::IntVid,
|
||||
val: ty::IntVarValue)
|
||||
-> RelateResult<'tcx, Ty<'tcx>>
|
||||
fn unify_integral_variable(&self,
|
||||
vid_is_expected: bool,
|
||||
vid: ty::IntVid,
|
||||
val: ty::IntVarValue)
|
||||
-> RelateResult<'tcx, Ty<'tcx>>
|
||||
{
|
||||
infcx.int_unification_table
|
||||
.borrow_mut()
|
||||
.unify_var_value(vid, val)
|
||||
.map_err(|e| int_unification_error(vid_is_expected, e))?;
|
||||
self.int_unification_table
|
||||
.borrow_mut()
|
||||
.unify_var_value(vid, val)
|
||||
.map_err(|e| int_unification_error(vid_is_expected, e))?;
|
||||
match val {
|
||||
IntType(v) => Ok(infcx.tcx.mk_mach_int(v)),
|
||||
UintType(v) => Ok(infcx.tcx.mk_mach_uint(v)),
|
||||
IntType(v) => Ok(self.tcx.mk_mach_int(v)),
|
||||
UintType(v) => Ok(self.tcx.mk_mach_uint(v)),
|
||||
}
|
||||
}
|
||||
|
||||
fn unify_float_variable<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
|
||||
vid_is_expected: bool,
|
||||
vid: ty::FloatVid,
|
||||
val: ast::FloatTy)
|
||||
-> RelateResult<'tcx, Ty<'tcx>>
|
||||
fn unify_float_variable(&self,
|
||||
vid_is_expected: bool,
|
||||
vid: ty::FloatVid,
|
||||
val: ast::FloatTy)
|
||||
-> RelateResult<'tcx, Ty<'tcx>>
|
||||
{
|
||||
infcx.float_unification_table
|
||||
.borrow_mut()
|
||||
.unify_var_value(vid, val)
|
||||
.map_err(|e| float_unification_error(vid_is_expected, e))?;
|
||||
Ok(infcx.tcx.mk_mach_float(val))
|
||||
self.float_unification_table
|
||||
.borrow_mut()
|
||||
.unify_var_value(vid, val)
|
||||
.map_err(|e| float_unification_error(vid_is_expected, e))?;
|
||||
Ok(self.tcx.mk_mach_float(val))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> CombineFields<'a, 'tcx> {
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use super::combine::{self, CombineFields};
|
||||
use super::combine::CombineFields;
|
||||
use super::higher_ranked::HigherRankedRelations;
|
||||
use super::{Subtype};
|
||||
use super::type_variable::{EqTo};
|
||||
@ -74,7 +74,7 @@ impl<'a, 'tcx> TypeRelation<'a,'tcx> for Equate<'a, 'tcx> {
|
||||
}
|
||||
|
||||
_ => {
|
||||
combine::super_combine_tys(self.fields.infcx, self, a, b)?;
|
||||
self.fields.infcx.super_combine_tys(self, a, b)?;
|
||||
Ok(a)
|
||||
}
|
||||
}
|
||||
|
@ -31,14 +31,6 @@ pub trait HigherRankedRelations<'a,'tcx> {
|
||||
where T: Relate<'a,'tcx>;
|
||||
}
|
||||
|
||||
trait InferCtxtExt {
|
||||
fn tainted_regions(&self, snapshot: &CombinedSnapshot, r: ty::Region) -> Vec<ty::Region>;
|
||||
|
||||
fn region_vars_confined_to_snapshot(&self,
|
||||
snapshot: &CombinedSnapshot)
|
||||
-> Vec<ty::RegionVid>;
|
||||
}
|
||||
|
||||
impl<'a,'tcx> HigherRankedRelations<'a,'tcx> for CombineFields<'a,'tcx> {
|
||||
fn higher_ranked_sub<T>(&self, a: &Binder<T>, b: &Binder<T>)
|
||||
-> RelateResult<'tcx, Binder<T>>
|
||||
@ -79,23 +71,9 @@ impl<'a,'tcx> HigherRankedRelations<'a,'tcx> for CombineFields<'a,'tcx> {
|
||||
|
||||
// Presuming type comparison succeeds, we need to check
|
||||
// that the skolemized regions do not "leak".
|
||||
match leak_check(self.infcx, &skol_map, snapshot) {
|
||||
Ok(()) => { }
|
||||
Err((skol_br, tainted_region)) => {
|
||||
if self.a_is_expected {
|
||||
debug!("Not as polymorphic!");
|
||||
return Err(TypeError::RegionsInsufficientlyPolymorphic(skol_br,
|
||||
tainted_region));
|
||||
} else {
|
||||
debug!("Overly polymorphic!");
|
||||
return Err(TypeError::RegionsOverlyPolymorphic(skol_br,
|
||||
tainted_region));
|
||||
}
|
||||
}
|
||||
}
|
||||
self.infcx.leak_check(!self.a_is_expected, &skol_map, snapshot)?;
|
||||
|
||||
debug!("higher_ranked_sub: OK result={:?}",
|
||||
result);
|
||||
debug!("higher_ranked_sub: OK result={:?}", result);
|
||||
|
||||
Ok(ty::Binder(result))
|
||||
});
|
||||
@ -371,7 +349,7 @@ fn fold_regions_in<'tcx, T, F>(tcx: &TyCtxt<'tcx>,
|
||||
})
|
||||
}
|
||||
|
||||
impl<'a,'tcx> InferCtxtExt for InferCtxt<'a,'tcx> {
|
||||
impl<'a,'tcx> InferCtxt<'a,'tcx> {
|
||||
fn tainted_regions(&self, snapshot: &CombinedSnapshot, r: ty::Region) -> Vec<ty::Region> {
|
||||
self.region_vars.tainted(&snapshot.region_vars_snapshot, r)
|
||||
}
|
||||
@ -452,12 +430,11 @@ impl<'a,'tcx> InferCtxtExt for InferCtxt<'a,'tcx> {
|
||||
|
||||
region_vars
|
||||
}
|
||||
}
|
||||
|
||||
pub fn skolemize_late_bound_regions<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
|
||||
binder: &ty::Binder<T>,
|
||||
snapshot: &CombinedSnapshot)
|
||||
-> (T, SkolemizationMap)
|
||||
pub fn skolemize_late_bound_regions<T>(&self,
|
||||
binder: &ty::Binder<T>,
|
||||
snapshot: &CombinedSnapshot)
|
||||
-> (T, SkolemizationMap)
|
||||
where T : TypeFoldable<'tcx>
|
||||
{
|
||||
/*!
|
||||
@ -468,8 +445,8 @@ pub fn skolemize_late_bound_regions<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
|
||||
* details.
|
||||
*/
|
||||
|
||||
let (result, map) = infcx.tcx.replace_late_bound_regions(binder, |br| {
|
||||
infcx.region_vars.new_skolemized(br, &snapshot.region_vars_snapshot)
|
||||
let (result, map) = self.tcx.replace_late_bound_regions(binder, |br| {
|
||||
self.region_vars.new_skolemized(br, &snapshot.region_vars_snapshot)
|
||||
});
|
||||
|
||||
debug!("skolemize_bound_regions(binder={:?}, result={:?}, map={:?})",
|
||||
@ -480,10 +457,11 @@ pub fn skolemize_late_bound_regions<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
|
||||
(result, map)
|
||||
}
|
||||
|
||||
pub fn leak_check<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
|
||||
skol_map: &SkolemizationMap,
|
||||
snapshot: &CombinedSnapshot)
|
||||
-> Result<(),(ty::BoundRegion,ty::Region)>
|
||||
pub fn leak_check(&self,
|
||||
overly_polymorphic: bool,
|
||||
skol_map: &SkolemizationMap,
|
||||
snapshot: &CombinedSnapshot)
|
||||
-> RelateResult<'tcx, ()>
|
||||
{
|
||||
/*!
|
||||
* Searches the region constriants created since `snapshot` was started
|
||||
@ -496,9 +474,9 @@ pub fn leak_check<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
|
||||
debug!("leak_check: skol_map={:?}",
|
||||
skol_map);
|
||||
|
||||
let new_vars = infcx.region_vars_confined_to_snapshot(snapshot);
|
||||
let new_vars = self.region_vars_confined_to_snapshot(snapshot);
|
||||
for (&skol_br, &skol) in skol_map {
|
||||
let tainted = infcx.tainted_regions(snapshot, skol);
|
||||
let tainted = self.tainted_regions(snapshot, skol);
|
||||
for &tainted_region in &tainted {
|
||||
// Each skolemized should only be relatable to itself
|
||||
// or new variables:
|
||||
@ -516,8 +494,15 @@ pub fn leak_check<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
|
||||
skol_br,
|
||||
tainted_region);
|
||||
|
||||
// A is not as polymorphic as B:
|
||||
return Err((skol_br, tainted_region));
|
||||
if overly_polymorphic {
|
||||
debug!("Overly polymorphic!");
|
||||
return Err(TypeError::RegionsOverlyPolymorphic(skol_br,
|
||||
tainted_region));
|
||||
} else {
|
||||
debug!("Not as polymorphic!");
|
||||
return Err(TypeError::RegionsInsufficientlyPolymorphic(skol_br,
|
||||
tainted_region));
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@ -551,14 +536,13 @@ pub fn leak_check<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
|
||||
/// replace `'0` with a late-bound region `'a`. The depth is matched
|
||||
/// to the depth of the predicate, in this case 1, so that the final
|
||||
/// predicate is `for<'a> &'a int : Clone`.
|
||||
pub fn plug_leaks<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
|
||||
skol_map: SkolemizationMap,
|
||||
snapshot: &CombinedSnapshot,
|
||||
value: &T)
|
||||
-> T
|
||||
pub fn plug_leaks<T>(&self,
|
||||
skol_map: SkolemizationMap,
|
||||
snapshot: &CombinedSnapshot,
|
||||
value: &T) -> T
|
||||
where T : TypeFoldable<'tcx>
|
||||
{
|
||||
debug_assert!(leak_check(infcx, &skol_map, snapshot).is_ok());
|
||||
debug_assert!(self.leak_check(false, &skol_map, snapshot).is_ok());
|
||||
|
||||
debug!("plug_leaks(skol_map={:?}, value={:?})",
|
||||
skol_map,
|
||||
@ -572,7 +556,7 @@ pub fn plug_leaks<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
|
||||
skol_map
|
||||
.into_iter()
|
||||
.flat_map(|(skol_br, skol)| {
|
||||
infcx.tainted_regions(snapshot, skol)
|
||||
self.tainted_regions(snapshot, skol)
|
||||
.into_iter()
|
||||
.map(move |tainted_region| (tainted_region, skol_br))
|
||||
})
|
||||
@ -583,14 +567,14 @@ pub fn plug_leaks<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
|
||||
|
||||
// Remove any instantiated type variables from `value`; those can hide
|
||||
// references to regions from the `fold_regions` code below.
|
||||
let value = infcx.resolve_type_vars_if_possible(value);
|
||||
let value = self.resolve_type_vars_if_possible(value);
|
||||
|
||||
// Map any skolemization byproducts back to a late-bound
|
||||
// region. Put that late-bound region at whatever the outermost
|
||||
// binder is that we encountered in `value`. The caller is
|
||||
// responsible for ensuring that (a) `value` contains at least one
|
||||
// binder and (b) that binder is the one we want to use.
|
||||
let result = infcx.tcx.fold_regions(&value, &mut false, |r, current_depth| {
|
||||
let result = self.tcx.fold_regions(&value, &mut false, |r, current_depth| {
|
||||
match inv_skol_map.get(&r) {
|
||||
None => r,
|
||||
Some(br) => {
|
||||
@ -612,3 +596,4 @@ pub fn plug_leaks<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,6 @@
|
||||
//! over a `LatticeValue`, which is a value defined with respect to
|
||||
//! a lattice.
|
||||
|
||||
use super::combine;
|
||||
use super::InferCtxt;
|
||||
|
||||
use ty::TyVar;
|
||||
@ -78,7 +77,7 @@ pub fn super_lattice_tys<'a,'tcx,L:LatticeDir<'a,'tcx>>(this: &mut L,
|
||||
}
|
||||
|
||||
_ => {
|
||||
combine::super_combine_tys(this.infcx(), this, a, b)
|
||||
infcx.super_combine_tys(this, a, b)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -366,19 +366,21 @@ pub enum FixupError {
|
||||
UnresolvedTy(TyVid)
|
||||
}
|
||||
|
||||
pub fn fixup_err_to_string(f: FixupError) -> String {
|
||||
use self::FixupError::*;
|
||||
impl fmt::Display for FixupError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
use self::FixupError::*;
|
||||
|
||||
match f {
|
||||
UnresolvedIntTy(_) => {
|
||||
"cannot determine the type of this integer; add a suffix to \
|
||||
specify the type explicitly".to_string()
|
||||
}
|
||||
UnresolvedFloatTy(_) => {
|
||||
"cannot determine the type of this number; add a suffix to specify \
|
||||
the type explicitly".to_string()
|
||||
}
|
||||
UnresolvedTy(_) => "unconstrained type".to_string(),
|
||||
match *self {
|
||||
UnresolvedIntTy(_) => {
|
||||
write!(f, "cannot determine the type of this integer; \
|
||||
add a suffix to specify the type explicitly")
|
||||
}
|
||||
UnresolvedFloatTy(_) => {
|
||||
write!(f, "cannot determine the type of this number; \
|
||||
add a suffix to specify the type explicitly")
|
||||
}
|
||||
UnresolvedTy(_) => write!(f, "unconstrained type")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -414,103 +416,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
|
||||
a_is_expected: bool,
|
||||
origin: TypeOrigin,
|
||||
a: Ty<'tcx>,
|
||||
b: Ty<'tcx>)
|
||||
-> InferResult<'tcx, ()>
|
||||
{
|
||||
debug!("mk_subty({:?} <: {:?})", a, b);
|
||||
cx.sub_types(a_is_expected, origin, a, b)
|
||||
}
|
||||
|
||||
pub fn can_mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>, a: Ty<'tcx>, b: Ty<'tcx>)
|
||||
-> UnitResult<'tcx>
|
||||
{
|
||||
debug!("can_mk_subty({:?} <: {:?})", a, b);
|
||||
cx.probe(|_| {
|
||||
let trace = TypeTrace {
|
||||
origin: TypeOrigin::Misc(codemap::DUMMY_SP),
|
||||
values: Types(expected_found(true, a, b))
|
||||
};
|
||||
cx.sub(true, trace, &a, &b).map(|_| ())
|
||||
})
|
||||
}
|
||||
|
||||
pub fn can_mk_eqty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>, a: Ty<'tcx>, b: Ty<'tcx>)
|
||||
-> UnitResult<'tcx>
|
||||
{
|
||||
cx.can_equate(&a, &b)
|
||||
}
|
||||
|
||||
pub fn mk_subr<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
|
||||
origin: SubregionOrigin<'tcx>,
|
||||
a: ty::Region,
|
||||
b: ty::Region) {
|
||||
debug!("mk_subr({:?} <: {:?})", a, b);
|
||||
let snapshot = cx.region_vars.start_snapshot();
|
||||
cx.region_vars.make_subregion(origin, a, b);
|
||||
cx.region_vars.commit(snapshot);
|
||||
}
|
||||
|
||||
pub fn mk_eqty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
|
||||
a_is_expected: bool,
|
||||
origin: TypeOrigin,
|
||||
a: Ty<'tcx>,
|
||||
b: Ty<'tcx>)
|
||||
-> InferResult<'tcx, ()>
|
||||
{
|
||||
debug!("mk_eqty({:?} <: {:?})", a, b);
|
||||
cx.eq_types(a_is_expected, origin, a, b)
|
||||
}
|
||||
|
||||
pub fn mk_eq_trait_refs<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
|
||||
a_is_expected: bool,
|
||||
origin: TypeOrigin,
|
||||
a: ty::TraitRef<'tcx>,
|
||||
b: ty::TraitRef<'tcx>)
|
||||
-> InferResult<'tcx, ()>
|
||||
{
|
||||
debug!("mk_eq_trait_refs({:?} = {:?})", a, b);
|
||||
cx.eq_trait_refs(a_is_expected, origin, a, b)
|
||||
}
|
||||
|
||||
pub fn mk_sub_poly_trait_refs<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
|
||||
a_is_expected: bool,
|
||||
origin: TypeOrigin,
|
||||
a: ty::PolyTraitRef<'tcx>,
|
||||
b: ty::PolyTraitRef<'tcx>)
|
||||
-> InferResult<'tcx, ()>
|
||||
{
|
||||
debug!("mk_sub_poly_trait_refs({:?} <: {:?})", a, b);
|
||||
cx.sub_poly_trait_refs(a_is_expected, origin, a, b)
|
||||
}
|
||||
|
||||
pub fn mk_eq_impl_headers<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
|
||||
a_is_expected: bool,
|
||||
origin: TypeOrigin,
|
||||
a: &ty::ImplHeader<'tcx>,
|
||||
b: &ty::ImplHeader<'tcx>)
|
||||
-> InferResult<'tcx, ()>
|
||||
{
|
||||
debug!("mk_eq_impl_header({:?} = {:?})", a, b);
|
||||
match (a.trait_ref, b.trait_ref) {
|
||||
(Some(a_ref), Some(b_ref)) => mk_eq_trait_refs(cx, a_is_expected, origin, a_ref, b_ref),
|
||||
(None, None) => mk_eqty(cx, a_is_expected, origin, a.self_ty, b.self_ty),
|
||||
_ => bug!("mk_eq_impl_headers given mismatched impl kinds"),
|
||||
impl<T> ExpectedFound<T> {
|
||||
fn new(a_is_expected: bool, a: T, b: T) -> Self {
|
||||
if a_is_expected {
|
||||
ExpectedFound {expected: a, found: b}
|
||||
} else {
|
||||
ExpectedFound {expected: b, found: a}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn expected_found<T>(a_is_expected: bool,
|
||||
a: T,
|
||||
b: T)
|
||||
-> ExpectedFound<T>
|
||||
{
|
||||
if a_is_expected {
|
||||
ExpectedFound {expected: a, found: b}
|
||||
} else {
|
||||
ExpectedFound {expected: b, found: a}
|
||||
impl<'tcx, T> InferOk<'tcx, T> {
|
||||
fn unit(self) -> InferOk<'tcx, ()> {
|
||||
InferOk { value: (), obligations: self.obligations }
|
||||
}
|
||||
}
|
||||
|
||||
@ -551,18 +469,19 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
fulfill_cx.register_predicate_obligation(&infcx, obligation);
|
||||
}
|
||||
|
||||
drain_fulfillment_cx_or_panic(DUMMY_SP, &infcx, &mut fulfill_cx, &result)
|
||||
infcx.drain_fulfillment_cx_or_panic(DUMMY_SP, &mut fulfill_cx, &result)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn drain_fulfillment_cx_or_panic<'a,'tcx,T>(span: Span,
|
||||
infcx: &InferCtxt<'a,'tcx>,
|
||||
fulfill_cx: &mut traits::FulfillmentContext<'tcx>,
|
||||
result: &T)
|
||||
-> T
|
||||
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
pub fn drain_fulfillment_cx_or_panic<T>(&self,
|
||||
span: Span,
|
||||
fulfill_cx: &mut traits::FulfillmentContext<'tcx>,
|
||||
result: &T)
|
||||
-> T
|
||||
where T : TypeFoldable<'tcx>
|
||||
{
|
||||
match drain_fulfillment_cx(infcx, fulfill_cx, result) {
|
||||
match self.drain_fulfillment_cx(fulfill_cx, result) {
|
||||
Ok(v) => v,
|
||||
Err(errors) => {
|
||||
span_bug!(
|
||||
@ -580,10 +499,10 @@ pub fn drain_fulfillment_cx_or_panic<'a,'tcx,T>(span: Span,
|
||||
/// inference variables that appear in `result` to be unified, and
|
||||
/// hence we need to process those obligations to get the complete
|
||||
/// picture of the type.
|
||||
pub fn drain_fulfillment_cx<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
|
||||
fulfill_cx: &mut traits::FulfillmentContext<'tcx>,
|
||||
result: &T)
|
||||
-> Result<T,Vec<traits::FulfillmentError<'tcx>>>
|
||||
pub fn drain_fulfillment_cx<T>(&self,
|
||||
fulfill_cx: &mut traits::FulfillmentContext<'tcx>,
|
||||
result: &T)
|
||||
-> Result<T,Vec<traits::FulfillmentError<'tcx>>>
|
||||
where T : TypeFoldable<'tcx>
|
||||
{
|
||||
debug!("drain_fulfillment_cx(result={:?})",
|
||||
@ -592,24 +511,12 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
|
||||
// In principle, we only need to do this so long as `result`
|
||||
// contains unbound type parameters. It could be a slight
|
||||
// optimization to stop iterating early.
|
||||
match fulfill_cx.select_all_or_error(infcx) {
|
||||
Ok(()) => { }
|
||||
Err(errors) => {
|
||||
return Err(errors);
|
||||
}
|
||||
}
|
||||
fulfill_cx.select_all_or_error(self)?;
|
||||
|
||||
let result = infcx.resolve_type_vars_if_possible(result);
|
||||
Ok(infcx.tcx.erase_regions(&result))
|
||||
let result = self.resolve_type_vars_if_possible(result);
|
||||
Ok(self.tcx.erase_regions(&result))
|
||||
}
|
||||
|
||||
impl<'tcx, T> InferOk<'tcx, T> {
|
||||
fn unit(self) -> InferOk<'tcx, ()> {
|
||||
InferOk { value: (), obligations: self.obligations }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
pub fn projection_mode(&self) -> ProjectionMode {
|
||||
self.projection_mode
|
||||
}
|
||||
@ -896,6 +803,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn can_sub_types(&self,
|
||||
a: Ty<'tcx>,
|
||||
b: Ty<'tcx>)
|
||||
-> UnitResult<'tcx>
|
||||
{
|
||||
self.probe(|_| {
|
||||
let origin = TypeOrigin::Misc(codemap::DUMMY_SP);
|
||||
let trace = TypeTrace::types(origin, true, a, b);
|
||||
self.sub(true, trace, &a, &b).map(|_| ())
|
||||
})
|
||||
}
|
||||
|
||||
pub fn eq_types(&self,
|
||||
a_is_expected: bool,
|
||||
origin: TypeOrigin,
|
||||
@ -916,18 +835,31 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
b: ty::TraitRef<'tcx>)
|
||||
-> InferResult<'tcx, ()>
|
||||
{
|
||||
debug!("eq_trait_refs({:?} <: {:?})",
|
||||
a,
|
||||
b);
|
||||
debug!("eq_trait_refs({:?} = {:?})", a, b);
|
||||
self.commit_if_ok(|_| {
|
||||
let trace = TypeTrace {
|
||||
origin: origin,
|
||||
values: TraitRefs(expected_found(a_is_expected, a.clone(), b.clone()))
|
||||
values: TraitRefs(ExpectedFound::new(a_is_expected, a, b))
|
||||
};
|
||||
self.equate(a_is_expected, trace, &a, &b).map(|ok| ok.unit())
|
||||
})
|
||||
}
|
||||
|
||||
pub fn eq_impl_headers(&self,
|
||||
a_is_expected: bool,
|
||||
origin: TypeOrigin,
|
||||
a: &ty::ImplHeader<'tcx>,
|
||||
b: &ty::ImplHeader<'tcx>)
|
||||
-> InferResult<'tcx, ()>
|
||||
{
|
||||
debug!("eq_impl_header({:?} = {:?})", a, b);
|
||||
match (a.trait_ref, b.trait_ref) {
|
||||
(Some(a_ref), Some(b_ref)) => self.eq_trait_refs(a_is_expected, origin, a_ref, b_ref),
|
||||
(None, None) => self.eq_types(a_is_expected, origin, a.self_ty, b.self_ty),
|
||||
_ => bug!("mk_eq_impl_headers given mismatched impl kinds"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sub_poly_trait_refs(&self,
|
||||
a_is_expected: bool,
|
||||
origin: TypeOrigin,
|
||||
@ -935,52 +867,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
b: ty::PolyTraitRef<'tcx>)
|
||||
-> InferResult<'tcx, ()>
|
||||
{
|
||||
debug!("sub_poly_trait_refs({:?} <: {:?})",
|
||||
a,
|
||||
b);
|
||||
debug!("sub_poly_trait_refs({:?} <: {:?})", a, b);
|
||||
self.commit_if_ok(|_| {
|
||||
let trace = TypeTrace {
|
||||
origin: origin,
|
||||
values: PolyTraitRefs(expected_found(a_is_expected, a.clone(), b.clone()))
|
||||
values: PolyTraitRefs(ExpectedFound::new(a_is_expected, a, b))
|
||||
};
|
||||
self.sub(a_is_expected, trace, &a, &b).map(|ok| ok.unit())
|
||||
})
|
||||
}
|
||||
|
||||
pub fn skolemize_late_bound_regions<T>(&self,
|
||||
value: &ty::Binder<T>,
|
||||
snapshot: &CombinedSnapshot)
|
||||
-> (T, SkolemizationMap)
|
||||
where T : TypeFoldable<'tcx>
|
||||
{
|
||||
/*! See `higher_ranked::skolemize_late_bound_regions` */
|
||||
|
||||
higher_ranked::skolemize_late_bound_regions(self, value, snapshot)
|
||||
}
|
||||
|
||||
pub fn leak_check(&self,
|
||||
skol_map: &SkolemizationMap,
|
||||
snapshot: &CombinedSnapshot)
|
||||
-> UnitResult<'tcx>
|
||||
{
|
||||
/*! See `higher_ranked::leak_check` */
|
||||
|
||||
match higher_ranked::leak_check(self, skol_map, snapshot) {
|
||||
Ok(()) => Ok(()),
|
||||
Err((br, r)) => Err(TypeError::RegionsInsufficientlyPolymorphic(br, r))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn plug_leaks<T>(&self,
|
||||
skol_map: SkolemizationMap,
|
||||
snapshot: &CombinedSnapshot,
|
||||
value: &T)
|
||||
-> T
|
||||
where T : TypeFoldable<'tcx>
|
||||
{
|
||||
/*! See `higher_ranked::plug_leaks` */
|
||||
|
||||
higher_ranked::plug_leaks(self, skol_map, snapshot, value)
|
||||
pub fn sub_regions(&self,
|
||||
origin: SubregionOrigin<'tcx>,
|
||||
a: ty::Region,
|
||||
b: ty::Region) {
|
||||
debug!("sub_regions({:?} <: {:?})", a, b);
|
||||
self.region_vars.make_subregion(origin, a, b);
|
||||
}
|
||||
|
||||
pub fn equality_predicate(&self,
|
||||
@ -992,8 +894,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
let (ty::EquatePredicate(a, b), skol_map) =
|
||||
self.skolemize_late_bound_regions(predicate, snapshot);
|
||||
let origin = TypeOrigin::EquatePredicate(span);
|
||||
let eqty_ok = mk_eqty(self, false, origin, a, b)?;
|
||||
self.leak_check(&skol_map, snapshot).map(|_| eqty_ok.unit())
|
||||
let eqty_ok = self.eq_types(false, origin, a, b)?;
|
||||
self.leak_check(false, &skol_map, snapshot).map(|_| eqty_ok.unit())
|
||||
})
|
||||
}
|
||||
|
||||
@ -1006,8 +908,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
let (ty::OutlivesPredicate(r_a, r_b), skol_map) =
|
||||
self.skolemize_late_bound_regions(predicate, snapshot);
|
||||
let origin = RelateRegionParamBound(span);
|
||||
let () = mk_subr(self, origin, r_b, r_a); // `b : a` ==> `a <= b`
|
||||
self.leak_check(&skol_map, snapshot)
|
||||
self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b`
|
||||
self.leak_check(false, &skol_map, snapshot)
|
||||
})
|
||||
}
|
||||
|
||||
@ -1509,12 +1411,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
// anyhow. We should make this typetrace stuff more
|
||||
// generic so we don't have to do anything quite this
|
||||
// terrible.
|
||||
let e = self.tcx.types.err;
|
||||
let trace = TypeTrace {
|
||||
origin: TypeOrigin::Misc(codemap::DUMMY_SP),
|
||||
values: Types(expected_found(true, e, e))
|
||||
};
|
||||
self.equate(true, trace, a, b)
|
||||
self.equate(true, TypeTrace::dummy(self.tcx), a, b)
|
||||
}).map(|_| ())
|
||||
}
|
||||
|
||||
@ -1638,7 +1535,7 @@ impl<'tcx> TypeTrace<'tcx> {
|
||||
-> TypeTrace<'tcx> {
|
||||
TypeTrace {
|
||||
origin: origin,
|
||||
values: Types(expected_found(a_is_expected, a, b))
|
||||
values: Types(ExpectedFound::new(a_is_expected, a, b))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use super::combine::{self, CombineFields};
|
||||
use super::combine::CombineFields;
|
||||
use super::higher_ranked::HigherRankedRelations;
|
||||
use super::SubregionOrigin;
|
||||
use super::type_variable::{SubtypeOf, SupertypeOf};
|
||||
@ -96,7 +96,7 @@ impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Sub<'a, 'tcx> {
|
||||
}
|
||||
|
||||
_ => {
|
||||
combine::super_combine_tys(self.fields.infcx, self, a, b)?;
|
||||
self.fields.infcx.super_combine_tys(self, a, b)?;
|
||||
Ok(a)
|
||||
}
|
||||
}
|
||||
|
@ -20,59 +20,59 @@ use ty::{Ty, TyCtxt};
|
||||
use syntax::codemap::Span;
|
||||
use hir as ast;
|
||||
|
||||
pub fn prohibit_type_params(tcx: &TyCtxt, segments: &[ast::PathSegment]) {
|
||||
impl<'tcx> TyCtxt<'tcx> {
|
||||
pub fn prohibit_type_params(&self, segments: &[ast::PathSegment]) {
|
||||
for segment in segments {
|
||||
for typ in segment.parameters.types() {
|
||||
span_err!(tcx.sess, typ.span, E0109,
|
||||
span_err!(self.sess, typ.span, E0109,
|
||||
"type parameters are not allowed on this type");
|
||||
break;
|
||||
}
|
||||
for lifetime in segment.parameters.lifetimes() {
|
||||
span_err!(tcx.sess, lifetime.span, E0110,
|
||||
span_err!(self.sess, lifetime.span, E0110,
|
||||
"lifetime parameters are not allowed on this type");
|
||||
break;
|
||||
}
|
||||
for binding in segment.parameters.bindings() {
|
||||
prohibit_projection(tcx, binding.span);
|
||||
self.prohibit_projection(binding.span);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn prohibit_projection(tcx: &TyCtxt, span: Span)
|
||||
pub fn prohibit_projection(&self, span: Span)
|
||||
{
|
||||
span_err!(tcx.sess, span, E0229,
|
||||
span_err!(self.sess, span, E0229,
|
||||
"associated type bindings are not allowed here");
|
||||
}
|
||||
|
||||
pub fn prim_ty_to_ty<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
segments: &[ast::PathSegment],
|
||||
nty: ast::PrimTy)
|
||||
-> Ty<'tcx> {
|
||||
prohibit_type_params(tcx, segments);
|
||||
pub fn prim_ty_to_ty(&self,
|
||||
segments: &[ast::PathSegment],
|
||||
nty: ast::PrimTy)
|
||||
-> Ty<'tcx> {
|
||||
self.prohibit_type_params(segments);
|
||||
match nty {
|
||||
ast::TyBool => tcx.types.bool,
|
||||
ast::TyChar => tcx.types.char,
|
||||
ast::TyInt(it) => tcx.mk_mach_int(it),
|
||||
ast::TyUint(uit) => tcx.mk_mach_uint(uit),
|
||||
ast::TyFloat(ft) => tcx.mk_mach_float(ft),
|
||||
ast::TyStr => tcx.mk_str()
|
||||
ast::TyBool => self.types.bool,
|
||||
ast::TyChar => self.types.char,
|
||||
ast::TyInt(it) => self.mk_mach_int(it),
|
||||
ast::TyUint(uit) => self.mk_mach_uint(uit),
|
||||
ast::TyFloat(ft) => self.mk_mach_float(ft),
|
||||
ast::TyStr => self.mk_str()
|
||||
}
|
||||
}
|
||||
|
||||
/// If a type in the AST is a primitive type, return the ty::Ty corresponding
|
||||
/// to it.
|
||||
pub fn ast_ty_to_prim_ty<'tcx>(tcx: &TyCtxt<'tcx>, ast_ty: &ast::Ty)
|
||||
-> Option<Ty<'tcx>> {
|
||||
pub fn ast_ty_to_prim_ty(&self, ast_ty: &ast::Ty) -> Option<Ty<'tcx>> {
|
||||
if let ast::TyPath(None, ref path) = ast_ty.node {
|
||||
let def = match tcx.def_map.borrow().get(&ast_ty.id) {
|
||||
let def = match self.def_map.borrow().get(&ast_ty.id) {
|
||||
None => {
|
||||
span_bug!(ast_ty.span, "unbound path {:?}", path)
|
||||
}
|
||||
Some(d) => d.full_def()
|
||||
};
|
||||
if let Def::PrimTy(nty) = def {
|
||||
Some(prim_ty_to_ty(tcx, &path.segments, nty))
|
||||
Some(self.prim_ty_to_ty(&path.segments, nty))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -80,3 +80,4 @@ pub fn ast_ty_to_prim_ty<'tcx>(tcx: &TyCtxt<'tcx>, ast_ty: &ast::Ty)
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,9 +48,8 @@ impl FreeRegionMap {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn relate_free_regions_from_predicates<'tcx>(&mut self,
|
||||
_tcx: &TyCtxt<'tcx>,
|
||||
predicates: &[ty::Predicate<'tcx>]) {
|
||||
pub fn relate_free_regions_from_predicates(&mut self,
|
||||
predicates: &[ty::Predicate]) {
|
||||
debug!("relate_free_regions_from_predicates(predicates={:?})", predicates);
|
||||
for predicate in predicates {
|
||||
match *predicate {
|
||||
|
@ -625,9 +625,9 @@ fn maybe_do_stability_check(tcx: &TyCtxt, id: DefId, span: Span,
|
||||
return;
|
||||
}
|
||||
let (stability, deprecation) = if is_staged_api(tcx, id) {
|
||||
(lookup_stability(tcx, id), None)
|
||||
(tcx.lookup_stability(id), None)
|
||||
} else {
|
||||
(None, lookup_deprecation(tcx, id))
|
||||
(None, tcx.lookup_deprecation(id))
|
||||
};
|
||||
debug!("maybe_do_stability_check: \
|
||||
inspecting id={:?} span={:?} of stability={:?}", id, span, stability);
|
||||
@ -651,45 +651,47 @@ fn is_staged_api(tcx: &TyCtxt, id: DefId) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TyCtxt<'tcx> {
|
||||
/// Lookup the stability for a node, loading external crate
|
||||
/// metadata as necessary.
|
||||
pub fn lookup_stability<'tcx>(tcx: &TyCtxt<'tcx>, id: DefId) -> Option<&'tcx Stability> {
|
||||
if let Some(st) = tcx.stability.borrow().stab_map.get(&id) {
|
||||
pub fn lookup_stability(&self, id: DefId) -> Option<&'tcx Stability> {
|
||||
if let Some(st) = self.stability.borrow().stab_map.get(&id) {
|
||||
return *st;
|
||||
}
|
||||
|
||||
let st = lookup_stability_uncached(tcx, id);
|
||||
tcx.stability.borrow_mut().stab_map.insert(id, st);
|
||||
let st = self.lookup_stability_uncached(id);
|
||||
self.stability.borrow_mut().stab_map.insert(id, st);
|
||||
st
|
||||
}
|
||||
|
||||
pub fn lookup_deprecation<'tcx>(tcx: &TyCtxt<'tcx>, id: DefId) -> Option<Deprecation> {
|
||||
if let Some(depr) = tcx.stability.borrow().depr_map.get(&id) {
|
||||
pub fn lookup_deprecation(&self, id: DefId) -> Option<Deprecation> {
|
||||
if let Some(depr) = self.stability.borrow().depr_map.get(&id) {
|
||||
return depr.clone();
|
||||
}
|
||||
|
||||
let depr = lookup_deprecation_uncached(tcx, id);
|
||||
tcx.stability.borrow_mut().depr_map.insert(id, depr.clone());
|
||||
let depr = self.lookup_deprecation_uncached(id);
|
||||
self.stability.borrow_mut().depr_map.insert(id, depr.clone());
|
||||
depr
|
||||
}
|
||||
|
||||
fn lookup_stability_uncached<'tcx>(tcx: &TyCtxt<'tcx>, id: DefId) -> Option<&'tcx Stability> {
|
||||
fn lookup_stability_uncached(&self, id: DefId) -> Option<&'tcx Stability> {
|
||||
debug!("lookup(id={:?})", id);
|
||||
if id.is_local() {
|
||||
None // The stability cache is filled partially lazily
|
||||
} else {
|
||||
tcx.sess.cstore.stability(id).map(|st| tcx.intern_stability(st))
|
||||
self.sess.cstore.stability(id).map(|st| self.intern_stability(st))
|
||||
}
|
||||
}
|
||||
|
||||
fn lookup_deprecation_uncached<'tcx>(tcx: &TyCtxt<'tcx>, id: DefId) -> Option<Deprecation> {
|
||||
fn lookup_deprecation_uncached(&self, id: DefId) -> Option<Deprecation> {
|
||||
debug!("lookup(id={:?})", id);
|
||||
if id.is_local() {
|
||||
None // The stability cache is filled partially lazily
|
||||
} else {
|
||||
tcx.sess.cstore.deprecation(id)
|
||||
self.sess.cstore.deprecation(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Given the list of enabled features that were not language features (i.e. that
|
||||
/// were expected to be library features), and the list of features used from
|
||||
|
@ -16,7 +16,7 @@ use middle::cstore::LOCAL_CRATE;
|
||||
use hir::def_id::DefId;
|
||||
use ty::subst::TypeSpace;
|
||||
use ty::{self, Ty, TyCtxt};
|
||||
use infer::{self, InferCtxt, TypeOrigin};
|
||||
use infer::{InferCtxt, TypeOrigin};
|
||||
use syntax::codemap::DUMMY_SP;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
@ -57,11 +57,10 @@ fn overlap<'cx, 'tcx>(selcx: &mut SelectionContext<'cx, 'tcx>,
|
||||
debug!("overlap: b_impl_header={:?}", b_impl_header);
|
||||
|
||||
// Do `a` and `b` unify? If not, no overlap.
|
||||
if let Err(_) = infer::mk_eq_impl_headers(selcx.infcx(),
|
||||
true,
|
||||
TypeOrigin::Misc(DUMMY_SP),
|
||||
&a_impl_header,
|
||||
&b_impl_header) {
|
||||
if let Err(_) = selcx.infcx().eq_impl_headers(true,
|
||||
TypeOrigin::Misc(DUMMY_SP),
|
||||
&a_impl_header,
|
||||
&b_impl_header) {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,6 @@ use super::{
|
||||
SelectionError,
|
||||
ObjectSafetyViolation,
|
||||
MethodViolationCode,
|
||||
object_safety_violations,
|
||||
};
|
||||
|
||||
use fmt_macros::{Parser, Piece, Position};
|
||||
@ -61,56 +60,55 @@ impl<'tcx> TraitErrorKey<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn report_fulfillment_errors<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
errors: &Vec<FulfillmentError<'tcx>>) {
|
||||
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
pub fn report_fulfillment_errors(&self, errors: &Vec<FulfillmentError<'tcx>>) {
|
||||
for error in errors {
|
||||
report_fulfillment_error(infcx, error, None);
|
||||
self.report_fulfillment_error(error, None);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn report_fulfillment_errors_as_warnings<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
errors: &Vec<FulfillmentError<'tcx>>,
|
||||
node_id: ast::NodeId)
|
||||
{
|
||||
pub fn report_fulfillment_errors_as_warnings(&self,
|
||||
errors: &Vec<FulfillmentError<'tcx>>,
|
||||
node_id: ast::NodeId) {
|
||||
for error in errors {
|
||||
report_fulfillment_error(infcx, error, Some(node_id));
|
||||
self.report_fulfillment_error(error, Some(node_id));
|
||||
}
|
||||
}
|
||||
|
||||
fn report_fulfillment_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
error: &FulfillmentError<'tcx>,
|
||||
warning_node_id: Option<ast::NodeId>) {
|
||||
let error_key = TraitErrorKey::from_error(infcx, error, warning_node_id);
|
||||
fn report_fulfillment_error(&self,
|
||||
error: &FulfillmentError<'tcx>,
|
||||
warning_node_id: Option<ast::NodeId>) {
|
||||
let error_key = TraitErrorKey::from_error(self, error, warning_node_id);
|
||||
debug!("report_fulfillment_errors({:?}) - key={:?}",
|
||||
error, error_key);
|
||||
if !infcx.reported_trait_errors.borrow_mut().insert(error_key) {
|
||||
if !self.reported_trait_errors.borrow_mut().insert(error_key) {
|
||||
debug!("report_fulfillment_errors: skipping duplicate");
|
||||
return;
|
||||
}
|
||||
match error.code {
|
||||
FulfillmentErrorCode::CodeSelectionError(ref e) => {
|
||||
report_selection_error(infcx, &error.obligation, e, warning_node_id);
|
||||
self.report_selection_error(&error.obligation, e, warning_node_id);
|
||||
}
|
||||
FulfillmentErrorCode::CodeProjectionError(ref e) => {
|
||||
report_projection_error(infcx, &error.obligation, e, warning_node_id);
|
||||
self.report_projection_error(&error.obligation, e, warning_node_id);
|
||||
}
|
||||
FulfillmentErrorCode::CodeAmbiguity => {
|
||||
maybe_report_ambiguity(infcx, &error.obligation);
|
||||
self.maybe_report_ambiguity(&error.obligation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn report_projection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
error: &MismatchedProjectionTypes<'tcx>,
|
||||
warning_node_id: Option<ast::NodeId>)
|
||||
fn report_projection_error(&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
error: &MismatchedProjectionTypes<'tcx>,
|
||||
warning_node_id: Option<ast::NodeId>)
|
||||
{
|
||||
let predicate =
|
||||
infcx.resolve_type_vars_if_possible(&obligation.predicate);
|
||||
self.resolve_type_vars_if_possible(&obligation.predicate);
|
||||
|
||||
if !predicate.references_error() {
|
||||
if let Some(warning_node_id) = warning_node_id {
|
||||
infcx.tcx.sess.add_lint(
|
||||
self.tcx.sess.add_lint(
|
||||
::lint::builtin::UNSIZED_IN_TUPLE,
|
||||
warning_node_id,
|
||||
obligation.cause.span,
|
||||
@ -118,26 +116,26 @@ pub fn report_projection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
predicate,
|
||||
error.err));
|
||||
} else {
|
||||
let mut err = struct_span_err!(infcx.tcx.sess, obligation.cause.span, E0271,
|
||||
let mut err = struct_span_err!(self.tcx.sess, obligation.cause.span, E0271,
|
||||
"type mismatch resolving `{}`: {}",
|
||||
predicate,
|
||||
error.err);
|
||||
note_obligation_cause(infcx, &mut err, obligation);
|
||||
self.note_obligation_cause(&mut err, obligation);
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn on_unimplemented_note<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
span: Span) -> Option<String> {
|
||||
fn on_unimplemented_note(&self,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
span: Span) -> Option<String> {
|
||||
let trait_ref = trait_ref.skip_binder();
|
||||
let def_id = trait_ref.def_id;
|
||||
let mut report = None;
|
||||
for item in infcx.tcx.get_attrs(def_id).iter() {
|
||||
for item in self.tcx.get_attrs(def_id).iter() {
|
||||
if item.check_name("rustc_on_unimplemented") {
|
||||
let err_sp = item.meta().span.substitute_dummy(span);
|
||||
let def = infcx.tcx.lookup_trait_def(def_id);
|
||||
let def = self.tcx.lookup_trait_def(def_id);
|
||||
let trait_str = def.trait_ref.to_string();
|
||||
if let Some(ref istring) = item.value_str() {
|
||||
let mut generic_map = def.generics.types.iter_enumerated()
|
||||
@ -157,7 +155,7 @@ fn on_unimplemented_note<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
Position::ArgumentNamed(s) => match generic_map.get(s) {
|
||||
Some(val) => Some(val),
|
||||
None => {
|
||||
span_err!(infcx.tcx.sess, err_sp, E0272,
|
||||
span_err!(self.tcx.sess, err_sp, E0272,
|
||||
"the #[rustc_on_unimplemented] \
|
||||
attribute on \
|
||||
trait definition for {} refers to \
|
||||
@ -168,7 +166,7 @@ fn on_unimplemented_note<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
span_err!(infcx.tcx.sess, err_sp, E0273,
|
||||
span_err!(self.tcx.sess, err_sp, E0273,
|
||||
"the #[rustc_on_unimplemented] \
|
||||
attribute on \
|
||||
trait definition for {} must have named \
|
||||
@ -187,7 +185,7 @@ fn on_unimplemented_note<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
report = Some(err);
|
||||
}
|
||||
} else {
|
||||
span_err!(infcx.tcx.sess, err_sp, E0274,
|
||||
span_err!(self.tcx.sess, err_sp, E0274,
|
||||
"the #[rustc_on_unimplemented] attribute on \
|
||||
trait definition for {} must have a value, \
|
||||
eg `#[rustc_on_unimplemented = \"foo\"]`",
|
||||
@ -199,21 +197,20 @@ fn on_unimplemented_note<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
report
|
||||
}
|
||||
|
||||
fn find_similar_impl_candidates<'a, 'tcx>(
|
||||
infcx: &InferCtxt<'a, 'tcx>,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>)
|
||||
-> Vec<ty::TraitRef<'tcx>>
|
||||
fn report_similar_impl_candidates(&self,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
err: &mut DiagnosticBuilder)
|
||||
{
|
||||
let simp = fast_reject::simplify_type(infcx.tcx,
|
||||
let simp = fast_reject::simplify_type(self.tcx,
|
||||
trait_ref.skip_binder().self_ty(),
|
||||
true);
|
||||
let mut impl_candidates = Vec::new();
|
||||
let trait_def = infcx.tcx.lookup_trait_def(trait_ref.def_id());
|
||||
let trait_def = self.tcx.lookup_trait_def(trait_ref.def_id());
|
||||
|
||||
match simp {
|
||||
Some(simp) => trait_def.for_each_impl(infcx.tcx, |def_id| {
|
||||
let imp = infcx.tcx.impl_trait_ref(def_id).unwrap();
|
||||
let imp_simp = fast_reject::simplify_type(infcx.tcx,
|
||||
Some(simp) => trait_def.for_each_impl(self.tcx, |def_id| {
|
||||
let imp = self.tcx.impl_trait_ref(def_id).unwrap();
|
||||
let imp_simp = fast_reject::simplify_type(self.tcx,
|
||||
imp.self_ty(),
|
||||
true);
|
||||
if let Some(imp_simp) = imp_simp {
|
||||
@ -223,17 +220,16 @@ fn find_similar_impl_candidates<'a, 'tcx>(
|
||||
}
|
||||
impl_candidates.push(imp);
|
||||
}),
|
||||
None => trait_def.for_each_impl(infcx.tcx, |def_id| {
|
||||
None => trait_def.for_each_impl(self.tcx, |def_id| {
|
||||
impl_candidates.push(
|
||||
infcx.tcx.impl_trait_ref(def_id).unwrap());
|
||||
self.tcx.impl_trait_ref(def_id).unwrap());
|
||||
})
|
||||
};
|
||||
impl_candidates
|
||||
}
|
||||
|
||||
fn report_similar_impl_candidates(err: &mut DiagnosticBuilder,
|
||||
impl_candidates: &[ty::TraitRef])
|
||||
{
|
||||
if impl_candidates.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
err.help(&format!("the following implementations were found:"));
|
||||
|
||||
let end = cmp::min(4, impl_candidates.len());
|
||||
@ -251,26 +247,25 @@ fn report_similar_impl_candidates(err: &mut DiagnosticBuilder,
|
||||
/// whose result could not be truly determined and thus we can't say
|
||||
/// if the program type checks or not -- and they are unusual
|
||||
/// occurrences in any case.
|
||||
pub fn report_overflow_error<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
obligation: &Obligation<'tcx, T>,
|
||||
suggest_increasing_limit: bool)
|
||||
-> !
|
||||
pub fn report_overflow_error<T>(&self,
|
||||
obligation: &Obligation<'tcx, T>,
|
||||
suggest_increasing_limit: bool) -> !
|
||||
where T: fmt::Display + TypeFoldable<'tcx>
|
||||
{
|
||||
let predicate =
|
||||
infcx.resolve_type_vars_if_possible(&obligation.predicate);
|
||||
let mut err = struct_span_err!(infcx.tcx.sess, obligation.cause.span, E0275,
|
||||
self.resolve_type_vars_if_possible(&obligation.predicate);
|
||||
let mut err = struct_span_err!(self.tcx.sess, obligation.cause.span, E0275,
|
||||
"overflow evaluating the requirement `{}`",
|
||||
predicate);
|
||||
|
||||
if suggest_increasing_limit {
|
||||
suggest_new_overflow_limit(infcx.tcx, &mut err);
|
||||
self.suggest_new_overflow_limit(&mut err);
|
||||
}
|
||||
|
||||
note_obligation_cause(infcx, &mut err, obligation);
|
||||
self.note_obligation_cause(&mut err, obligation);
|
||||
|
||||
err.emit();
|
||||
infcx.tcx.sess.abort_if_errors();
|
||||
self.tcx.sess.abort_if_errors();
|
||||
bug!();
|
||||
}
|
||||
|
||||
@ -279,33 +274,29 @@ pub fn report_overflow_error<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
/// that we can give a more helpful error message (and, in particular,
|
||||
/// we do not suggest increasing the overflow limit, which is not
|
||||
/// going to help).
|
||||
pub fn report_overflow_error_cycle<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
cycle: &Vec<PredicateObligation<'tcx>>)
|
||||
-> !
|
||||
{
|
||||
pub fn report_overflow_error_cycle(&self, cycle: &Vec<PredicateObligation<'tcx>>) -> ! {
|
||||
assert!(cycle.len() > 1);
|
||||
|
||||
debug!("report_overflow_error_cycle(cycle length = {})", cycle.len());
|
||||
|
||||
let cycle = infcx.resolve_type_vars_if_possible(cycle);
|
||||
let cycle = self.resolve_type_vars_if_possible(cycle);
|
||||
|
||||
debug!("report_overflow_error_cycle: cycle={:?}", cycle);
|
||||
|
||||
assert_eq!(&cycle[0].predicate, &cycle.last().unwrap().predicate);
|
||||
|
||||
try_report_overflow_error_type_of_infinite_size(infcx, &cycle);
|
||||
report_overflow_error(infcx, &cycle[0], false);
|
||||
self.try_report_overflow_error_type_of_infinite_size(&cycle);
|
||||
self.report_overflow_error(&cycle[0], false);
|
||||
}
|
||||
|
||||
/// If a cycle results from evaluated whether something is Sized, that
|
||||
/// is a particular special case that always results from a struct or
|
||||
/// enum definition that lacks indirection (e.g., `struct Foo { x: Foo
|
||||
/// }`). We wish to report a targeted error for this case.
|
||||
pub fn try_report_overflow_error_type_of_infinite_size<'a, 'tcx>(
|
||||
infcx: &InferCtxt<'a, 'tcx>,
|
||||
pub fn try_report_overflow_error_type_of_infinite_size(&self,
|
||||
cycle: &[PredicateObligation<'tcx>])
|
||||
{
|
||||
let sized_trait = match infcx.tcx.lang_items.sized_trait() {
|
||||
let sized_trait = match self.tcx.lang_items.sized_trait() {
|
||||
Some(v) => v,
|
||||
None => return,
|
||||
};
|
||||
@ -373,8 +364,8 @@ pub fn try_report_overflow_error_type_of_infinite_size<'a, 'tcx>(
|
||||
.chain(struct_enum_tys.iter().cloned().take(main_index))
|
||||
.collect();
|
||||
|
||||
let tcx = infcx.tcx;
|
||||
let mut err = recursive_type_with_infinite_size_error(tcx, main_def_id);
|
||||
let tcx = self.tcx;
|
||||
let mut err = tcx.recursive_type_with_infinite_size_error(main_def_id);
|
||||
let len = struct_enum_tys.len();
|
||||
if len > 2 {
|
||||
err.note(&format!("type `{}` is embedded within `{}`...",
|
||||
@ -388,48 +379,38 @@ pub fn try_report_overflow_error_type_of_infinite_size<'a, 'tcx>(
|
||||
struct_enum_tys[len-1]));
|
||||
}
|
||||
err.emit();
|
||||
infcx.tcx.sess.abort_if_errors();
|
||||
self.tcx.sess.abort_if_errors();
|
||||
bug!();
|
||||
}
|
||||
|
||||
pub fn recursive_type_with_infinite_size_error<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
type_def_id: DefId)
|
||||
-> DiagnosticBuilder<'tcx>
|
||||
pub fn report_selection_error(&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
error: &SelectionError<'tcx>,
|
||||
warning_node_id: Option<ast::NodeId>)
|
||||
{
|
||||
assert!(type_def_id.is_local());
|
||||
let span = tcx.map.span_if_local(type_def_id).unwrap();
|
||||
let mut err = struct_span_err!(tcx.sess, span, E0072, "recursive type `{}` has infinite size",
|
||||
tcx.item_path_str(type_def_id));
|
||||
err.help(&format!("insert indirection (e.g., a `Box`, `Rc`, or `&`) \
|
||||
at some point to make `{}` representable",
|
||||
tcx.item_path_str(type_def_id)));
|
||||
err
|
||||
}
|
||||
|
||||
pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
error: &SelectionError<'tcx>,
|
||||
warning_node_id: Option<ast::NodeId>)
|
||||
{
|
||||
match *error {
|
||||
let span = obligation.cause.span;
|
||||
let mut err = match *error {
|
||||
SelectionError::Unimplemented => {
|
||||
if let ObligationCauseCode::CompareImplMethodObligation = obligation.cause.code {
|
||||
span_err!(
|
||||
infcx.tcx.sess, obligation.cause.span, E0276,
|
||||
self.tcx.sess, span, E0276,
|
||||
"the requirement `{}` appears on the impl \
|
||||
method but not on the corresponding trait method",
|
||||
obligation.predicate);
|
||||
return;
|
||||
} else {
|
||||
match obligation.predicate {
|
||||
ty::Predicate::Trait(ref trait_predicate) => {
|
||||
let trait_predicate =
|
||||
infcx.resolve_type_vars_if_possible(trait_predicate);
|
||||
self.resolve_type_vars_if_possible(trait_predicate);
|
||||
|
||||
if !infcx.tcx.sess.has_errors() || !trait_predicate.references_error() {
|
||||
if self.tcx.sess.has_errors() && trait_predicate.references_error() {
|
||||
return;
|
||||
} else {
|
||||
let trait_ref = trait_predicate.to_poly_trait_ref();
|
||||
|
||||
if let Some(warning_node_id) = warning_node_id {
|
||||
infcx.tcx.sess.add_lint(
|
||||
self.tcx.sess.add_lint(
|
||||
::lint::builtin::UNSIZED_IN_TUPLE,
|
||||
warning_node_id,
|
||||
obligation.cause.span,
|
||||
@ -439,14 +420,14 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
}
|
||||
|
||||
let mut err = struct_span_err!(
|
||||
infcx.tcx.sess, obligation.cause.span, E0277,
|
||||
self.tcx.sess, span, E0277,
|
||||
"the trait bound `{}` is not satisfied",
|
||||
trait_ref.to_predicate());
|
||||
|
||||
// Try to report a help message
|
||||
|
||||
if !trait_ref.has_infer_types() &&
|
||||
predicate_can_apply(infcx, trait_ref)
|
||||
self.predicate_can_apply(trait_ref)
|
||||
{
|
||||
// If a where-clause may be useful, remind the
|
||||
// user that they can add it.
|
||||
@ -458,8 +439,7 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
err.help(&format!("consider adding a `where {}` bound",
|
||||
trait_ref.to_predicate()
|
||||
));
|
||||
} else if let Some(s) = on_unimplemented_note(infcx, trait_ref,
|
||||
obligation.cause.span) {
|
||||
} else if let Some(s) = self.on_unimplemented_note(trait_ref, span) {
|
||||
// Otherwise, if there is an on-unimplemented note,
|
||||
// display it.
|
||||
err.note(&s);
|
||||
@ -467,72 +447,55 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
// If we can't show anything useful, try to find
|
||||
// similar impls.
|
||||
|
||||
let impl_candidates =
|
||||
find_similar_impl_candidates(infcx, trait_ref);
|
||||
if impl_candidates.len() > 0 {
|
||||
report_similar_impl_candidates(&mut err, &impl_candidates);
|
||||
}
|
||||
self.report_similar_impl_candidates(trait_ref, &mut err);
|
||||
}
|
||||
note_obligation_cause(infcx, &mut err, obligation);
|
||||
err.emit();
|
||||
err
|
||||
}
|
||||
},
|
||||
ty::Predicate::Equate(ref predicate) => {
|
||||
let predicate = infcx.resolve_type_vars_if_possible(predicate);
|
||||
let err = infcx.equality_predicate(obligation.cause.span,
|
||||
&predicate).err().unwrap();
|
||||
let mut err = struct_span_err!(
|
||||
infcx.tcx.sess, obligation.cause.span, E0278,
|
||||
let predicate = self.resolve_type_vars_if_possible(predicate);
|
||||
let err = self.equality_predicate(span,
|
||||
&predicate).err().unwrap();
|
||||
struct_span_err!(self.tcx.sess, span, E0278,
|
||||
"the requirement `{}` is not satisfied (`{}`)",
|
||||
predicate,
|
||||
err);
|
||||
note_obligation_cause(infcx, &mut err, obligation);
|
||||
err.emit();
|
||||
predicate, err)
|
||||
}
|
||||
|
||||
ty::Predicate::RegionOutlives(ref predicate) => {
|
||||
let predicate = infcx.resolve_type_vars_if_possible(predicate);
|
||||
let err = infcx.region_outlives_predicate(obligation.cause.span,
|
||||
&predicate).err().unwrap();
|
||||
let mut err = struct_span_err!(
|
||||
infcx.tcx.sess, obligation.cause.span, E0279,
|
||||
let predicate = self.resolve_type_vars_if_possible(predicate);
|
||||
let err = self.region_outlives_predicate(span,
|
||||
&predicate).err().unwrap();
|
||||
struct_span_err!(self.tcx.sess, span, E0279,
|
||||
"the requirement `{}` is not satisfied (`{}`)",
|
||||
predicate,
|
||||
err);
|
||||
note_obligation_cause(infcx, &mut err, obligation);
|
||||
err.emit();
|
||||
predicate, err)
|
||||
}
|
||||
|
||||
ty::Predicate::Projection(..) | ty::Predicate::TypeOutlives(..) => {
|
||||
let predicate =
|
||||
infcx.resolve_type_vars_if_possible(&obligation.predicate);
|
||||
let mut err = struct_span_err!(
|
||||
infcx.tcx.sess, obligation.cause.span, E0280,
|
||||
self.resolve_type_vars_if_possible(&obligation.predicate);
|
||||
struct_span_err!(self.tcx.sess, span, E0280,
|
||||
"the requirement `{}` is not satisfied",
|
||||
predicate);
|
||||
note_obligation_cause(infcx, &mut err, obligation);
|
||||
err.emit();
|
||||
predicate)
|
||||
}
|
||||
|
||||
ty::Predicate::ObjectSafe(trait_def_id) => {
|
||||
let violations = object_safety_violations(
|
||||
infcx.tcx, trait_def_id);
|
||||
let err = report_object_safety_error(infcx.tcx,
|
||||
obligation.cause.span,
|
||||
trait_def_id,
|
||||
warning_node_id,
|
||||
violations);
|
||||
if let Some(mut err) = err {
|
||||
note_obligation_cause(infcx, &mut err, obligation);
|
||||
err.emit();
|
||||
let violations = self.tcx.object_safety_violations(trait_def_id);
|
||||
let err = self.tcx.report_object_safety_error(span,
|
||||
trait_def_id,
|
||||
warning_node_id,
|
||||
violations);
|
||||
if let Some(err) = err {
|
||||
err
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ty::Predicate::ClosureKind(closure_def_id, kind) => {
|
||||
let found_kind = infcx.closure_kind(closure_def_id).unwrap();
|
||||
let closure_span = infcx.tcx.map.span_if_local(closure_def_id).unwrap();
|
||||
let found_kind = self.closure_kind(closure_def_id).unwrap();
|
||||
let closure_span = self.tcx.map.span_if_local(closure_def_id).unwrap();
|
||||
let mut err = struct_span_err!(
|
||||
infcx.tcx.sess, closure_span, E0525,
|
||||
self.tcx.sess, closure_span, E0525,
|
||||
"expected a closure that implements the `{}` trait, but this closure \
|
||||
only implements `{}`",
|
||||
kind,
|
||||
@ -541,6 +504,7 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
obligation.cause.span,
|
||||
&format!("the requirement to implement `{}` derives from here", kind));
|
||||
err.emit();
|
||||
return;
|
||||
}
|
||||
|
||||
ty::Predicate::WellFormed(ty) => {
|
||||
@ -549,10 +513,7 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
// ambiguity; otherwise, they always
|
||||
// degenerate into other obligations
|
||||
// (which may fail).
|
||||
span_bug!(
|
||||
obligation.cause.span,
|
||||
"WF predicate not satisfied for {:?}",
|
||||
ty);
|
||||
span_bug!(span, "WF predicate not satisfied for {:?}", ty);
|
||||
}
|
||||
|
||||
ty::Predicate::Rfc1592(ref data) => {
|
||||
@ -566,49 +527,66 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
}
|
||||
|
||||
OutputTypeParameterMismatch(ref expected_trait_ref, ref actual_trait_ref, ref e) => {
|
||||
let expected_trait_ref = infcx.resolve_type_vars_if_possible(&*expected_trait_ref);
|
||||
let actual_trait_ref = infcx.resolve_type_vars_if_possible(&*actual_trait_ref);
|
||||
if !actual_trait_ref.self_ty().references_error() {
|
||||
let mut err = struct_span_err!(
|
||||
infcx.tcx.sess, obligation.cause.span, E0281,
|
||||
"type mismatch: the type `{}` implements the trait `{}`, \
|
||||
but the trait `{}` is required ({})",
|
||||
expected_trait_ref.self_ty(),
|
||||
expected_trait_ref,
|
||||
actual_trait_ref,
|
||||
e);
|
||||
note_obligation_cause(infcx, &mut err, obligation);
|
||||
err.emit();
|
||||
let expected_trait_ref = self.resolve_type_vars_if_possible(&*expected_trait_ref);
|
||||
let actual_trait_ref = self.resolve_type_vars_if_possible(&*actual_trait_ref);
|
||||
if actual_trait_ref.self_ty().references_error() {
|
||||
return;
|
||||
}
|
||||
struct_span_err!(self.tcx.sess, span, E0281,
|
||||
"type mismatch: the type `{}` implements the trait `{}`, \
|
||||
but the trait `{}` is required ({})",
|
||||
expected_trait_ref.self_ty(),
|
||||
expected_trait_ref,
|
||||
actual_trait_ref,
|
||||
e)
|
||||
}
|
||||
|
||||
TraitNotObjectSafe(did) => {
|
||||
let violations = object_safety_violations(infcx.tcx, did);
|
||||
let err = report_object_safety_error(infcx.tcx, obligation.cause.span, did,
|
||||
warning_node_id,
|
||||
violations);
|
||||
if let Some(mut err) = err {
|
||||
note_obligation_cause(infcx, &mut err, obligation);
|
||||
err.emit();
|
||||
let violations = self.tcx.object_safety_violations(did);
|
||||
let err = self.tcx.report_object_safety_error(span, did,
|
||||
warning_node_id,
|
||||
violations);
|
||||
if let Some(err) = err {
|
||||
err
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
self.note_obligation_cause(&mut err, obligation);
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn report_object_safety_error<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
span: Span,
|
||||
trait_def_id: DefId,
|
||||
warning_node_id: Option<ast::NodeId>,
|
||||
violations: Vec<ObjectSafetyViolation>)
|
||||
-> Option<DiagnosticBuilder<'tcx>>
|
||||
impl<'tcx> TyCtxt<'tcx> {
|
||||
pub fn recursive_type_with_infinite_size_error(&self,
|
||||
type_def_id: DefId)
|
||||
-> DiagnosticBuilder<'tcx>
|
||||
{
|
||||
assert!(type_def_id.is_local());
|
||||
let span = self.map.span_if_local(type_def_id).unwrap();
|
||||
let mut err = struct_span_err!(self.sess, span, E0072, "recursive type `{}` has infinite size",
|
||||
self.item_path_str(type_def_id));
|
||||
err.help(&format!("insert indirection (e.g., a `Box`, `Rc`, or `&`) \
|
||||
at some point to make `{}` representable",
|
||||
self.item_path_str(type_def_id)));
|
||||
err
|
||||
}
|
||||
|
||||
pub fn report_object_safety_error(&self,
|
||||
span: Span,
|
||||
trait_def_id: DefId,
|
||||
warning_node_id: Option<ast::NodeId>,
|
||||
violations: Vec<ObjectSafetyViolation>)
|
||||
-> Option<DiagnosticBuilder<'tcx>>
|
||||
{
|
||||
let mut err = match warning_node_id {
|
||||
Some(_) => None,
|
||||
None => {
|
||||
Some(struct_span_err!(
|
||||
tcx.sess, span, E0038,
|
||||
self.sess, span, E0038,
|
||||
"the trait `{}` cannot be made into an object",
|
||||
tcx.item_path_str(trait_def_id)))
|
||||
self.item_path_str(trait_def_id)))
|
||||
}
|
||||
};
|
||||
|
||||
@ -652,7 +630,7 @@ pub fn report_object_safety_error<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
};
|
||||
match (warning_node_id, &mut err) {
|
||||
(Some(node_id), &mut None) => {
|
||||
tcx.sess.add_lint(
|
||||
self.sess.add_lint(
|
||||
::lint::builtin::OBJECT_UNSAFE_FRAGMENT,
|
||||
node_id,
|
||||
span,
|
||||
@ -666,15 +644,16 @@ pub fn report_object_safety_error<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
}
|
||||
err
|
||||
}
|
||||
}
|
||||
|
||||
pub fn maybe_report_ambiguity<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
obligation: &PredicateObligation<'tcx>) {
|
||||
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>) {
|
||||
// Unable to successfully determine, probably means
|
||||
// insufficient type information, but could mean
|
||||
// ambiguous impls. The latter *ought* to be a
|
||||
// coherence violation, so we don't report it here.
|
||||
|
||||
let predicate = infcx.resolve_type_vars_if_possible(&obligation.predicate);
|
||||
let predicate = self.resolve_type_vars_if_possible(&obligation.predicate);
|
||||
|
||||
debug!("maybe_report_ambiguity(predicate={:?}, obligation={:?})",
|
||||
predicate,
|
||||
@ -682,7 +661,7 @@ pub fn maybe_report_ambiguity<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
|
||||
// Ambiguity errors are often caused as fallout from earlier
|
||||
// errors. So just ignore them if this infcx is tainted.
|
||||
if infcx.is_tainted_by_errors() {
|
||||
if self.is_tainted_by_errors() {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -717,18 +696,18 @@ pub fn maybe_report_ambiguity<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
// inhabited. But in any case I just threw in this check for
|
||||
// has_errors() to be sure that compilation isn't happening
|
||||
// anyway. In that case, why inundate the user.
|
||||
if !infcx.tcx.sess.has_errors() {
|
||||
if !self.tcx.sess.has_errors() {
|
||||
if
|
||||
infcx.tcx.lang_items.sized_trait()
|
||||
self.tcx.lang_items.sized_trait()
|
||||
.map_or(false, |sized_id| sized_id == trait_ref.def_id())
|
||||
{
|
||||
need_type_info(infcx, obligation.cause.span, self_ty);
|
||||
self.need_type_info(obligation.cause.span, self_ty);
|
||||
} else {
|
||||
let mut err = struct_span_err!(infcx.tcx.sess, obligation.cause.span, E0283,
|
||||
let mut err = struct_span_err!(self.tcx.sess, obligation.cause.span, E0283,
|
||||
"type annotations required: \
|
||||
cannot resolve `{}`",
|
||||
predicate);
|
||||
note_obligation_cause(infcx, &mut err, obligation);
|
||||
self.note_obligation_cause(&mut err, obligation);
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
@ -738,17 +717,17 @@ pub fn maybe_report_ambiguity<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
ty::Predicate::WellFormed(ty) => {
|
||||
// Same hacky approach as above to avoid deluging user
|
||||
// with error messages.
|
||||
if !ty.references_error() && !infcx.tcx.sess.has_errors() {
|
||||
need_type_info(infcx, obligation.cause.span, ty);
|
||||
if !ty.references_error() && !self.tcx.sess.has_errors() {
|
||||
self.need_type_info(obligation.cause.span, ty);
|
||||
}
|
||||
}
|
||||
|
||||
_ => {
|
||||
if !infcx.tcx.sess.has_errors() {
|
||||
let mut err = struct_span_err!(infcx.tcx.sess, obligation.cause.span, E0284,
|
||||
if !self.tcx.sess.has_errors() {
|
||||
let mut err = struct_span_err!(self.tcx.sess, obligation.cause.span, E0284,
|
||||
"type annotations required: cannot resolve `{}`",
|
||||
predicate);
|
||||
note_obligation_cause(infcx, &mut err, obligation);
|
||||
self.note_obligation_cause(&mut err, obligation);
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
@ -757,10 +736,7 @@ pub fn maybe_report_ambiguity<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
|
||||
/// Returns whether the trait predicate may apply for *some* assignment
|
||||
/// to the type parameters.
|
||||
fn predicate_can_apply<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
pred: ty::PolyTraitRef<'tcx>)
|
||||
-> bool
|
||||
{
|
||||
fn predicate_can_apply(&self, pred: ty::PolyTraitRef<'tcx>) -> bool {
|
||||
struct ParamToVarFolder<'a, 'tcx: 'a> {
|
||||
infcx: &'a InferCtxt<'a, 'tcx>,
|
||||
var_map: FnvHashMap<Ty<'tcx>, Ty<'tcx>>
|
||||
@ -780,11 +756,11 @@ fn predicate_can_apply<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
}
|
||||
}
|
||||
|
||||
infcx.probe(|_| {
|
||||
let mut selcx = SelectionContext::new(infcx);
|
||||
self.probe(|_| {
|
||||
let mut selcx = SelectionContext::new(self);
|
||||
|
||||
let cleaned_pred = pred.fold_with(&mut ParamToVarFolder {
|
||||
infcx: infcx,
|
||||
infcx: self,
|
||||
var_map: FnvHashMap()
|
||||
});
|
||||
|
||||
@ -804,34 +780,30 @@ fn predicate_can_apply<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
}
|
||||
|
||||
|
||||
fn need_type_info<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
span: Span,
|
||||
ty: Ty<'tcx>)
|
||||
{
|
||||
span_err!(infcx.tcx.sess, span, E0282,
|
||||
fn need_type_info(&self, span: Span, ty: Ty<'tcx>) {
|
||||
span_err!(self.tcx.sess, span, E0282,
|
||||
"unable to infer enough type information about `{}`; \
|
||||
type annotations or generic parameter binding required",
|
||||
ty);
|
||||
}
|
||||
|
||||
fn note_obligation_cause<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
err: &mut DiagnosticBuilder,
|
||||
obligation: &Obligation<'tcx, T>)
|
||||
fn note_obligation_cause<T>(&self,
|
||||
err: &mut DiagnosticBuilder,
|
||||
obligation: &Obligation<'tcx, T>)
|
||||
where T: fmt::Display
|
||||
{
|
||||
note_obligation_cause_code(infcx,
|
||||
err,
|
||||
&obligation.predicate,
|
||||
&obligation.cause.code);
|
||||
self.note_obligation_cause_code(err,
|
||||
&obligation.predicate,
|
||||
&obligation.cause.code);
|
||||
}
|
||||
|
||||
fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
err: &mut DiagnosticBuilder,
|
||||
predicate: &T,
|
||||
cause_code: &ObligationCauseCode<'tcx>)
|
||||
fn note_obligation_cause_code<T>(&self,
|
||||
err: &mut DiagnosticBuilder,
|
||||
predicate: &T,
|
||||
cause_code: &ObligationCauseCode<'tcx>)
|
||||
where T: fmt::Display
|
||||
{
|
||||
let tcx = infcx.tcx;
|
||||
let tcx = self.tcx;
|
||||
match *cause_code {
|
||||
ObligationCauseCode::MiscObligation => { }
|
||||
ObligationCauseCode::SliceOrArrayElem => {
|
||||
@ -854,7 +826,7 @@ fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
}
|
||||
ObligationCauseCode::ObjectCastObligation(object_ty) => {
|
||||
err.note(&format!("required for the cast to the object type `{}`",
|
||||
infcx.ty_to_string(object_ty)));
|
||||
self.ty_to_string(object_ty)));
|
||||
}
|
||||
ObligationCauseCode::RepeatVec => {
|
||||
err.note("the `Copy` trait is required because the \
|
||||
@ -891,26 +863,24 @@ fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
err.note("shared static variables must have a type that implements `Sync`");
|
||||
}
|
||||
ObligationCauseCode::BuiltinDerivedObligation(ref data) => {
|
||||
let parent_trait_ref = infcx.resolve_type_vars_if_possible(&data.parent_trait_ref);
|
||||
let parent_trait_ref = self.resolve_type_vars_if_possible(&data.parent_trait_ref);
|
||||
err.note(&format!("required because it appears within the type `{}`",
|
||||
parent_trait_ref.0.self_ty()));
|
||||
let parent_predicate = parent_trait_ref.to_predicate();
|
||||
note_obligation_cause_code(infcx,
|
||||
err,
|
||||
&parent_predicate,
|
||||
&data.parent_code);
|
||||
self.note_obligation_cause_code(err,
|
||||
&parent_predicate,
|
||||
&data.parent_code);
|
||||
}
|
||||
ObligationCauseCode::ImplDerivedObligation(ref data) => {
|
||||
let parent_trait_ref = infcx.resolve_type_vars_if_possible(&data.parent_trait_ref);
|
||||
let parent_trait_ref = self.resolve_type_vars_if_possible(&data.parent_trait_ref);
|
||||
err.note(
|
||||
&format!("required because of the requirements on the impl of `{}` for `{}`",
|
||||
parent_trait_ref,
|
||||
parent_trait_ref.0.self_ty()));
|
||||
let parent_predicate = parent_trait_ref.to_predicate();
|
||||
note_obligation_cause_code(infcx,
|
||||
err,
|
||||
&parent_predicate,
|
||||
&data.parent_code);
|
||||
self.note_obligation_cause_code(err,
|
||||
&parent_predicate,
|
||||
&data.parent_code);
|
||||
}
|
||||
ObligationCauseCode::CompareImplMethodObligation => {
|
||||
err.note(
|
||||
@ -921,10 +891,11 @@ fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
}
|
||||
}
|
||||
|
||||
fn suggest_new_overflow_limit(tcx: &TyCtxt, err:&mut DiagnosticBuilder) {
|
||||
let current_limit = tcx.sess.recursion_limit.get();
|
||||
fn suggest_new_overflow_limit(&self, err: &mut DiagnosticBuilder) {
|
||||
let current_limit = self.tcx.sess.recursion_limit.get();
|
||||
let suggested_limit = current_limit * 2;
|
||||
err.note(&format!(
|
||||
"consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate",
|
||||
suggested_limit));
|
||||
}
|
||||
}
|
||||
|
@ -21,16 +21,13 @@ use util::nodemap::{FnvHashMap, FnvHashSet, NodeMap};
|
||||
use super::CodeAmbiguity;
|
||||
use super::CodeProjectionError;
|
||||
use super::CodeSelectionError;
|
||||
use super::is_object_safe;
|
||||
use super::FulfillmentError;
|
||||
use super::FulfillmentErrorCode;
|
||||
use super::ObligationCause;
|
||||
use super::PredicateObligation;
|
||||
use super::project;
|
||||
use super::report_overflow_error_cycle;
|
||||
use super::select::SelectionContext;
|
||||
use super::Unimplemented;
|
||||
use super::util::predicate_for_builtin_bound;
|
||||
|
||||
pub struct GlobalFulfilledPredicates<'tcx> {
|
||||
set: FnvHashSet<ty::PolyTraitPredicate<'tcx>>,
|
||||
@ -163,7 +160,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
|
||||
builtin_bound: ty::BuiltinBound,
|
||||
cause: ObligationCause<'tcx>)
|
||||
{
|
||||
match predicate_for_builtin_bound(infcx.tcx, cause, builtin_bound, 0, ty) {
|
||||
match infcx.tcx.predicate_for_builtin_bound(cause, builtin_bound, 0, ty) {
|
||||
Ok(predicate) => {
|
||||
self.register_predicate_obligation(infcx, predicate);
|
||||
}
|
||||
@ -449,7 +446,7 @@ fn process_child_obligations<'a,'tcx>(
|
||||
debug!("process_child_obligations: coinductive match");
|
||||
None
|
||||
} else {
|
||||
report_overflow_error_cycle(selcx.infcx(), &cycle);
|
||||
selcx.infcx().report_overflow_error_cycle(&cycle);
|
||||
}
|
||||
} else {
|
||||
// Not a cycle. Just ignore this obligation then,
|
||||
@ -677,7 +674,7 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
|
||||
}
|
||||
|
||||
ty::Predicate::ObjectSafe(trait_def_id) => {
|
||||
if !is_object_safe(selcx.tcx(), trait_def_id) {
|
||||
if !selcx.tcx().is_object_safe(trait_def_id) {
|
||||
Err(CodeSelectionError(Unimplemented))
|
||||
} else {
|
||||
Ok(Some(Vec::new()))
|
||||
|
@ -19,46 +19,31 @@ use hir::def_id::DefId;
|
||||
use middle::free_region::FreeRegionMap;
|
||||
use ty::subst;
|
||||
use ty::{self, Ty, TypeFoldable};
|
||||
use infer::{fixup_err_to_string, InferCtxt};
|
||||
use infer::InferCtxt;
|
||||
|
||||
use std::rc::Rc;
|
||||
use syntax::ast;
|
||||
use syntax::codemap::{Span, DUMMY_SP};
|
||||
|
||||
pub use self::error_reporting::TraitErrorKey;
|
||||
pub use self::error_reporting::recursive_type_with_infinite_size_error;
|
||||
pub use self::error_reporting::report_fulfillment_errors;
|
||||
pub use self::error_reporting::report_fulfillment_errors_as_warnings;
|
||||
pub use self::error_reporting::report_overflow_error;
|
||||
pub use self::error_reporting::report_overflow_error_cycle;
|
||||
pub use self::error_reporting::report_selection_error;
|
||||
pub use self::error_reporting::report_object_safety_error;
|
||||
pub use self::coherence::orphan_check;
|
||||
pub use self::coherence::overlapping_impls;
|
||||
pub use self::coherence::OrphanCheckErr;
|
||||
pub use self::fulfill::{FulfillmentContext, GlobalFulfilledPredicates, RegionObligation};
|
||||
pub use self::project::{MismatchedProjectionTypes, ProjectionMode};
|
||||
pub use self::project::{normalize, Normalized};
|
||||
pub use self::object_safety::is_object_safe;
|
||||
pub use self::object_safety::astconv_object_safety_violations;
|
||||
pub use self::object_safety::object_safety_violations;
|
||||
pub use self::object_safety::ObjectSafetyViolation;
|
||||
pub use self::object_safety::MethodViolationCode;
|
||||
pub use self::object_safety::is_vtable_safe_method;
|
||||
pub use self::select::{EvaluationCache, SelectionContext, SelectionCache};
|
||||
pub use self::select::{MethodMatchResult, MethodMatched, MethodAmbiguous, MethodDidNotMatch};
|
||||
pub use self::select::{MethodMatchedData}; // intentionally don't export variants
|
||||
pub use self::specialize::{Overlap, specialization_graph, specializes, translate_substs};
|
||||
pub use self::util::elaborate_predicates;
|
||||
pub use self::util::get_vtable_index_of_object_method;
|
||||
pub use self::util::trait_ref_for_builtin_bound;
|
||||
pub use self::util::predicate_for_trait_def;
|
||||
pub use self::util::supertraits;
|
||||
pub use self::util::Supertraits;
|
||||
pub use self::util::supertrait_def_ids;
|
||||
pub use self::util::SupertraitDefIds;
|
||||
pub use self::util::transitive_bounds;
|
||||
pub use self::util::upcast;
|
||||
|
||||
mod coherence;
|
||||
mod error_reporting;
|
||||
@ -343,7 +328,7 @@ pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
|
||||
|
||||
let cause = ObligationCause::misc(span, ast::DUMMY_NODE_ID);
|
||||
let obligation =
|
||||
util::predicate_for_builtin_bound(infcx.tcx, cause, bound, 0, ty);
|
||||
infcx.tcx.predicate_for_builtin_bound(cause, bound, 0, ty);
|
||||
let obligation = match obligation {
|
||||
Ok(o) => o,
|
||||
Err(..) => return false
|
||||
@ -444,7 +429,7 @@ pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvi
|
||||
&infcx.parameter_environment.caller_bounds) {
|
||||
Ok(predicates) => predicates,
|
||||
Err(errors) => {
|
||||
report_fulfillment_errors(&infcx, &errors);
|
||||
infcx.report_fulfillment_errors(&errors);
|
||||
return infcx.parameter_environment; // an unnormalized env is better than nothing
|
||||
}
|
||||
};
|
||||
@ -464,8 +449,7 @@ pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvi
|
||||
// represents a legitimate failure due to some kind of
|
||||
// unconstrained variable, and it seems better not to ICE,
|
||||
// all things considered.
|
||||
let err_msg = fixup_err_to_string(fixup_err);
|
||||
tcx.sess.span_err(span, &err_msg);
|
||||
tcx.sess.span_err(span, &fixup_err.to_string());
|
||||
return infcx.parameter_environment; // an unnormalized env is better than nothing
|
||||
}
|
||||
};
|
||||
|
@ -53,15 +53,13 @@ pub enum MethodViolationCode {
|
||||
Generic,
|
||||
}
|
||||
|
||||
pub fn is_object_safe<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
trait_def_id: DefId)
|
||||
-> bool
|
||||
{
|
||||
impl<'tcx> TyCtxt<'tcx> {
|
||||
pub fn is_object_safe(&self, trait_def_id: DefId) -> bool {
|
||||
// Because we query yes/no results frequently, we keep a cache:
|
||||
let def = tcx.lookup_trait_def(trait_def_id);
|
||||
let def = self.lookup_trait_def(trait_def_id);
|
||||
|
||||
let result = def.object_safety().unwrap_or_else(|| {
|
||||
let result = object_safety_violations(tcx, trait_def_id).is_empty();
|
||||
let result = self.object_safety_violations(trait_def_id).is_empty();
|
||||
|
||||
// Record just a yes/no result in the cache; this is what is
|
||||
// queried most frequently. Note that this may overwrite a
|
||||
@ -80,43 +78,40 @@ pub fn is_object_safe<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
/// astconv - currently, Self in supertraits. This is needed
|
||||
/// because `object_safety_violations` can't be used during
|
||||
/// type collection.
|
||||
pub fn astconv_object_safety_violations<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
trait_def_id: DefId)
|
||||
-> Vec<ObjectSafetyViolation<'tcx>>
|
||||
pub fn astconv_object_safety_violations(&self, trait_def_id: DefId)
|
||||
-> Vec<ObjectSafetyViolation<'tcx>>
|
||||
{
|
||||
let mut violations = vec![];
|
||||
|
||||
if supertraits_reference_self(tcx, trait_def_id) {
|
||||
if self.supertraits_reference_self(trait_def_id) {
|
||||
violations.push(ObjectSafetyViolation::SupertraitSelf);
|
||||
}
|
||||
|
||||
debug!("object_safety_violations_for_trait(trait_def_id={:?}) = {:?}",
|
||||
debug!("astconv_object_safety_violations(trait_def_id={:?}) = {:?}",
|
||||
trait_def_id,
|
||||
violations);
|
||||
|
||||
violations
|
||||
}
|
||||
|
||||
pub fn object_safety_violations<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
trait_def_id: DefId)
|
||||
-> Vec<ObjectSafetyViolation<'tcx>>
|
||||
pub fn object_safety_violations(&self, trait_def_id: DefId)
|
||||
-> Vec<ObjectSafetyViolation<'tcx>>
|
||||
{
|
||||
traits::supertrait_def_ids(tcx, trait_def_id)
|
||||
.flat_map(|def_id| object_safety_violations_for_trait(tcx, def_id))
|
||||
traits::supertrait_def_ids(self, trait_def_id)
|
||||
.flat_map(|def_id| self.object_safety_violations_for_trait(def_id))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn object_safety_violations_for_trait<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
trait_def_id: DefId)
|
||||
-> Vec<ObjectSafetyViolation<'tcx>>
|
||||
fn object_safety_violations_for_trait(&self, trait_def_id: DefId)
|
||||
-> Vec<ObjectSafetyViolation<'tcx>>
|
||||
{
|
||||
// Check methods for violations.
|
||||
let mut violations: Vec<_> =
|
||||
tcx.trait_items(trait_def_id).iter()
|
||||
self.trait_items(trait_def_id).iter()
|
||||
.filter_map(|item| {
|
||||
match *item {
|
||||
ty::MethodTraitItem(ref m) => {
|
||||
object_safety_violation_for_method(tcx, trait_def_id, &m)
|
||||
self.object_safety_violation_for_method(trait_def_id, &m)
|
||||
.map(|code| ObjectSafetyViolation::Method(m.clone(), code))
|
||||
}
|
||||
_ => None,
|
||||
@ -125,10 +120,10 @@ fn object_safety_violations_for_trait<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
.collect();
|
||||
|
||||
// Check the trait itself.
|
||||
if trait_has_sized_self(tcx, trait_def_id) {
|
||||
if self.trait_has_sized_self(trait_def_id) {
|
||||
violations.push(ObjectSafetyViolation::SizedSelf);
|
||||
}
|
||||
if supertraits_reference_self(tcx, trait_def_id) {
|
||||
if self.supertraits_reference_self(trait_def_id) {
|
||||
violations.push(ObjectSafetyViolation::SupertraitSelf);
|
||||
}
|
||||
|
||||
@ -139,18 +134,15 @@ fn object_safety_violations_for_trait<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
violations
|
||||
}
|
||||
|
||||
pub fn supertraits_reference_self<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
trait_def_id: DefId)
|
||||
-> bool
|
||||
{
|
||||
let trait_def = tcx.lookup_trait_def(trait_def_id);
|
||||
fn supertraits_reference_self(&self, trait_def_id: DefId) -> bool {
|
||||
let trait_def = self.lookup_trait_def(trait_def_id);
|
||||
let trait_ref = trait_def.trait_ref.clone();
|
||||
let trait_ref = trait_ref.to_poly_trait_ref();
|
||||
let predicates = tcx.lookup_super_predicates(trait_def_id);
|
||||
let predicates = self.lookup_super_predicates(trait_def_id);
|
||||
predicates
|
||||
.predicates
|
||||
.into_iter()
|
||||
.map(|predicate| predicate.subst_supertrait(tcx, &trait_ref))
|
||||
.map(|predicate| predicate.subst_supertrait(self, &trait_ref))
|
||||
.any(|predicate| {
|
||||
match predicate {
|
||||
ty::Predicate::Trait(ref data) => {
|
||||
@ -174,30 +166,27 @@ pub fn supertraits_reference_self<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
})
|
||||
}
|
||||
|
||||
fn trait_has_sized_self<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
trait_def_id: DefId)
|
||||
-> bool
|
||||
{
|
||||
let trait_def = tcx.lookup_trait_def(trait_def_id);
|
||||
let trait_predicates = tcx.lookup_predicates(trait_def_id);
|
||||
generics_require_sized_self(tcx, &trait_def.generics, &trait_predicates)
|
||||
fn trait_has_sized_self(&self, trait_def_id: DefId) -> bool {
|
||||
let trait_def = self.lookup_trait_def(trait_def_id);
|
||||
let trait_predicates = self.lookup_predicates(trait_def_id);
|
||||
self.generics_require_sized_self(&trait_def.generics, &trait_predicates)
|
||||
}
|
||||
|
||||
fn generics_require_sized_self<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
generics: &ty::Generics<'tcx>,
|
||||
predicates: &ty::GenericPredicates<'tcx>)
|
||||
-> bool
|
||||
fn generics_require_sized_self(&self,
|
||||
generics: &ty::Generics<'tcx>,
|
||||
predicates: &ty::GenericPredicates<'tcx>)
|
||||
-> bool
|
||||
{
|
||||
let sized_def_id = match tcx.lang_items.sized_trait() {
|
||||
let sized_def_id = match self.lang_items.sized_trait() {
|
||||
Some(def_id) => def_id,
|
||||
None => { return false; /* No Sized trait, can't require it! */ }
|
||||
};
|
||||
|
||||
// Search for a predicate like `Self : Sized` amongst the trait bounds.
|
||||
let free_substs = tcx.construct_free_substs(generics,
|
||||
tcx.region_maps.node_extent(ast::DUMMY_NODE_ID));
|
||||
let predicates = predicates.instantiate(tcx, &free_substs).predicates.into_vec();
|
||||
elaborate_predicates(tcx, predicates)
|
||||
let free_substs = self.construct_free_substs(generics,
|
||||
self.region_maps.node_extent(ast::DUMMY_NODE_ID));
|
||||
let predicates = predicates.instantiate(self, &free_substs).predicates.into_vec();
|
||||
elaborate_predicates(self, predicates)
|
||||
.any(|predicate| {
|
||||
match predicate {
|
||||
ty::Predicate::Trait(ref trait_pred) if trait_pred.def_id() == sized_def_id => {
|
||||
@ -219,40 +208,40 @@ fn generics_require_sized_self<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
}
|
||||
|
||||
/// Returns `Some(_)` if this method makes the containing trait not object safe.
|
||||
fn object_safety_violation_for_method<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
trait_def_id: DefId,
|
||||
method: &ty::Method<'tcx>)
|
||||
-> Option<MethodViolationCode>
|
||||
fn object_safety_violation_for_method(&self,
|
||||
trait_def_id: DefId,
|
||||
method: &ty::Method<'tcx>)
|
||||
-> Option<MethodViolationCode>
|
||||
{
|
||||
// Any method that has a `Self : Sized` requisite is otherwise
|
||||
// exempt from the regulations.
|
||||
if generics_require_sized_self(tcx, &method.generics, &method.predicates) {
|
||||
if self.generics_require_sized_self(&method.generics, &method.predicates) {
|
||||
return None;
|
||||
}
|
||||
|
||||
virtual_call_violation_for_method(tcx, trait_def_id, method)
|
||||
self.virtual_call_violation_for_method(trait_def_id, method)
|
||||
}
|
||||
|
||||
/// We say a method is *vtable safe* if it can be invoked on a trait
|
||||
/// object. Note that object-safe traits can have some
|
||||
/// non-vtable-safe methods, so long as they require `Self:Sized` or
|
||||
/// otherwise ensure that they cannot be used when `Self=Trait`.
|
||||
pub fn is_vtable_safe_method<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
trait_def_id: DefId,
|
||||
method: &ty::Method<'tcx>)
|
||||
-> bool
|
||||
pub fn is_vtable_safe_method(&self,
|
||||
trait_def_id: DefId,
|
||||
method: &ty::Method<'tcx>)
|
||||
-> bool
|
||||
{
|
||||
virtual_call_violation_for_method(tcx, trait_def_id, method).is_none()
|
||||
self.virtual_call_violation_for_method(trait_def_id, method).is_none()
|
||||
}
|
||||
|
||||
/// Returns `Some(_)` if this method cannot be called on a trait
|
||||
/// object; this does not necessarily imply that the enclosing trait
|
||||
/// is not object safe, because the method might have a where clause
|
||||
/// `Self:Sized`.
|
||||
fn virtual_call_violation_for_method<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
trait_def_id: DefId,
|
||||
method: &ty::Method<'tcx>)
|
||||
-> Option<MethodViolationCode>
|
||||
fn virtual_call_violation_for_method(&self,
|
||||
trait_def_id: DefId,
|
||||
method: &ty::Method<'tcx>)
|
||||
-> Option<MethodViolationCode>
|
||||
{
|
||||
// The method's first parameter must be something that derefs (or
|
||||
// autorefs) to `&self`. For now, we only accept `self`, `&self`
|
||||
@ -272,12 +261,12 @@ fn virtual_call_violation_for_method<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
// arguments or return type apart from the receiver.
|
||||
let ref sig = method.fty.sig;
|
||||
for &input_ty in &sig.0.inputs[1..] {
|
||||
if contains_illegal_self_type_reference(tcx, trait_def_id, input_ty) {
|
||||
if self.contains_illegal_self_type_reference(trait_def_id, input_ty) {
|
||||
return Some(MethodViolationCode::ReferencesSelf);
|
||||
}
|
||||
}
|
||||
if let ty::FnConverging(result_type) = sig.0.output {
|
||||
if contains_illegal_self_type_reference(tcx, trait_def_id, result_type) {
|
||||
if self.contains_illegal_self_type_reference(trait_def_id, result_type) {
|
||||
return Some(MethodViolationCode::ReferencesSelf);
|
||||
}
|
||||
}
|
||||
@ -290,10 +279,10 @@ fn virtual_call_violation_for_method<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
None
|
||||
}
|
||||
|
||||
fn contains_illegal_self_type_reference<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
trait_def_id: DefId,
|
||||
ty: Ty<'tcx>)
|
||||
-> bool
|
||||
fn contains_illegal_self_type_reference(&self,
|
||||
trait_def_id: DefId,
|
||||
ty: Ty<'tcx>)
|
||||
-> bool
|
||||
{
|
||||
// This is somewhat subtle. In general, we want to forbid
|
||||
// references to `Self` in the argument and return types,
|
||||
@ -351,9 +340,9 @@ fn contains_illegal_self_type_reference<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
|
||||
// Compute supertraits of current trait lazily.
|
||||
if supertraits.is_none() {
|
||||
let trait_def = tcx.lookup_trait_def(trait_def_id);
|
||||
let trait_def = self.lookup_trait_def(trait_def_id);
|
||||
let trait_ref = ty::Binder(trait_def.trait_ref.clone());
|
||||
supertraits = Some(traits::supertraits(tcx, trait_ref).collect());
|
||||
supertraits = Some(traits::supertraits(self, trait_ref).collect());
|
||||
}
|
||||
|
||||
// Determine whether the trait reference `Foo as
|
||||
@ -381,3 +370,4 @@ fn contains_illegal_self_type_reference<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
|
||||
error
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,6 @@
|
||||
//! Code for projecting associated types out of trait references.
|
||||
|
||||
use super::elaborate_predicates;
|
||||
use super::report_overflow_error;
|
||||
use super::specialization_graph;
|
||||
use super::translate_substs;
|
||||
use super::Obligation;
|
||||
@ -188,7 +187,7 @@ pub fn poly_project_and_unify_type<'cx,'tcx>(
|
||||
let skol_obligation = obligation.with(skol_predicate);
|
||||
match project_and_unify_type(selcx, &skol_obligation) {
|
||||
Ok(result) => {
|
||||
match infcx.leak_check(&skol_map, snapshot) {
|
||||
match infcx.leak_check(false, &skol_map, snapshot) {
|
||||
Ok(()) => Ok(infcx.plug_leaks(skol_map, snapshot, &result)),
|
||||
Err(e) => Err(MismatchedProjectionTypes { err: e }),
|
||||
}
|
||||
@ -231,7 +230,7 @@ fn project_and_unify_type<'cx,'tcx>(
|
||||
|
||||
let infcx = selcx.infcx();
|
||||
let origin = TypeOrigin::RelateOutputImplTypes(obligation.cause.span);
|
||||
match infer::mk_eqty(infcx, true, origin, normalized_ty, obligation.predicate.ty) {
|
||||
match infcx.eq_types(true, origin, normalized_ty, obligation.predicate.ty) {
|
||||
Ok(InferOk { obligations: inferred_obligations, .. }) => {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(inferred_obligations.is_empty());
|
||||
@ -262,11 +261,10 @@ fn consider_unification_despite_ambiguity<'cx,'tcx>(selcx: &mut SelectionContext
|
||||
let closure_typer = selcx.closure_typer();
|
||||
let closure_type = closure_typer.closure_type(closure_def_id, substs);
|
||||
let ty::Binder((_, ret_type)) =
|
||||
util::closure_trait_ref_and_return_type(infcx.tcx,
|
||||
def_id,
|
||||
self_ty,
|
||||
&closure_type.sig,
|
||||
util::TupleArgumentsFlag::No);
|
||||
infcx.tcx.closure_trait_ref_and_return_type(def_id,
|
||||
self_ty,
|
||||
&closure_type.sig,
|
||||
util::TupleArgumentsFlag::No);
|
||||
// We don't have to normalize the return type here - this is only
|
||||
// reached for TyClosure: Fn inputs where the closure kind is
|
||||
// still unknown, which should only occur in typeck where the
|
||||
@ -281,7 +279,7 @@ fn consider_unification_despite_ambiguity<'cx,'tcx>(selcx: &mut SelectionContext
|
||||
ret_type);
|
||||
let origin = TypeOrigin::RelateOutputImplTypes(obligation.cause.span);
|
||||
let obligation_ty = obligation.predicate.ty;
|
||||
match infer::mk_eqty(infcx, true, origin, obligation_ty, ret_type) {
|
||||
match infcx.eq_types(true, origin, obligation_ty, ret_type) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty());
|
||||
@ -578,7 +576,7 @@ fn project_type<'cx,'tcx>(
|
||||
let recursion_limit = selcx.tcx().sess.recursion_limit.get();
|
||||
if obligation.recursion_depth >= recursion_limit {
|
||||
debug!("project: overflow!");
|
||||
report_overflow_error(selcx.infcx(), &obligation, true);
|
||||
selcx.infcx().report_overflow_error(&obligation, true);
|
||||
}
|
||||
|
||||
let obligation_trait_ref =
|
||||
@ -1053,11 +1051,10 @@ fn confirm_callable_candidate<'cx,'tcx>(
|
||||
|
||||
// Note: we unwrap the binder here but re-create it below (1)
|
||||
let ty::Binder((trait_ref, ret_type)) =
|
||||
util::closure_trait_ref_and_return_type(tcx,
|
||||
fn_once_def_id,
|
||||
obligation.predicate.trait_ref.self_ty(),
|
||||
fn_sig,
|
||||
flag);
|
||||
tcx.closure_trait_ref_and_return_type(fn_once_def_id,
|
||||
obligation.predicate.trait_ref.self_ty(),
|
||||
fn_sig,
|
||||
flag);
|
||||
|
||||
let predicate = ty::Binder(ty::ProjectionPredicate { // (1) recreate binder here
|
||||
projection_ty: ty::ProjectionTy {
|
||||
|
@ -20,7 +20,6 @@ use super::DerivedObligationCause;
|
||||
use super::project;
|
||||
use super::project::{normalize_with_depth, Normalized};
|
||||
use super::{PredicateObligation, TraitObligation, ObligationCause};
|
||||
use super::report_overflow_error;
|
||||
use super::{ObligationCauseCode, BuiltinDerivedObligation, ImplDerivedObligation};
|
||||
use super::{SelectionError, Unimplemented, OutputTypeParameterMismatch};
|
||||
use super::{ObjectCastObligation, Obligation};
|
||||
@ -32,7 +31,6 @@ use super::{VtableBuiltin, VtableImpl, VtableParam, VtableClosure,
|
||||
VtableFnPointer, VtableObject, VtableDefaultImpl};
|
||||
use super::{VtableImplData, VtableObjectData, VtableBuiltinData,
|
||||
VtableClosureData, VtableDefaultImplData};
|
||||
use super::object_safety;
|
||||
use super::util;
|
||||
|
||||
use hir::def_id::DefId;
|
||||
@ -455,7 +453,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
}
|
||||
|
||||
ty::Predicate::ObjectSafe(trait_def_id) => {
|
||||
if object_safety::is_object_safe(self.tcx(), trait_def_id) {
|
||||
if self.tcx().is_object_safe(trait_def_id) {
|
||||
EvaluatedToOk
|
||||
} else {
|
||||
EvaluatedToErr
|
||||
@ -683,7 +681,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
// not update) the cache.
|
||||
let recursion_limit = self.infcx.tcx.sess.recursion_limit.get();
|
||||
if stack.obligation.recursion_depth >= recursion_limit {
|
||||
report_overflow_error(self.infcx(), &stack.obligation, true);
|
||||
self.infcx().report_overflow_error(&stack.obligation, true);
|
||||
}
|
||||
|
||||
// Check the cache. Note that we skolemize the trait-ref
|
||||
@ -1155,7 +1153,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
Err(_) => { return false; }
|
||||
}
|
||||
|
||||
self.infcx.leak_check(skol_map, snapshot).is_ok()
|
||||
self.infcx.leak_check(false, skol_map, snapshot).is_ok()
|
||||
}
|
||||
|
||||
/// Given an obligation like `<SomeTrait for T>`, search the obligations that the caller
|
||||
@ -1397,7 +1395,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
// these cases wind up being considered ambiguous due to a
|
||||
// (spurious) ambiguity introduced here.
|
||||
let predicate_trait_ref = obligation.predicate.to_poly_trait_ref();
|
||||
if !object_safety::is_object_safe(self.tcx(), predicate_trait_ref.def_id()) {
|
||||
if !self.tcx().is_object_safe(predicate_trait_ref.def_id()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1855,7 +1853,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
recursion_depth,
|
||||
&skol_ty);
|
||||
let skol_obligation =
|
||||
util::predicate_for_trait_def(self.tcx(),
|
||||
self.tcx().predicate_for_trait_def(
|
||||
cause.clone(),
|
||||
trait_def_id,
|
||||
recursion_depth,
|
||||
@ -2226,7 +2224,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
// entries, so that we can compute the offset for the selected
|
||||
// trait.
|
||||
vtable_base =
|
||||
nonmatching.map(|t| util::count_own_vtable_entries(self.tcx(), t))
|
||||
nonmatching.map(|t| self.tcx().count_own_vtable_entries(t))
|
||||
.sum();
|
||||
|
||||
}
|
||||
@ -2248,11 +2246,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
|
||||
let sig = self_ty.fn_sig();
|
||||
let trait_ref =
|
||||
util::closure_trait_ref_and_return_type(self.tcx(),
|
||||
obligation.predicate.def_id(),
|
||||
self_ty,
|
||||
sig,
|
||||
util::TupleArgumentsFlag::Yes)
|
||||
self.tcx().closure_trait_ref_and_return_type(obligation.predicate.def_id(),
|
||||
self_ty,
|
||||
sig,
|
||||
util::TupleArgumentsFlag::Yes)
|
||||
.map_bound(|(trait_ref, _)| trait_ref);
|
||||
|
||||
self.confirm_poly_trait_refs(obligation.cause.clone(),
|
||||
@ -2396,7 +2393,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
// })
|
||||
// .chain(Some(data.principal_def_id()));
|
||||
if let Some(did) = object_dids.find(|did| {
|
||||
!object_safety::is_object_safe(tcx, *did)
|
||||
!tcx.is_object_safe(*did)
|
||||
}) {
|
||||
return Err(TraitNotObjectSafe(did))
|
||||
}
|
||||
@ -2422,7 +2419,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
// object type is Foo+Send, this would create an obligation
|
||||
// for the Send check.)
|
||||
for bound in &builtin_bounds {
|
||||
if let Ok(tr) = util::trait_ref_for_builtin_bound(tcx, bound, source) {
|
||||
if let Ok(tr) = tcx.trait_ref_for_builtin_bound(bound, source) {
|
||||
push(tr.to_predicate());
|
||||
} else {
|
||||
return Err(Unimplemented);
|
||||
@ -2511,7 +2508,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
assert!(obligations.is_empty());
|
||||
|
||||
// Construct the nested Field<T>: Unsize<Field<U>> predicate.
|
||||
nested.push(util::predicate_for_trait_def(tcx,
|
||||
nested.push(tcx.predicate_for_trait_def(
|
||||
obligation.cause.clone(),
|
||||
obligation.predicate.def_id(),
|
||||
obligation.recursion_depth + 1,
|
||||
@ -2605,7 +2602,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty());
|
||||
|
||||
if let Err(e) = self.infcx.leak_check(&skol_map, snapshot) {
|
||||
if let Err(e) = self.infcx.leak_check(false, &skol_map, snapshot) {
|
||||
debug!("match_impl: failed leak check due to `{}`", e);
|
||||
return Err(());
|
||||
}
|
||||
@ -2710,11 +2707,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
{
|
||||
let closure_type = self.infcx.closure_type(closure_def_id, substs);
|
||||
let ty::Binder((trait_ref, _)) =
|
||||
util::closure_trait_ref_and_return_type(self.tcx(),
|
||||
obligation.predicate.def_id(),
|
||||
obligation.predicate.0.self_ty(), // (1)
|
||||
&closure_type.sig,
|
||||
util::TupleArgumentsFlag::No);
|
||||
self.tcx().closure_trait_ref_and_return_type(obligation.predicate.def_id(),
|
||||
obligation.predicate.0.self_ty(), // (1)
|
||||
&closure_type.sig,
|
||||
util::TupleArgumentsFlag::No);
|
||||
// (1) Feels icky to skip the binder here, but OTOH we know
|
||||
// that the self-type is an unboxed closure type and hence is
|
||||
// in fact unparameterized (or at least does not reference any
|
||||
|
@ -21,7 +21,7 @@ use super::{SelectionContext, FulfillmentContext};
|
||||
use super::util::{fresh_type_vars_for_impl, impl_trait_ref_and_oblig};
|
||||
|
||||
use hir::def_id::DefId;
|
||||
use infer::{self, InferCtxt, TypeOrigin};
|
||||
use infer::{InferCtxt, TypeOrigin};
|
||||
use middle::region;
|
||||
use ty::subst::{Subst, Substs};
|
||||
use traits::{self, ProjectionMode, ObligationCause, Normalized};
|
||||
@ -177,11 +177,10 @@ fn fulfill_implication<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
&target_substs);
|
||||
|
||||
// do the impls unify? If not, no specialization.
|
||||
if let Err(_) = infer::mk_eq_trait_refs(&infcx,
|
||||
true,
|
||||
TypeOrigin::Misc(DUMMY_SP),
|
||||
source_trait_ref,
|
||||
target_trait_ref) {
|
||||
if let Err(_) = infcx.eq_trait_refs(true,
|
||||
TypeOrigin::Misc(DUMMY_SP),
|
||||
source_trait_ref,
|
||||
target_trait_ref) {
|
||||
debug!("fulfill_implication: {:?} does not unify with {:?}",
|
||||
source_trait_ref,
|
||||
target_trait_ref);
|
||||
@ -196,7 +195,7 @@ fn fulfill_implication<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
fulfill_cx.register_predicate_obligation(&infcx, oblig);
|
||||
}
|
||||
|
||||
if let Err(errors) = infer::drain_fulfillment_cx(&infcx, &mut fulfill_cx, &()) {
|
||||
if let Err(errors) = infcx.drain_fulfillment_cx(&mut fulfill_cx, &()) {
|
||||
// no dice!
|
||||
debug!("fulfill_implication: for impls on {:?} and {:?}, could not fulfill: {:?} given \
|
||||
{:?}",
|
||||
|
@ -378,26 +378,6 @@ pub fn predicates_for_generics<'tcx>(cause: ObligationCause<'tcx>,
|
||||
}).collect()
|
||||
}
|
||||
|
||||
pub fn trait_ref_for_builtin_bound<'tcx>(
|
||||
tcx: &TyCtxt<'tcx>,
|
||||
builtin_bound: ty::BuiltinBound,
|
||||
param_ty: Ty<'tcx>)
|
||||
-> Result<ty::TraitRef<'tcx>, ErrorReported>
|
||||
{
|
||||
match tcx.lang_items.from_builtin_kind(builtin_bound) {
|
||||
Ok(def_id) => {
|
||||
Ok(ty::TraitRef {
|
||||
def_id: def_id,
|
||||
substs: tcx.mk_substs(Substs::empty().with_self_ty(param_ty))
|
||||
})
|
||||
}
|
||||
Err(e) => {
|
||||
tcx.sess.err(&e);
|
||||
Err(ErrorReported)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn predicate_for_trait_ref<'tcx>(
|
||||
cause: ObligationCause<'tcx>,
|
||||
trait_ref: ty::TraitRef<'tcx>,
|
||||
@ -411,8 +391,27 @@ pub fn predicate_for_trait_ref<'tcx>(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn predicate_for_trait_def<'tcx>(
|
||||
tcx: &TyCtxt<'tcx>,
|
||||
impl<'tcx> TyCtxt<'tcx> {
|
||||
pub fn trait_ref_for_builtin_bound(&self,
|
||||
builtin_bound: ty::BuiltinBound,
|
||||
param_ty: Ty<'tcx>)
|
||||
-> Result<ty::TraitRef<'tcx>, ErrorReported>
|
||||
{
|
||||
match self.lang_items.from_builtin_kind(builtin_bound) {
|
||||
Ok(def_id) => {
|
||||
Ok(ty::TraitRef {
|
||||
def_id: def_id,
|
||||
substs: self.mk_substs(Substs::empty().with_self_ty(param_ty))
|
||||
})
|
||||
}
|
||||
Err(e) => {
|
||||
self.sess.err(&e);
|
||||
Err(ErrorReported)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn predicate_for_trait_def(&self,
|
||||
cause: ObligationCause<'tcx>,
|
||||
trait_def_id: DefId,
|
||||
recursion_depth: usize,
|
||||
@ -422,36 +421,35 @@ pub fn predicate_for_trait_def<'tcx>(
|
||||
{
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: trait_def_id,
|
||||
substs: tcx.mk_substs(Substs::new_trait(ty_params, vec![], param_ty))
|
||||
substs: self.mk_substs(Substs::new_trait(ty_params, vec![], param_ty))
|
||||
};
|
||||
predicate_for_trait_ref(cause, trait_ref, recursion_depth)
|
||||
}
|
||||
|
||||
pub fn predicate_for_builtin_bound<'tcx>(
|
||||
tcx: &TyCtxt<'tcx>,
|
||||
pub fn predicate_for_builtin_bound(&self,
|
||||
cause: ObligationCause<'tcx>,
|
||||
builtin_bound: ty::BuiltinBound,
|
||||
recursion_depth: usize,
|
||||
param_ty: Ty<'tcx>)
|
||||
-> Result<PredicateObligation<'tcx>, ErrorReported>
|
||||
{
|
||||
let trait_ref = trait_ref_for_builtin_bound(tcx, builtin_bound, param_ty)?;
|
||||
let trait_ref = self.trait_ref_for_builtin_bound(builtin_bound, param_ty)?;
|
||||
Ok(predicate_for_trait_ref(cause, trait_ref, recursion_depth))
|
||||
}
|
||||
|
||||
/// Cast a trait reference into a reference to one of its super
|
||||
/// traits; returns `None` if `target_trait_def_id` is not a
|
||||
/// supertrait.
|
||||
pub fn upcast<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
source_trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
target_trait_def_id: DefId)
|
||||
-> Vec<ty::PolyTraitRef<'tcx>>
|
||||
pub fn upcast_choices(&self,
|
||||
source_trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
target_trait_def_id: DefId)
|
||||
-> Vec<ty::PolyTraitRef<'tcx>>
|
||||
{
|
||||
if source_trait_ref.def_id() == target_trait_def_id {
|
||||
return vec![source_trait_ref]; // shorcut the most common case
|
||||
}
|
||||
|
||||
supertraits(tcx, source_trait_ref)
|
||||
supertraits(self, source_trait_ref)
|
||||
.filter(|r| r.def_id() == target_trait_def_id)
|
||||
.collect()
|
||||
}
|
||||
@ -459,13 +457,11 @@ pub fn upcast<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
/// Given a trait `trait_ref`, returns the number of vtable entries
|
||||
/// that come from `trait_ref`, excluding its supertraits. Used in
|
||||
/// computing the vtable base for an upcast trait of a trait object.
|
||||
pub fn count_own_vtable_entries<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>)
|
||||
-> usize {
|
||||
pub fn count_own_vtable_entries(&self, trait_ref: ty::PolyTraitRef<'tcx>) -> usize {
|
||||
let mut entries = 0;
|
||||
// Count number of methods and add them to the total offset.
|
||||
// Skip over associated types and constants.
|
||||
for trait_item in &tcx.trait_items(trait_ref.def_id())[..] {
|
||||
for trait_item in &self.trait_items(trait_ref.def_id())[..] {
|
||||
if let ty::MethodTraitItem(_) = *trait_item {
|
||||
entries += 1;
|
||||
}
|
||||
@ -476,14 +472,14 @@ pub fn count_own_vtable_entries<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
/// Given an upcast trait object described by `object`, returns the
|
||||
/// index of the method `method_def_id` (which should be part of
|
||||
/// `object.upcast_trait_ref`) within the vtable for `object`.
|
||||
pub fn get_vtable_index_of_object_method<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
object: &super::VtableObjectData<'tcx>,
|
||||
method_def_id: DefId) -> usize {
|
||||
pub fn get_vtable_index_of_object_method(&self,
|
||||
object: &super::VtableObjectData<'tcx>,
|
||||
method_def_id: DefId) -> usize {
|
||||
// Count number of methods preceding the one we are selecting and
|
||||
// add them to the total offset.
|
||||
// Skip over associated types and constants.
|
||||
let mut entries = object.vtable_base;
|
||||
for trait_item in &tcx.trait_items(object.upcast_trait_ref.def_id())[..] {
|
||||
for trait_item in &self.trait_items(object.upcast_trait_ref.def_id())[..] {
|
||||
if trait_item.def_id() == method_def_id {
|
||||
// The item with the ID we were given really ought to be a method.
|
||||
assert!(match *trait_item {
|
||||
@ -502,10 +498,7 @@ pub fn get_vtable_index_of_object_method<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
method_def_id);
|
||||
}
|
||||
|
||||
pub enum TupleArgumentsFlag { Yes, No }
|
||||
|
||||
pub fn closure_trait_ref_and_return_type<'tcx>(
|
||||
tcx: &TyCtxt<'tcx>,
|
||||
pub fn closure_trait_ref_and_return_type(&self,
|
||||
fn_trait_def_id: DefId,
|
||||
self_ty: Ty<'tcx>,
|
||||
sig: &ty::PolyFnSig<'tcx>,
|
||||
@ -514,12 +507,15 @@ pub fn closure_trait_ref_and_return_type<'tcx>(
|
||||
{
|
||||
let arguments_tuple = match tuple_arguments {
|
||||
TupleArgumentsFlag::No => sig.0.inputs[0],
|
||||
TupleArgumentsFlag::Yes => tcx.mk_tup(sig.0.inputs.to_vec()),
|
||||
TupleArgumentsFlag::Yes => self.mk_tup(sig.0.inputs.to_vec()),
|
||||
};
|
||||
let trait_substs = Substs::new_trait(vec![arguments_tuple], vec![], self_ty);
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: fn_trait_def_id,
|
||||
substs: tcx.mk_substs(trait_substs),
|
||||
substs: self.mk_substs(trait_substs),
|
||||
};
|
||||
ty::Binder((trait_ref, sig.0.output.unwrap_or(tcx.mk_nil())))
|
||||
ty::Binder((trait_ref, sig.0.output.unwrap_or(self.mk_nil())))
|
||||
}
|
||||
}
|
||||
|
||||
pub enum TupleArgumentsFlag { Yes, No }
|
||||
|
@ -12,7 +12,7 @@ pub use self::Integer::*;
|
||||
pub use self::Layout::*;
|
||||
pub use self::Primitive::*;
|
||||
|
||||
use infer::{InferCtxt, drain_fulfillment_cx_or_panic};
|
||||
use infer::InferCtxt;
|
||||
use session::Session;
|
||||
use traits;
|
||||
use ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||
@ -754,7 +754,7 @@ fn normalize_associated_type<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
fulfill_cx.register_predicate_obligation(infcx, obligation);
|
||||
}
|
||||
|
||||
drain_fulfillment_cx_or_panic(DUMMY_SP, infcx, &mut fulfill_cx, &result)
|
||||
infcx.drain_fulfillment_cx_or_panic(DUMMY_SP, &mut fulfill_cx, &result)
|
||||
}
|
||||
|
||||
impl Layout {
|
||||
|
@ -55,20 +55,18 @@ pub enum Component<'tcx> {
|
||||
EscapingProjection(Vec<Component<'tcx>>),
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
/// Returns all the things that must outlive `'a` for the condition
|
||||
/// `ty0: 'a` to hold.
|
||||
pub fn components<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
|
||||
ty0: Ty<'tcx>)
|
||||
pub fn outlives_components(&self, ty0: Ty<'tcx>)
|
||||
-> Vec<Component<'tcx>> {
|
||||
let mut components = vec![];
|
||||
compute_components(infcx, ty0, &mut components);
|
||||
self.compute_components(ty0, &mut components);
|
||||
debug!("components({:?}) = {:?}", ty0, components);
|
||||
components
|
||||
}
|
||||
|
||||
fn compute_components<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
out: &mut Vec<Component<'tcx>>) {
|
||||
fn compute_components(&self, ty: Ty<'tcx>, out: &mut Vec<Component<'tcx>>) {
|
||||
// Descend through the types, looking for the various "base"
|
||||
// components and collecting them into `out`. This is not written
|
||||
// with `collect()` because of the need to sometimes skip subtrees
|
||||
@ -114,7 +112,7 @@ fn compute_components<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
|
||||
// taking into consideration UFCS and so forth.
|
||||
|
||||
for &upvar_ty in &substs.upvar_tys {
|
||||
compute_components(infcx, upvar_ty, out);
|
||||
self.compute_components(upvar_ty, out);
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,7 +143,7 @@ fn compute_components<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
|
||||
// fallback case: hard code
|
||||
// OutlivesProjectionComponents. Continue walking
|
||||
// through and constrain Pi.
|
||||
let subcomponents = capture_components(infcx, ty);
|
||||
let subcomponents = self.capture_components(ty);
|
||||
out.push(Component::EscapingProjection(subcomponents));
|
||||
}
|
||||
}
|
||||
@ -154,11 +152,11 @@ fn compute_components<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
|
||||
// and proceed with resolved version. If we cannot resolve it,
|
||||
// then record the unresolved variable as a component.
|
||||
ty::TyInfer(_) => {
|
||||
let ty = infcx.resolve_type_vars_if_possible(&ty);
|
||||
let ty = self.resolve_type_vars_if_possible(&ty);
|
||||
if let ty::TyInfer(infer_ty) = ty.sty {
|
||||
out.push(Component::UnresolvedInferenceVariable(infer_ty));
|
||||
} else {
|
||||
compute_components(infcx, ty, out);
|
||||
self.compute_components(ty, out);
|
||||
}
|
||||
}
|
||||
|
||||
@ -194,22 +192,21 @@ fn compute_components<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
|
||||
|
||||
push_region_constraints(out, ty.regions());
|
||||
for subty in ty.walk_shallow() {
|
||||
compute_components(infcx, subty, out);
|
||||
self.compute_components(subty, out);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn capture_components<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
|
||||
ty: Ty<'tcx>)
|
||||
-> Vec<Component<'tcx>> {
|
||||
fn capture_components(&self, ty: Ty<'tcx>) -> Vec<Component<'tcx>> {
|
||||
let mut temp = vec![];
|
||||
push_region_constraints(&mut temp, ty.regions());
|
||||
for subty in ty.walk_shallow() {
|
||||
compute_components(infcx, subty, &mut temp);
|
||||
self.compute_components(subty, &mut temp);
|
||||
}
|
||||
temp
|
||||
}
|
||||
}
|
||||
|
||||
fn push_region_constraints<'tcx>(out: &mut Vec<Component<'tcx>>, regions: Vec<ty::Region>) {
|
||||
for r in regions {
|
||||
|
@ -14,7 +14,6 @@ use middle::cstore;
|
||||
use hir::def_id::DefId;
|
||||
use middle::region;
|
||||
use ty::subst::{self, Substs};
|
||||
use traits;
|
||||
use ty::{self, AdtDef, ToPredicate, TypeFlags, Ty, TyCtxt, TyS, TypeFoldable};
|
||||
use util::common::ErrorReported;
|
||||
|
||||
@ -633,7 +632,7 @@ pub struct DebruijnIndex {
|
||||
/// to be used. These also support explicit bounds: both the internally-stored
|
||||
/// *scope*, which the region is assumed to outlive, as well as other
|
||||
/// relations stored in the `FreeRegionMap`. Note that these relations
|
||||
/// aren't checked when you `make_subregion` (or `mk_eqty`), only by
|
||||
/// aren't checked when you `make_subregion` (or `eq_types`), only by
|
||||
/// `resolve_regions_and_report_errors`.
|
||||
///
|
||||
/// When working with higher-ranked types, some region relations aren't
|
||||
@ -778,7 +777,7 @@ impl BuiltinBounds {
|
||||
tcx: &TyCtxt<'tcx>,
|
||||
self_ty: Ty<'tcx>) -> Vec<ty::Predicate<'tcx>> {
|
||||
self.iter().filter_map(|builtin_bound|
|
||||
match traits::trait_ref_for_builtin_bound(tcx, builtin_bound, self_ty) {
|
||||
match tcx.trait_ref_for_builtin_bound(builtin_bound, self_ty) {
|
||||
Ok(trait_ref) => Some(trait_ref.to_predicate()),
|
||||
Err(ErrorReported) => { None }
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
use hir::def_id::DefId;
|
||||
use infer::InferCtxt;
|
||||
use ty::outlives::{self, Component};
|
||||
use ty::outlives::Component;
|
||||
use ty::subst::Substs;
|
||||
use traits;
|
||||
use ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable};
|
||||
@ -182,7 +182,7 @@ pub fn implied_bounds<'a,'tcx>(
|
||||
match infcx.tcx.no_late_bound_regions(data) {
|
||||
None => vec![],
|
||||
Some(ty::OutlivesPredicate(ty_a, r_b)) => {
|
||||
let components = outlives::components(infcx, ty_a);
|
||||
let components = infcx.outlives_components(ty_a);
|
||||
implied_bounds_from_components(r_b, components)
|
||||
}
|
||||
},
|
||||
@ -288,9 +288,7 @@ impl<'a,'tcx> WfPredicates<'a,'tcx> {
|
||||
rfc1592: bool) {
|
||||
if !subty.has_escaping_regions() {
|
||||
let cause = self.cause(cause);
|
||||
match traits::trait_ref_for_builtin_bound(self.infcx.tcx,
|
||||
ty::BoundSized,
|
||||
subty) {
|
||||
match self.infcx.tcx.trait_ref_for_builtin_bound(ty::BoundSized, subty) {
|
||||
Ok(trait_ref) => {
|
||||
let predicate = trait_ref.to_predicate();
|
||||
let predicate = if rfc1592 {
|
||||
|
@ -26,7 +26,6 @@ use rustc::hir::pat_util::def_to_path;
|
||||
use rustc::ty::{self, Ty, TyCtxt, subst};
|
||||
use rustc::ty::util::IntTypeExt;
|
||||
use rustc::traits::ProjectionMode;
|
||||
use rustc::middle::astconv_util::ast_ty_to_prim_ty;
|
||||
use rustc::util::nodemap::NodeMap;
|
||||
use rustc::lint;
|
||||
|
||||
@ -100,7 +99,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
|
||||
None => None,
|
||||
Some(ast_map::NodeItem(it)) => match it.node {
|
||||
hir::ItemConst(ref ty, ref const_expr) => {
|
||||
Some((&const_expr, ast_ty_to_prim_ty(tcx, ty)))
|
||||
Some((&const_expr, tcx.ast_ty_to_prim_ty(ty)))
|
||||
}
|
||||
_ => None
|
||||
},
|
||||
@ -126,7 +125,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
|
||||
},
|
||||
Some(ast_map::NodeImplItem(ii)) => match ii.node {
|
||||
hir::ImplItemKind::Const(ref ty, ref expr) => {
|
||||
Some((&expr, ast_ty_to_prim_ty(tcx, ty)))
|
||||
Some((&expr, tcx.ast_ty_to_prim_ty(ty)))
|
||||
}
|
||||
_ => None
|
||||
},
|
||||
@ -144,7 +143,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
|
||||
let expr_ty = match tcx.sess.cstore.maybe_get_item_ast(tcx, def_id) {
|
||||
cstore::FoundAst::Found(&InlinedItem::Item(ref item)) => match item.node {
|
||||
hir::ItemConst(ref ty, ref const_expr) => {
|
||||
Some((&**const_expr, ast_ty_to_prim_ty(tcx, ty)))
|
||||
Some((&**const_expr, tcx.ast_ty_to_prim_ty(ty)))
|
||||
},
|
||||
_ => None
|
||||
},
|
||||
@ -165,7 +164,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
|
||||
},
|
||||
cstore::FoundAst::Found(&InlinedItem::ImplItem(_, ref ii)) => match ii.node {
|
||||
hir::ImplItemKind::Const(ref ty, ref expr) => {
|
||||
Some((&**expr, ast_ty_to_prim_ty(tcx, ty)))
|
||||
Some((&**expr, tcx.ast_ty_to_prim_ty(ty)))
|
||||
},
|
||||
_ => None
|
||||
},
|
||||
@ -679,7 +678,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
}
|
||||
}
|
||||
hir::ExprCast(ref base, ref target_ty) => {
|
||||
let ety = ast_ty_to_prim_ty(tcx, &target_ty).or_else(|| ety)
|
||||
let ety = tcx.ast_ty_to_prim_ty(&target_ty).or(ety)
|
||||
.unwrap_or_else(|| {
|
||||
tcx.sess.span_fatal(target_ty.span,
|
||||
"target type not found for const cast")
|
||||
@ -1041,7 +1040,7 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
|
||||
Some(ic) => lookup_const_by_id(tcx, ic.def_id, None),
|
||||
None => match ti.node {
|
||||
hir::ConstTraitItem(ref ty, Some(ref expr)) => {
|
||||
Some((&*expr, ast_ty_to_prim_ty(tcx, ty)))
|
||||
Some((&*expr, tcx.ast_ty_to_prim_ty(ty)))
|
||||
},
|
||||
_ => None,
|
||||
},
|
||||
|
@ -242,17 +242,14 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn make_subtype(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
|
||||
match infer::mk_subty(self.infcx, true, TypeOrigin::Misc(DUMMY_SP), a, b) {
|
||||
match self.infcx.sub_types(true, TypeOrigin::Misc(DUMMY_SP), a, b) {
|
||||
Ok(_) => true,
|
||||
Err(ref e) => panic!("Encountered error: {}", e),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_subtype(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
|
||||
match infer::can_mk_subty(self.infcx, a, b) {
|
||||
Ok(_) => true,
|
||||
Err(_) => false,
|
||||
}
|
||||
self.infcx.can_sub_types(a, b).is_ok()
|
||||
}
|
||||
|
||||
pub fn assert_subtype(&self, a: Ty<'tcx>, b: Ty<'tcx>) {
|
||||
|
@ -25,7 +25,6 @@ use middle::cstore::{LOCAL_CRATE, InlinedItemRef, LinkMeta, tls};
|
||||
use rustc::hir::def;
|
||||
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
|
||||
use middle::dependency_format::Linkage;
|
||||
use middle::stability;
|
||||
use rustc::ty::subst;
|
||||
use rustc::traits::specialization_graph;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
@ -283,8 +282,8 @@ fn encode_enum_variant_info<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
|
||||
encode_attributes(rbml_w, &attrs);
|
||||
encode_repr_attrs(rbml_w, ecx, &attrs);
|
||||
|
||||
let stab = stability::lookup_stability(ecx.tcx, vid);
|
||||
let depr = stability::lookup_deprecation(ecx.tcx, vid);
|
||||
let stab = ecx.tcx.lookup_stability(vid);
|
||||
let depr = ecx.tcx.lookup_deprecation(vid);
|
||||
encode_stability(rbml_w, stab);
|
||||
encode_deprecation(rbml_w, depr);
|
||||
|
||||
@ -376,8 +375,8 @@ fn encode_info_for_mod(ecx: &EncodeContext,
|
||||
|
||||
encode_visibility(rbml_w, vis);
|
||||
|
||||
let stab = stability::lookup_stability(ecx.tcx, ecx.tcx.map.local_def_id(id));
|
||||
let depr = stability::lookup_deprecation(ecx.tcx, ecx.tcx.map.local_def_id(id));
|
||||
let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(id));
|
||||
let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(id));
|
||||
encode_stability(rbml_w, stab);
|
||||
encode_deprecation(rbml_w, depr);
|
||||
|
||||
@ -484,8 +483,8 @@ fn encode_field<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
|
||||
encode_bounds_and_type_for_item(rbml_w, ecx, index, id);
|
||||
encode_def_id_and_key(ecx, rbml_w, field.did);
|
||||
|
||||
let stab = stability::lookup_stability(ecx.tcx, field.did);
|
||||
let depr = stability::lookup_deprecation(ecx.tcx, field.did);
|
||||
let stab = ecx.tcx.lookup_stability(field.did);
|
||||
let depr = ecx.tcx.lookup_deprecation(field.did);
|
||||
encode_stability(rbml_w, stab);
|
||||
encode_deprecation(rbml_w, depr);
|
||||
|
||||
@ -517,8 +516,8 @@ fn encode_info_for_struct_ctor<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
|
||||
encode_symbol(ecx, rbml_w, ctor_id);
|
||||
}
|
||||
|
||||
let stab = stability::lookup_stability(ecx.tcx, ecx.tcx.map.local_def_id(ctor_id));
|
||||
let depr= stability::lookup_deprecation(ecx.tcx, ecx.tcx.map.local_def_id(ctor_id));
|
||||
let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(ctor_id));
|
||||
let depr= ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(ctor_id));
|
||||
encode_stability(rbml_w, stab);
|
||||
encode_deprecation(rbml_w, depr);
|
||||
|
||||
@ -646,8 +645,8 @@ fn encode_info_for_associated_const<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
|
||||
encode_bounds_and_type_for_item(rbml_w, ecx, index,
|
||||
ecx.local_id(associated_const.def_id));
|
||||
|
||||
let stab = stability::lookup_stability(ecx.tcx, associated_const.def_id);
|
||||
let depr = stability::lookup_deprecation(ecx.tcx, associated_const.def_id);
|
||||
let stab = ecx.tcx.lookup_stability(associated_const.def_id);
|
||||
let depr = ecx.tcx.lookup_deprecation(associated_const.def_id);
|
||||
encode_stability(rbml_w, stab);
|
||||
encode_deprecation(rbml_w, depr);
|
||||
|
||||
@ -681,8 +680,8 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
|
||||
encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id));
|
||||
encode_item_sort(rbml_w, 'r');
|
||||
|
||||
let stab = stability::lookup_stability(ecx.tcx, m.def_id);
|
||||
let depr = stability::lookup_deprecation(ecx.tcx, m.def_id);
|
||||
let stab = ecx.tcx.lookup_stability(m.def_id);
|
||||
let depr = ecx.tcx.lookup_deprecation(m.def_id);
|
||||
encode_stability(rbml_w, stab);
|
||||
encode_deprecation(rbml_w, depr);
|
||||
|
||||
@ -736,8 +735,8 @@ fn encode_info_for_associated_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
|
||||
encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id));
|
||||
encode_item_sort(rbml_w, 't');
|
||||
|
||||
let stab = stability::lookup_stability(ecx.tcx, associated_type.def_id);
|
||||
let depr = stability::lookup_deprecation(ecx.tcx, associated_type.def_id);
|
||||
let stab = ecx.tcx.lookup_stability(associated_type.def_id);
|
||||
let depr = ecx.tcx.lookup_deprecation(associated_type.def_id);
|
||||
encode_stability(rbml_w, stab);
|
||||
encode_deprecation(rbml_w, depr);
|
||||
|
||||
@ -872,8 +871,8 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
|
||||
|
||||
let vis = &item.vis;
|
||||
let def_id = ecx.tcx.map.local_def_id(item.id);
|
||||
let stab = stability::lookup_stability(tcx, ecx.tcx.map.local_def_id(item.id));
|
||||
let depr = stability::lookup_deprecation(tcx, ecx.tcx.map.local_def_id(item.id));
|
||||
let stab = tcx.lookup_stability(ecx.tcx.map.local_def_id(item.id));
|
||||
let depr = tcx.lookup_deprecation(ecx.tcx.map.local_def_id(item.id));
|
||||
|
||||
match item.node {
|
||||
hir::ItemStatic(_, m, _) => {
|
||||
@ -1231,8 +1230,8 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
|
||||
|
||||
encode_parent_item(rbml_w, def_id);
|
||||
|
||||
let stab = stability::lookup_stability(tcx, item_def_id.def_id());
|
||||
let depr = stability::lookup_deprecation(tcx, item_def_id.def_id());
|
||||
let stab = tcx.lookup_stability(item_def_id.def_id());
|
||||
let depr = tcx.lookup_deprecation(item_def_id.def_id());
|
||||
encode_stability(rbml_w, stab);
|
||||
encode_deprecation(rbml_w, depr);
|
||||
|
||||
@ -1358,8 +1357,8 @@ fn encode_info_for_foreign_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
|
||||
encode_symbol(ecx, rbml_w, nitem.id);
|
||||
}
|
||||
encode_attributes(rbml_w, &nitem.attrs);
|
||||
let stab = stability::lookup_stability(ecx.tcx, ecx.tcx.map.local_def_id(nitem.id));
|
||||
let depr = stability::lookup_deprecation(ecx.tcx, ecx.tcx.map.local_def_id(nitem.id));
|
||||
let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(nitem.id));
|
||||
let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(nitem.id));
|
||||
encode_stability(rbml_w, stab);
|
||||
encode_deprecation(rbml_w, depr);
|
||||
encode_method_argument_names(rbml_w, &fndecl);
|
||||
@ -1372,8 +1371,8 @@ fn encode_info_for_foreign_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
|
||||
}
|
||||
encode_bounds_and_type_for_item(rbml_w, ecx, index, nitem.id);
|
||||
encode_attributes(rbml_w, &nitem.attrs);
|
||||
let stab = stability::lookup_stability(ecx.tcx, ecx.tcx.map.local_def_id(nitem.id));
|
||||
let depr = stability::lookup_deprecation(ecx.tcx, ecx.tcx.map.local_def_id(nitem.id));
|
||||
let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(nitem.id));
|
||||
let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(nitem.id));
|
||||
encode_stability(rbml_w, stab);
|
||||
encode_deprecation(rbml_w, depr);
|
||||
encode_symbol(ecx, rbml_w, nitem.id);
|
||||
|
@ -202,10 +202,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn closure_self_ty<'a, 'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
closure_expr_id: ast::NodeId,
|
||||
body_id: ast::NodeId)
|
||||
-> Ty<'tcx> {
|
||||
fn closure_self_ty<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
closure_expr_id: ast::NodeId,
|
||||
body_id: ast::NodeId)
|
||||
-> Ty<'tcx> {
|
||||
let closure_ty = tcx.node_id_to_type(closure_expr_id);
|
||||
|
||||
// We're just hard-coding the idea that the signature will be
|
||||
|
@ -1023,11 +1023,11 @@ impl<'tcx> MirMapPass<'tcx> for QualifyAndPromoteConstants {
|
||||
let mut fulfillment_cx = traits::FulfillmentContext::new();
|
||||
fulfillment_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause);
|
||||
if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) {
|
||||
traits::report_fulfillment_errors(&infcx, &err);
|
||||
infcx.report_fulfillment_errors(&err);
|
||||
}
|
||||
|
||||
if let Err(ref errors) = fulfillment_cx.select_rfc1592_obligations(&infcx) {
|
||||
traits::report_fulfillment_errors_as_warnings(&infcx, errors, id);
|
||||
if let Err(errors) = fulfillment_cx.select_rfc1592_obligations(&infcx) {
|
||||
infcx.report_fulfillment_errors_as_warnings(&errors, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -237,7 +237,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||
let fty = self.sanitize_type(lvalue, fty);
|
||||
match self.field_ty(lvalue, base, field) {
|
||||
Ok(ty) => {
|
||||
if let Err(terr) = self.cx.mk_eqty(span, ty, fty) {
|
||||
if let Err(terr) = self.cx.eq_types(span, ty, fty) {
|
||||
span_mirbug!(
|
||||
self, lvalue, "bad field access ({:?}: {:?}): {:?}",
|
||||
ty, fty, terr);
|
||||
@ -333,20 +333,18 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn mk_subty(&self, span: Span, sup: Ty<'tcx>, sub: Ty<'tcx>)
|
||||
-> infer::UnitResult<'tcx>
|
||||
fn sub_types(&self, span: Span, sup: Ty<'tcx>, sub: Ty<'tcx>)
|
||||
-> infer::UnitResult<'tcx>
|
||||
{
|
||||
infer::mk_subty(self.infcx, false, infer::TypeOrigin::Misc(span),
|
||||
sup, sub)
|
||||
self.infcx.sub_types(false, infer::TypeOrigin::Misc(span), sup, sub)
|
||||
// FIXME(#32730) propagate obligations
|
||||
.map(|InferOk { obligations, .. }| assert!(obligations.is_empty()))
|
||||
}
|
||||
|
||||
fn mk_eqty(&self, span: Span, a: Ty<'tcx>, b: Ty<'tcx>)
|
||||
fn eq_types(&self, span: Span, a: Ty<'tcx>, b: Ty<'tcx>)
|
||||
-> infer::UnitResult<'tcx>
|
||||
{
|
||||
infer::mk_eqty(self.infcx, false, infer::TypeOrigin::Misc(span),
|
||||
a, b)
|
||||
self.infcx.eq_types(false, infer::TypeOrigin::Misc(span), a, b)
|
||||
// FIXME(#32730) propagate obligations
|
||||
.map(|InferOk { obligations, .. }| assert!(obligations.is_empty()))
|
||||
}
|
||||
@ -363,7 +361,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
let lv_ty = mir.lvalue_ty(tcx, lv).to_ty(tcx);
|
||||
let rv_ty = mir.rvalue_ty(tcx, rv);
|
||||
if let Some(rv_ty) = rv_ty {
|
||||
if let Err(terr) = self.mk_subty(self.last_span, rv_ty, lv_ty) {
|
||||
if let Err(terr) = self.sub_types(self.last_span, rv_ty, lv_ty) {
|
||||
span_mirbug!(self, stmt, "bad assignment ({:?} = {:?}): {:?}",
|
||||
lv_ty, rv_ty, terr);
|
||||
}
|
||||
@ -399,7 +397,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
TerminatorKind::SwitchInt { ref discr, switch_ty, .. } => {
|
||||
let discr_ty = mir.lvalue_ty(tcx, discr).to_ty(tcx);
|
||||
if let Err(terr) = self.mk_subty(self.last_span, discr_ty, switch_ty) {
|
||||
if let Err(terr) = self.sub_types(self.last_span, discr_ty, switch_ty) {
|
||||
span_mirbug!(self, term, "bad SwitchInt ({:?} on {:?}): {:?}",
|
||||
switch_ty, discr_ty, terr);
|
||||
}
|
||||
@ -456,7 +454,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
(&Some((ref dest, _)), ty::FnConverging(ty)) => {
|
||||
let dest_ty = mir.lvalue_ty(tcx, dest).to_ty(tcx);
|
||||
if let Err(terr) = self.mk_subty(self.last_span, ty, dest_ty) {
|
||||
if let Err(terr) = self.sub_types(self.last_span, ty, dest_ty) {
|
||||
span_mirbug!(self, term,
|
||||
"call dest mismatch ({:?} <- {:?}): {:?}",
|
||||
dest_ty, ty, terr);
|
||||
@ -482,7 +480,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
for (n, (fn_arg, op_arg)) in sig.inputs.iter().zip(args).enumerate() {
|
||||
let op_arg_ty = mir.operand_ty(self.tcx(), op_arg);
|
||||
if let Err(terr) = self.mk_subty(self.last_span, op_arg_ty, fn_arg) {
|
||||
if let Err(terr) = self.sub_types(self.last_span, op_arg_ty, fn_arg) {
|
||||
span_mirbug!(self, term, "bad arg #{:?} ({:?} <- {:?}): {:?}",
|
||||
n, fn_arg, op_arg_ty, terr);
|
||||
}
|
||||
@ -537,7 +535,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
};
|
||||
|
||||
if let Err(terr) = self.mk_subty(self.last_span, arg_ty, pointee_ty) {
|
||||
if let Err(terr) = self.sub_types(self.last_span, arg_ty, pointee_ty) {
|
||||
span_mirbug!(self, term, "bad box_free arg ({:?} <- {:?}): {:?}",
|
||||
pointee_ty, arg_ty, terr);
|
||||
}
|
||||
|
@ -202,8 +202,7 @@ impl<'tcx> Callee<'tcx> {
|
||||
}
|
||||
traits::VtableObject(ref data) => {
|
||||
Callee {
|
||||
data: Virtual(traits::get_vtable_index_of_object_method(
|
||||
tcx, data, def_id)),
|
||||
data: Virtual(tcx.get_vtable_index_of_object_method(data, def_id)),
|
||||
ty: def_ty(tcx, def_id, substs)
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ use llvm::{True, False, Bool, OperandBundleDef};
|
||||
use rustc::cfg;
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::infer::{self, InferCtxt};
|
||||
use rustc::infer::InferCtxt;
|
||||
use rustc::util::common::MemoizationMap;
|
||||
use middle::lang_items::LangItem;
|
||||
use rustc::ty::subst::Substs;
|
||||
@ -1107,9 +1107,7 @@ pub fn fulfill_obligation<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
|
||||
let vtable = selection.map(|predicate| {
|
||||
fulfill_cx.register_predicate_obligation(&infcx, predicate);
|
||||
});
|
||||
let vtable = infer::drain_fulfillment_cx_or_panic(
|
||||
span, &infcx, &mut fulfill_cx, &vtable
|
||||
);
|
||||
let vtable = infcx.drain_fulfillment_cx_or_panic(span, &mut fulfill_cx, &vtable);
|
||||
|
||||
info!("Cache miss: {:?} => {:?}", trait_ref, vtable);
|
||||
|
||||
@ -1142,7 +1140,7 @@ pub fn normalize_and_test_predicates<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
fulfill_cx.register_predicate_obligation(&infcx, obligation);
|
||||
}
|
||||
|
||||
infer::drain_fulfillment_cx(&infcx, &mut fulfill_cx, &()).is_ok()
|
||||
infcx.drain_fulfillment_cx(&mut fulfill_cx, &()).is_ok()
|
||||
}
|
||||
|
||||
pub fn langcall(bcx: Block,
|
||||
|
@ -256,7 +256,7 @@ pub fn get_vtable_methods<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
let name = trait_method_type.name;
|
||||
|
||||
// Some methods cannot be called on an object; skip those.
|
||||
if !traits::is_vtable_safe_method(tcx, trt_id, &trait_method_type) {
|
||||
if !tcx.is_vtable_safe_method(trt_id, &trait_method_type) {
|
||||
debug!("get_vtable_methods: not vtable safe");
|
||||
return None;
|
||||
}
|
||||
|
@ -48,7 +48,6 @@
|
||||
//! case but `&a` in the second. Basically, defaults that appear inside
|
||||
//! an rptr (`&r.T`) use the region `r` that appears in the rptr.
|
||||
|
||||
use middle::astconv_util::{prim_ty_to_ty, prohibit_type_params, prohibit_projection};
|
||||
use middle::const_val::ConstVal;
|
||||
use rustc_const_eval::{eval_const_expr_partial, ConstEvalErr};
|
||||
use rustc_const_eval::EvalHint::UncheckedExprHint;
|
||||
@ -338,7 +337,7 @@ pub fn ast_path_substs_for_ty<'tcx>(
|
||||
}
|
||||
};
|
||||
|
||||
assoc_bindings.first().map(|b| prohibit_projection(this.tcx(), b.span));
|
||||
assoc_bindings.first().map(|b| this.tcx().prohibit_projection(b.span));
|
||||
|
||||
create_substs_for_ast_path(this,
|
||||
span,
|
||||
@ -825,7 +824,7 @@ fn ast_path_to_mono_trait_ref<'a,'tcx>(this: &AstConv<'tcx>,
|
||||
trait_def_id,
|
||||
self_ty,
|
||||
trait_segment);
|
||||
assoc_bindings.first().map(|b| prohibit_projection(this.tcx(), b.span));
|
||||
assoc_bindings.first().map(|b| this.tcx().prohibit_projection(b.span));
|
||||
ty::TraitRef::new(trait_def_id, substs)
|
||||
}
|
||||
|
||||
@ -1141,10 +1140,10 @@ fn make_object_type<'tcx>(this: &AstConv<'tcx>,
|
||||
// most importantly, that the supertraits don't contain Self,
|
||||
// to avoid ICE-s.
|
||||
let object_safety_violations =
|
||||
traits::astconv_object_safety_violations(tcx, principal.def_id());
|
||||
tcx.astconv_object_safety_violations(principal.def_id());
|
||||
if !object_safety_violations.is_empty() {
|
||||
traits::report_object_safety_error(
|
||||
tcx, span, principal.def_id(), None, object_safety_violations)
|
||||
tcx.report_object_safety_error(
|
||||
span, principal.def_id(), None, object_safety_violations)
|
||||
.unwrap().emit();
|
||||
return tcx.types.err;
|
||||
}
|
||||
@ -1281,7 +1280,7 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
|
||||
|
||||
debug!("associated_path_def_to_ty: {:?}::{}", ty, assoc_name);
|
||||
|
||||
prohibit_type_params(tcx, slice::ref_slice(item_segment));
|
||||
tcx.prohibit_type_params(slice::ref_slice(item_segment));
|
||||
|
||||
// Find the type of the associated item, and the trait where the associated
|
||||
// item is declared.
|
||||
@ -1383,7 +1382,7 @@ fn qpath_to_ty<'tcx>(this: &AstConv<'tcx>,
|
||||
{
|
||||
let tcx = this.tcx();
|
||||
|
||||
prohibit_type_params(tcx, slice::ref_slice(item_segment));
|
||||
tcx.prohibit_type_params(slice::ref_slice(item_segment));
|
||||
|
||||
let self_ty = if let Some(ty) = opt_self_ty {
|
||||
ty
|
||||
@ -1472,7 +1471,7 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
|
||||
base_segments.last().unwrap(),
|
||||
&mut projection_bounds);
|
||||
|
||||
prohibit_type_params(tcx, base_segments.split_last().unwrap().1);
|
||||
tcx.prohibit_type_params(base_segments.split_last().unwrap().1);
|
||||
trait_ref_to_object_type(this,
|
||||
rscope,
|
||||
span,
|
||||
@ -1481,7 +1480,7 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
|
||||
&[])
|
||||
}
|
||||
Def::Enum(did) | Def::TyAlias(did) | Def::Struct(did) => {
|
||||
prohibit_type_params(tcx, base_segments.split_last().unwrap().1);
|
||||
tcx.prohibit_type_params(base_segments.split_last().unwrap().1);
|
||||
ast_path_to_ty(this,
|
||||
rscope,
|
||||
span,
|
||||
@ -1490,12 +1489,12 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
|
||||
base_segments.last().unwrap())
|
||||
}
|
||||
Def::TyParam(space, index, _, name) => {
|
||||
prohibit_type_params(tcx, base_segments);
|
||||
tcx.prohibit_type_params(base_segments);
|
||||
tcx.mk_param(space, index, name)
|
||||
}
|
||||
Def::SelfTy(_, Some((_, self_ty_id))) => {
|
||||
// Self in impl (we know the concrete type).
|
||||
prohibit_type_params(tcx, base_segments);
|
||||
tcx.prohibit_type_params(base_segments);
|
||||
if let Some(&ty) = tcx.ast_ty_to_ty_cache.borrow().get(&self_ty_id) {
|
||||
if let Some(free_substs) = this.get_free_substs() {
|
||||
ty.subst(tcx, free_substs)
|
||||
@ -1508,11 +1507,11 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
|
||||
}
|
||||
Def::SelfTy(Some(_), None) => {
|
||||
// Self in trait.
|
||||
prohibit_type_params(tcx, base_segments);
|
||||
tcx.prohibit_type_params(base_segments);
|
||||
tcx.mk_self_type()
|
||||
}
|
||||
Def::AssociatedTy(trait_did, _) => {
|
||||
prohibit_type_params(tcx, &base_segments[..base_segments.len()-2]);
|
||||
tcx.prohibit_type_params(&base_segments[..base_segments.len()-2]);
|
||||
qpath_to_ty(this,
|
||||
rscope,
|
||||
span,
|
||||
@ -1536,7 +1535,7 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
|
||||
opt_self_ty.expect("missing T in <T>::a::b::c")
|
||||
}
|
||||
Def::PrimTy(prim_ty) => {
|
||||
prim_ty_to_ty(tcx, base_segments, prim_ty)
|
||||
tcx.prim_ty_to_ty(base_segments, prim_ty)
|
||||
}
|
||||
Def::Err => {
|
||||
this.set_tainted_by_errors();
|
||||
@ -2259,7 +2258,7 @@ impl<'tcx> Bounds<'tcx> {
|
||||
let mut vec = Vec::new();
|
||||
|
||||
for builtin_bound in &self.builtin_bounds {
|
||||
match traits::trait_ref_for_builtin_bound(tcx, builtin_bound, param_ty) {
|
||||
match tcx.trait_ref_for_builtin_bound(builtin_bound, param_ty) {
|
||||
Ok(trait_ref) => { vec.push(trait_ref.to_predicate()); }
|
||||
Err(ErrorReported) => { }
|
||||
}
|
||||
|
@ -64,7 +64,6 @@ use check::{FnCtxt, UnresolvedTypeAction};
|
||||
|
||||
use rustc::infer::{Coercion, InferOk, TypeOrigin, TypeTrace};
|
||||
use rustc::traits::{self, ObligationCause};
|
||||
use rustc::traits::{predicate_for_trait_def, report_selection_error};
|
||||
use rustc::ty::adjustment::{AutoAdjustment, AutoDerefRef, AdjustDerefRef};
|
||||
use rustc::ty::adjustment::{AutoPtr, AutoUnsafe, AdjustReifyFnPointer};
|
||||
use rustc::ty::adjustment::{AdjustUnsafeFnPointer, AdjustMutToConstPointer};
|
||||
@ -446,12 +445,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
|
||||
// Create an obligation for `Source: CoerceUnsized<Target>`.
|
||||
let cause = ObligationCause::misc(self.origin.span(), self.fcx.body_id);
|
||||
queue.push_back(predicate_for_trait_def(self.tcx(),
|
||||
cause,
|
||||
coerce_unsized_did,
|
||||
0,
|
||||
source,
|
||||
vec![target]));
|
||||
queue.push_back(self.tcx().predicate_for_trait_def(cause,
|
||||
coerce_unsized_did,
|
||||
0,
|
||||
source,
|
||||
vec![target]));
|
||||
|
||||
// Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid
|
||||
// emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where
|
||||
@ -477,7 +475,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
|
||||
// Object safety violations or miscellaneous.
|
||||
Err(err) => {
|
||||
report_selection_error(self.fcx.infcx(), &obligation, &err, None);
|
||||
self.fcx.infcx().report_selection_error(&obligation, &err, None);
|
||||
// Treat this like an obligation and follow through
|
||||
// with the unsizing - the lack of a coercion should
|
||||
// be silent, as it causes a type mismatch later.
|
||||
|
@ -325,9 +325,9 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
debug!("compare_impl_method: trait_fty={:?}",
|
||||
trait_fty);
|
||||
|
||||
infer::mk_subty(&infcx, false, origin, impl_fty, trait_fty)?;
|
||||
infcx.sub_types(false, origin, impl_fty, trait_fty)?;
|
||||
|
||||
infcx.leak_check(&skol_map, snapshot)
|
||||
infcx.leak_check(false, &skol_map, snapshot)
|
||||
});
|
||||
|
||||
match err {
|
||||
@ -347,7 +347,7 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
// Check that all obligations are satisfied by the implementation's
|
||||
// version.
|
||||
match fulfillment_cx.select_all_or_error(&infcx) {
|
||||
Err(ref errors) => { traits::report_fulfillment_errors(&infcx, errors) }
|
||||
Err(ref errors) => { infcx.report_fulfillment_errors(errors) }
|
||||
Ok(_) => {}
|
||||
}
|
||||
|
||||
@ -361,8 +361,7 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
// anyway, so it shouldn't be needed there either. Anyway, we can
|
||||
// always add more relations later (it's backwards compat).
|
||||
let mut free_regions = FreeRegionMap::new();
|
||||
free_regions.relate_free_regions_from_predicates(tcx,
|
||||
&infcx.parameter_environment.caller_bounds);
|
||||
free_regions.relate_free_regions_from_predicates(&infcx.parameter_environment.caller_bounds);
|
||||
|
||||
infcx.resolve_regions_and_report_errors(&free_regions, impl_m_body_id);
|
||||
|
||||
@ -474,7 +473,7 @@ pub fn compare_const_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
debug!("compare_const_impl: trait_ty={:?}",
|
||||
trait_ty);
|
||||
|
||||
infer::mk_subty(&infcx, false, origin, impl_ty, trait_ty)
|
||||
infcx.sub_types(false, origin, impl_ty, trait_ty)
|
||||
});
|
||||
|
||||
match err {
|
||||
|
@ -96,7 +96,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
|
||||
infcx.fresh_substs_for_generics(drop_impl_span, drop_impl_generics);
|
||||
let fresh_impl_self_ty = drop_impl_ty.subst(tcx, &fresh_impl_substs);
|
||||
|
||||
if let Err(_) = infer::mk_eqty(&infcx, true, infer::TypeOrigin::Misc(drop_impl_span),
|
||||
if let Err(_) = infcx.eq_types(true, infer::TypeOrigin::Misc(drop_impl_span),
|
||||
named_type, fresh_impl_self_ty) {
|
||||
let item_span = tcx.map.span(self_type_node_id);
|
||||
struct_span_err!(tcx.sess, drop_impl_span, E0366,
|
||||
@ -110,13 +110,12 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
|
||||
|
||||
if let Err(ref errors) = fulfillment_cx.select_all_or_error(&infcx) {
|
||||
// this could be reached when we get lazy normalization
|
||||
traits::report_fulfillment_errors(&infcx, errors);
|
||||
infcx.report_fulfillment_errors(errors);
|
||||
return Err(());
|
||||
}
|
||||
|
||||
if let Err(ref errors) = fulfillment_cx.select_rfc1592_obligations(&infcx) {
|
||||
traits::report_fulfillment_errors_as_warnings(&infcx, errors,
|
||||
drop_impl_node_id);
|
||||
infcx.report_fulfillment_errors_as_warnings(errors, drop_impl_node_id);
|
||||
}
|
||||
|
||||
let free_regions = FreeRegionMap::new();
|
||||
|
@ -19,7 +19,7 @@ use rustc::ty::{self, NoPreference, PreferMutLvalue, Ty, TyCtxt};
|
||||
use rustc::ty::adjustment::{AdjustDerefRef, AutoDerefRef, AutoPtr};
|
||||
use rustc::ty::fold::TypeFoldable;
|
||||
use rustc::infer;
|
||||
use rustc::infer::{InferCtxt, TypeOrigin};
|
||||
use rustc::infer::{InferCtxt, InferOk, TypeOrigin};
|
||||
use syntax::codemap::Span;
|
||||
use rustc::hir;
|
||||
|
||||
@ -369,8 +369,12 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
||||
self_ty: Ty<'tcx>,
|
||||
method_self_ty: Ty<'tcx>)
|
||||
{
|
||||
match self.fcx.mk_subty(false, TypeOrigin::Misc(self.span), self_ty, method_self_ty) {
|
||||
Ok(_) => {}
|
||||
match self.fcx.infcx().sub_types(false, TypeOrigin::Misc(self.span),
|
||||
self_ty, method_self_ty) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty());
|
||||
}
|
||||
Err(_) => {
|
||||
span_bug!(
|
||||
self.span,
|
||||
@ -636,9 +640,8 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
||||
target_trait_def_id: DefId)
|
||||
-> ty::PolyTraitRef<'tcx>
|
||||
{
|
||||
let upcast_trait_refs = traits::upcast(self.tcx(),
|
||||
source_trait_ref.clone(),
|
||||
target_trait_def_id);
|
||||
let upcast_trait_refs = self.tcx().upcast_choices(source_trait_ref.clone(),
|
||||
target_trait_def_id);
|
||||
|
||||
// must be exactly one trait ref or we'd get an ambig error etc
|
||||
if upcast_trait_refs.len() != 1 {
|
||||
|
@ -84,14 +84,13 @@ use astconv::{self, ast_region_to_region, ast_ty_to_ty, AstConv, PathParamMode};
|
||||
use check::_match::PatCtxt;
|
||||
use dep_graph::DepNode;
|
||||
use fmt_macros::{Parser, Piece, Position};
|
||||
use middle::astconv_util::prohibit_type_params;
|
||||
use middle::cstore::LOCAL_CRATE;
|
||||
use hir::def::{self, Def};
|
||||
use hir::def_id::DefId;
|
||||
use rustc::infer::{self, InferCtxt, InferOk, TypeOrigin, TypeTrace, type_variable};
|
||||
use hir::pat_util::{self, pat_id_map};
|
||||
use rustc::ty::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace};
|
||||
use rustc::traits::{self, report_fulfillment_errors, ProjectionMode};
|
||||
use rustc::traits::{self, ProjectionMode};
|
||||
use rustc::ty::{GenericPredicates, TypeScheme};
|
||||
use rustc::ty::{ParamTy, ParameterEnvironment};
|
||||
use rustc::ty::{LvaluePreference, NoPreference, PreferMutLvalue};
|
||||
@ -1158,7 +1157,7 @@ pub fn check_representable(tcx: &TyCtxt,
|
||||
match rty.is_representable(tcx, sp) {
|
||||
Representability::SelfRecursive => {
|
||||
let item_def_id = tcx.map.local_def_id(item_id);
|
||||
traits::recursive_type_with_infinite_size_error(tcx, item_def_id).emit();
|
||||
tcx.recursive_type_with_infinite_size_error(item_def_id).emit();
|
||||
return false
|
||||
}
|
||||
Representability::Representable | Representability::ContainsRecursive => (),
|
||||
@ -1803,35 +1802,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mk_subty(&self,
|
||||
a_is_expected: bool,
|
||||
origin: TypeOrigin,
|
||||
sub: Ty<'tcx>,
|
||||
sup: Ty<'tcx>)
|
||||
-> Result<(), TypeError<'tcx>> {
|
||||
infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup)
|
||||
// FIXME(#32730) propagate obligations
|
||||
.map(|InferOk { obligations, .. }| assert!(obligations.is_empty()))
|
||||
}
|
||||
|
||||
pub fn mk_eqty(&self,
|
||||
a_is_expected: bool,
|
||||
origin: TypeOrigin,
|
||||
sub: Ty<'tcx>,
|
||||
sup: Ty<'tcx>)
|
||||
-> Result<(), TypeError<'tcx>> {
|
||||
infer::mk_eqty(self.infcx(), a_is_expected, origin, sub, sup)
|
||||
// FIXME(#32730) propagate obligations
|
||||
.map(|InferOk { obligations, .. }| assert!(obligations.is_empty()))
|
||||
}
|
||||
|
||||
pub fn mk_subr(&self,
|
||||
origin: infer::SubregionOrigin<'tcx>,
|
||||
sub: ty::Region,
|
||||
sup: ty::Region) {
|
||||
infer::mk_subr(self.infcx(), origin, sub, sup)
|
||||
}
|
||||
|
||||
pub fn type_error_message<M>(&self,
|
||||
sp: Span,
|
||||
mk_msg: M,
|
||||
@ -2119,9 +2089,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
Neither => {
|
||||
if let Some(default) = default_map.get(ty) {
|
||||
let default = default.clone();
|
||||
match infer::mk_eqty(self.infcx(), false,
|
||||
TypeOrigin::Misc(default.origin_span),
|
||||
ty, default.ty) {
|
||||
match self.infcx().eq_types(false,
|
||||
TypeOrigin::Misc(default.origin_span),
|
||||
ty, default.ty) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty())
|
||||
@ -2215,9 +2185,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
Neither => {
|
||||
if let Some(default) = default_map.get(ty) {
|
||||
let default = default.clone();
|
||||
match infer::mk_eqty(self.infcx(), false,
|
||||
TypeOrigin::Misc(default.origin_span),
|
||||
ty, default.ty) {
|
||||
match self.infcx().eq_types(false,
|
||||
TypeOrigin::Misc(default.origin_span),
|
||||
ty, default.ty) {
|
||||
// FIXME(#32730) propagate obligations
|
||||
Ok(InferOk { obligations, .. }) => assert!(obligations.is_empty()),
|
||||
Err(_) => {
|
||||
@ -2239,18 +2209,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// upvar inference should have ensured that all deferred call
|
||||
// resolutions are handled by now.
|
||||
assert!(self.inh.deferred_call_resolutions.borrow().is_empty());
|
||||
let infcx = self.infcx();
|
||||
|
||||
self.select_all_obligations_and_apply_defaults();
|
||||
|
||||
let mut fulfillment_cx = self.inh.fulfillment_cx.borrow_mut();
|
||||
match fulfillment_cx.select_all_or_error(infcx) {
|
||||
match fulfillment_cx.select_all_or_error(self.infcx()) {
|
||||
Ok(()) => { }
|
||||
Err(errors) => { report_fulfillment_errors(infcx, &errors); }
|
||||
Err(errors) => { self.infcx().report_fulfillment_errors(&errors); }
|
||||
}
|
||||
|
||||
if let Err(ref errors) = fulfillment_cx.select_rfc1592_obligations(infcx) {
|
||||
traits::report_fulfillment_errors_as_warnings(infcx, errors, self.body_id);
|
||||
if let Err(ref errors) = fulfillment_cx.select_rfc1592_obligations(self.infcx()) {
|
||||
self.infcx().report_fulfillment_errors_as_warnings(errors, self.body_id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2262,7 +2231,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
.select_where_possible(self.infcx())
|
||||
{
|
||||
Ok(()) => { }
|
||||
Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
|
||||
Err(errors) => { self.infcx().report_fulfillment_errors(&errors); }
|
||||
}
|
||||
}
|
||||
|
||||
@ -3570,16 +3539,18 @@ fn check_expr_with_expectation_and_lvalue_pref(&self,
|
||||
hir::ExprRet(ref expr_opt) => {
|
||||
match self.ret_ty {
|
||||
ty::FnConverging(result_type) => {
|
||||
match *expr_opt {
|
||||
None =>
|
||||
if let Err(_) = self.mk_eqty(false, TypeOrigin::Misc(expr.span),
|
||||
result_type, self.tcx().mk_nil()) {
|
||||
span_err!(tcx.sess, expr.span, E0069,
|
||||
"`return;` in a function whose return type is \
|
||||
not `()`");
|
||||
},
|
||||
Some(ref e) => {
|
||||
self.check_expr_coercable_to_type(&e, result_type);
|
||||
if let Some(ref e) = *expr_opt {
|
||||
self.check_expr_coercable_to_type(&e, result_type);
|
||||
} else {
|
||||
let eq_result = self.infcx().eq_types(false,
|
||||
TypeOrigin::Misc(expr.span),
|
||||
result_type,
|
||||
self.tcx().mk_nil())
|
||||
// FIXME(#32730) propagate obligations
|
||||
.map(|InferOk { obligations, .. }| assert!(obligations.is_empty()));
|
||||
if eq_result.is_err() {
|
||||
span_err!(tcx.sess, expr.span, E0069,
|
||||
"`return;` in a function whose return type is not `()`");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4370,7 +4341,7 @@ pub fn instantiate_path(&self,
|
||||
segment,
|
||||
&mut substs);
|
||||
} else {
|
||||
prohibit_type_params(self.tcx(), slice::ref_slice(segment));
|
||||
self.tcx().prohibit_type_params(slice::ref_slice(segment));
|
||||
}
|
||||
}
|
||||
if let Some(self_ty) = opt_self_ty {
|
||||
@ -4423,11 +4394,17 @@ pub fn instantiate_path(&self,
|
||||
impl_scheme.generics.regions.len(subst::TypeSpace));
|
||||
|
||||
let impl_ty = self.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
|
||||
if self.mk_subty(false, TypeOrigin::Misc(span), self_ty, impl_ty).is_err() {
|
||||
span_bug!(span,
|
||||
"instantiate_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
|
||||
self_ty,
|
||||
impl_ty);
|
||||
match self.infcx().sub_types(false, TypeOrigin::Misc(span), self_ty, impl_ty) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty());
|
||||
}
|
||||
Err(_) => {
|
||||
span_bug!(span,
|
||||
"instantiate_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
|
||||
self_ty,
|
||||
impl_ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,8 +131,7 @@ pub fn regionck_item(&self,
|
||||
wf_tys: &[Ty<'tcx>]) {
|
||||
debug!("regionck_item(item.id={:?}, wf_tys={:?}", item_id, wf_tys);
|
||||
let mut rcx = Rcx::new(self, RepeatingScope(item_id), item_id, Subject(item_id));
|
||||
let tcx = self.tcx();
|
||||
rcx.free_region_map.relate_free_regions_from_predicates(tcx,
|
||||
rcx.free_region_map.relate_free_regions_from_predicates(
|
||||
&self.infcx().parameter_environment.caller_bounds);
|
||||
rcx.relate_free_regions(wf_tys, item_id, span);
|
||||
rcx.visit_region_obligations(item_id);
|
||||
@ -152,8 +151,7 @@ pub fn regionck_fn(&self,
|
||||
rcx.visit_fn_body(fn_id, decl, blk, fn_span);
|
||||
}
|
||||
|
||||
let tcx = self.tcx();
|
||||
rcx.free_region_map.relate_free_regions_from_predicates(tcx,
|
||||
rcx.free_region_map.relate_free_regions_from_predicates(
|
||||
&self.infcx().parameter_environment.caller_bounds);
|
||||
|
||||
rcx.resolve_regions_and_report_errors();
|
||||
@ -844,7 +842,7 @@ fn constrain_cast(rcx: &mut Rcx,
|
||||
/*From:*/ (&ty::TyRef(from_r, ref from_mt),
|
||||
/*To: */ &ty::TyRef(to_r, ref to_mt)) => {
|
||||
// Target cannot outlive source, naturally.
|
||||
rcx.fcx.mk_subr(infer::Reborrow(cast_expr.span), *to_r, *from_r);
|
||||
rcx.fcx.infcx().sub_regions(infer::Reborrow(cast_expr.span), *to_r, *from_r);
|
||||
walk_cast(rcx, cast_expr, from_mt.ty, to_mt.ty);
|
||||
}
|
||||
|
||||
@ -1038,8 +1036,8 @@ pub fn mk_subregion_due_to_dereference(rcx: &mut Rcx,
|
||||
deref_span: Span,
|
||||
minimum_lifetime: ty::Region,
|
||||
maximum_lifetime: ty::Region) {
|
||||
rcx.fcx.mk_subr(infer::DerefPointer(deref_span),
|
||||
minimum_lifetime, maximum_lifetime)
|
||||
rcx.fcx.infcx().sub_regions(infer::DerefPointer(deref_span),
|
||||
minimum_lifetime, maximum_lifetime)
|
||||
}
|
||||
|
||||
fn check_safety_of_rvalue_destructor_if_necessary<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
|
||||
@ -1081,8 +1079,8 @@ fn constrain_index<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
|
||||
if let ty::TyRef(r_ptr, mt) = indexed_ty.sty {
|
||||
match mt.ty.sty {
|
||||
ty::TySlice(_) | ty::TyStr => {
|
||||
rcx.fcx.mk_subr(infer::IndexSlice(index_expr.span),
|
||||
r_index_expr, *r_ptr);
|
||||
rcx.fcx.infcx().sub_regions(infer::IndexSlice(index_expr.span),
|
||||
r_index_expr, *r_ptr);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -1410,7 +1408,7 @@ fn link_reborrowed_region<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
|
||||
debug!("link_reborrowed_region: {:?} <= {:?}",
|
||||
borrow_region,
|
||||
ref_region);
|
||||
rcx.fcx.mk_subr(cause, *borrow_region, ref_region);
|
||||
rcx.fcx.infcx().sub_regions(cause, *borrow_region, ref_region);
|
||||
|
||||
// If we end up needing to recurse and establish a region link
|
||||
// with `ref_cmt`, calculate what borrow kind we will end up
|
||||
@ -1492,7 +1490,7 @@ pub fn substs_wf_in_scope<'a,'tcx>(rcx: &mut Rcx<'a,'tcx>,
|
||||
let origin = infer::ParameterInScope(origin, expr_span);
|
||||
|
||||
for ®ion in &substs.regions {
|
||||
rcx.fcx.mk_subr(origin.clone(), expr_region, region);
|
||||
rcx.fcx.infcx().sub_regions(origin.clone(), expr_region, region);
|
||||
}
|
||||
|
||||
for &ty in &substs.types {
|
||||
@ -1518,7 +1516,7 @@ pub fn type_must_outlive<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
|
||||
|
||||
assert!(!ty.has_escaping_regions());
|
||||
|
||||
let components = ty::outlives::components(rcx.infcx(), ty);
|
||||
let components = rcx.infcx().outlives_components(ty);
|
||||
components_must_outlive(rcx, origin, components, region);
|
||||
}
|
||||
|
||||
@ -1531,7 +1529,7 @@ fn components_must_outlive<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
|
||||
let origin = origin.clone();
|
||||
match component {
|
||||
ty::outlives::Component::Region(region1) => {
|
||||
rcx.fcx.mk_subr(origin, region, region1);
|
||||
rcx.fcx.infcx().sub_regions(origin, region, region1);
|
||||
}
|
||||
ty::outlives::Component::Param(param_ty) => {
|
||||
param_ty_must_outlive(rcx, origin, region, param_ty);
|
||||
@ -1629,7 +1627,7 @@ fn projection_must_outlive<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
|
||||
}
|
||||
|
||||
for &r in &projection_ty.trait_ref.substs.regions {
|
||||
rcx.fcx.mk_subr(origin.clone(), region, r);
|
||||
rcx.fcx.infcx().sub_regions(origin.clone(), region, r);
|
||||
}
|
||||
|
||||
return;
|
||||
@ -1650,7 +1648,7 @@ fn projection_must_outlive<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
|
||||
.any(|r| env_bounds.contains(r))
|
||||
{
|
||||
debug!("projection_must_outlive: unique declared bound appears in trait ref");
|
||||
rcx.fcx.mk_subr(origin.clone(), region, unique_bound);
|
||||
rcx.fcx.infcx().sub_regions(origin.clone(), region, unique_bound);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1840,7 +1838,7 @@ fn declared_projection_bounds_from_trait<'a,'tcx>(rcx: &Rcx<'a, 'tcx>,
|
||||
outlives);
|
||||
|
||||
// check whether this predicate applies to our current projection
|
||||
match infer::mk_eqty(infcx, false, TypeOrigin::Misc(span), ty, outlives.0) {
|
||||
match infcx.eq_types(false, TypeOrigin::Misc(span), ty, outlives.0) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty());
|
||||
|
@ -440,28 +440,24 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
|
||||
match self.reason {
|
||||
ResolvingExpr(span) => {
|
||||
span_err!(self.tcx.sess, span, E0101,
|
||||
"cannot determine a type for this expression: {}",
|
||||
infer::fixup_err_to_string(e));
|
||||
"cannot determine a type for this expression: {}", e);
|
||||
}
|
||||
|
||||
ResolvingLocal(span) => {
|
||||
span_err!(self.tcx.sess, span, E0102,
|
||||
"cannot determine a type for this local variable: {}",
|
||||
infer::fixup_err_to_string(e));
|
||||
"cannot determine a type for this local variable: {}", e);
|
||||
}
|
||||
|
||||
ResolvingPattern(span) => {
|
||||
span_err!(self.tcx.sess, span, E0103,
|
||||
"cannot determine a type for this pattern binding: {}",
|
||||
infer::fixup_err_to_string(e));
|
||||
"cannot determine a type for this pattern binding: {}", e);
|
||||
}
|
||||
|
||||
ResolvingUpvar(upvar_id) => {
|
||||
let span = self.reason.span(self.tcx);
|
||||
span_err!(self.tcx.sess, span, E0104,
|
||||
"cannot resolve lifetime for captured variable `{}`: {}",
|
||||
self.tcx.local_var_name_str(upvar_id.var_id).to_string(),
|
||||
infer::fixup_err_to_string(e));
|
||||
self.tcx.local_var_name_str(upvar_id.var_id), e);
|
||||
}
|
||||
|
||||
ResolvingClosure(_) => {
|
||||
|
@ -46,11 +46,28 @@ mod orphan;
|
||||
mod overlap;
|
||||
mod unsafety;
|
||||
|
||||
struct CoherenceChecker<'a, 'tcx: 'a> {
|
||||
crate_context: &'a CrateCtxt<'a, 'tcx>,
|
||||
inference_context: InferCtxt<'a, 'tcx>,
|
||||
inherent_impls: RefCell<DefIdMap<Rc<RefCell<Vec<DefId>>>>>,
|
||||
}
|
||||
|
||||
struct CoherenceCheckVisitor<'a, 'tcx: 'a> {
|
||||
cc: &'a CoherenceChecker<'a, 'tcx>
|
||||
}
|
||||
|
||||
impl<'a, 'tcx, 'v> intravisit::Visitor<'v> for CoherenceCheckVisitor<'a, 'tcx> {
|
||||
fn visit_item(&mut self, item: &Item) {
|
||||
if let ItemImpl(..) = item.node {
|
||||
self.cc.check_implementation(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
|
||||
|
||||
// Returns the def ID of the base type, if there is one.
|
||||
fn get_base_type_def_id<'a, 'tcx>(inference_context: &InferCtxt<'a, 'tcx>,
|
||||
span: Span,
|
||||
ty: Ty<'tcx>)
|
||||
-> Option<DefId> {
|
||||
fn get_base_type_def_id(&self, span: Span, ty: Ty<'tcx>) -> Option<DefId> {
|
||||
match ty.sty {
|
||||
TyEnum(def, _) |
|
||||
TyStruct(def, _) => {
|
||||
@ -62,7 +79,7 @@ fn get_base_type_def_id<'a, 'tcx>(inference_context: &InferCtxt<'a, 'tcx>,
|
||||
}
|
||||
|
||||
TyBox(_) => {
|
||||
inference_context.tcx.lang_items.owned_box()
|
||||
self.inference_context.tcx.lang_items.owned_box()
|
||||
}
|
||||
|
||||
TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
|
||||
@ -83,25 +100,6 @@ fn get_base_type_def_id<'a, 'tcx>(inference_context: &InferCtxt<'a, 'tcx>,
|
||||
}
|
||||
}
|
||||
|
||||
struct CoherenceChecker<'a, 'tcx: 'a> {
|
||||
crate_context: &'a CrateCtxt<'a, 'tcx>,
|
||||
inference_context: InferCtxt<'a, 'tcx>,
|
||||
inherent_impls: RefCell<DefIdMap<Rc<RefCell<Vec<DefId>>>>>,
|
||||
}
|
||||
|
||||
struct CoherenceCheckVisitor<'a, 'tcx: 'a> {
|
||||
cc: &'a CoherenceChecker<'a, 'tcx>
|
||||
}
|
||||
|
||||
impl<'a, 'tcx, 'v> intravisit::Visitor<'v> for CoherenceCheckVisitor<'a, 'tcx> {
|
||||
fn visit_item(&mut self, item: &Item) {
|
||||
if let ItemImpl(..) = item.node {
|
||||
self.cc.check_implementation(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
|
||||
fn check(&self) {
|
||||
// Check implementations and traits. This populates the tables
|
||||
// containing the inherent methods and extension methods. It also
|
||||
@ -167,9 +165,8 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
|
||||
// Add the implementation to the mapping from implementation to base
|
||||
// type def ID, if there is a base type for this implementation and
|
||||
// the implementation does not have any associated traits.
|
||||
if let Some(base_type_def_id) = get_base_type_def_id(
|
||||
&self.inference_context, item.span, self_type.ty) {
|
||||
self.add_inherent_impl(base_type_def_id, impl_did);
|
||||
if let Some(base_def_id) = self.get_base_type_def_id(item.span, self_type.ty) {
|
||||
self.add_inherent_impl(base_def_id, impl_did);
|
||||
}
|
||||
}
|
||||
|
||||
@ -394,7 +391,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
|
||||
(&ty::TyBox(a), &ty::TyBox(b)) => (a, b, unsize_trait, None),
|
||||
|
||||
(&ty::TyRef(r_a, mt_a), &ty::TyRef(r_b, mt_b)) => {
|
||||
infer::mk_subr(&infcx, infer::RelateObjectBound(span), *r_b, *r_a);
|
||||
infcx.sub_regions(infer::RelateObjectBound(span), *r_b, *r_a);
|
||||
check_mutbl(mt_a, mt_b, &|ty| tcx.mk_imm_ref(r_b, ty))
|
||||
}
|
||||
|
||||
@ -466,19 +463,19 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
|
||||
|
||||
// Register an obligation for `A: Trait<B>`.
|
||||
let cause = traits::ObligationCause::misc(span, impl_node_id);
|
||||
let predicate = traits::predicate_for_trait_def(tcx, cause, trait_def_id,
|
||||
0, source, vec![target]);
|
||||
let predicate = tcx.predicate_for_trait_def(cause, trait_def_id, 0,
|
||||
source, vec![target]);
|
||||
fulfill_cx.register_predicate_obligation(&infcx, predicate);
|
||||
|
||||
// Check that all transitive obligations are satisfied.
|
||||
if let Err(errors) = fulfill_cx.select_all_or_error(&infcx) {
|
||||
traits::report_fulfillment_errors(&infcx, &errors);
|
||||
infcx.report_fulfillment_errors(&errors);
|
||||
}
|
||||
|
||||
// Finally, resolve all regions.
|
||||
let mut free_regions = FreeRegionMap::new();
|
||||
free_regions.relate_free_regions_from_predicates(tcx, &infcx.parameter_environment
|
||||
.caller_bounds);
|
||||
free_regions.relate_free_regions_from_predicates(&infcx.parameter_environment
|
||||
.caller_bounds);
|
||||
infcx.resolve_regions_and_report_errors(&free_regions, impl_node_id);
|
||||
|
||||
if let Some(kind) = kind {
|
||||
|
@ -174,7 +174,7 @@ impl<'cx, 'tcx,'v> intravisit::Visitor<'v> for OverlapChecker<'cx, 'tcx> {
|
||||
// This is something like impl Trait1 for Trait2. Illegal
|
||||
// if Trait1 is a supertrait of Trait2 or Trait2 is not object safe.
|
||||
|
||||
if !traits::is_object_safe(self.tcx, data.principal_def_id()) {
|
||||
if !self.tcx.is_object_safe(data.principal_def_id()) {
|
||||
// This is an error, but it will be
|
||||
// reported by wfcheck. Ignore it
|
||||
// here. This is tested by
|
||||
|
@ -201,10 +201,10 @@ fn require_same_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
-> bool
|
||||
{
|
||||
let err = if let Some(infcx) = maybe_infcx {
|
||||
infer::mk_eqty(infcx, false, TypeOrigin::Misc(span), t1, t2).err()
|
||||
infcx.eq_types(false, TypeOrigin::Misc(span), t1, t2).err()
|
||||
} else {
|
||||
let infcx = InferCtxt::new(ccx.tcx, &ccx.tcx.tables, None, ProjectionMode::AnyFinal);
|
||||
infer::mk_eqty(&infcx, false, TypeOrigin::Misc(span), t1, t2).err()
|
||||
infcx.eq_types(false, TypeOrigin::Misc(span), t1, t2).err()
|
||||
};
|
||||
|
||||
if let Some(ref terr) = err {
|
||||
|
@ -22,7 +22,6 @@ use rustc::hir::def_id::DefId;
|
||||
use rustc::hir::print as pprust;
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
use rustc::ty::subst;
|
||||
use rustc::middle::stability;
|
||||
|
||||
use rustc_const_eval::lookup_const_by_id;
|
||||
|
||||
@ -124,8 +123,8 @@ fn try_inline_def(cx: &DocContext, tcx: &TyCtxt,
|
||||
attrs: load_attrs(cx, tcx, did),
|
||||
inner: inner,
|
||||
visibility: Some(clean::Public),
|
||||
stability: stability::lookup_stability(tcx, did).clean(cx),
|
||||
deprecation: stability::lookup_deprecation(tcx, did).clean(cx),
|
||||
stability: tcx.lookup_stability(did).clean(cx),
|
||||
deprecation: tcx.lookup_deprecation(did).clean(cx),
|
||||
def_id: did,
|
||||
});
|
||||
Some(ret)
|
||||
@ -305,8 +304,8 @@ pub fn build_impl(cx: &DocContext,
|
||||
name: None,
|
||||
attrs: attrs,
|
||||
visibility: Some(clean::Inherited),
|
||||
stability: stability::lookup_stability(tcx, did).clean(cx),
|
||||
deprecation: stability::lookup_deprecation(tcx, did).clean(cx),
|
||||
stability: tcx.lookup_stability(did).clean(cx),
|
||||
deprecation: tcx.lookup_deprecation(did).clean(cx),
|
||||
def_id: did,
|
||||
});
|
||||
}
|
||||
@ -347,8 +346,8 @@ pub fn build_impl(cx: &DocContext,
|
||||
source: clean::Span::empty(),
|
||||
attrs: vec![],
|
||||
visibility: None,
|
||||
stability: stability::lookup_stability(tcx, did).clean(cx),
|
||||
deprecation: stability::lookup_deprecation(tcx, did).clean(cx),
|
||||
stability: tcx.lookup_stability(did).clean(cx),
|
||||
deprecation: tcx.lookup_deprecation(did).clean(cx),
|
||||
def_id: did
|
||||
})
|
||||
}
|
||||
@ -396,8 +395,8 @@ pub fn build_impl(cx: &DocContext,
|
||||
source: clean::Span::empty(),
|
||||
attrs: vec![],
|
||||
visibility: None,
|
||||
stability: stability::lookup_stability(tcx, did).clean(cx),
|
||||
deprecation: stability::lookup_deprecation(tcx, did).clean(cx),
|
||||
stability: tcx.lookup_stability(did).clean(cx),
|
||||
deprecation: tcx.lookup_deprecation(did).clean(cx),
|
||||
def_id: did
|
||||
})
|
||||
}
|
||||
@ -436,8 +435,8 @@ pub fn build_impl(cx: &DocContext,
|
||||
name: None,
|
||||
attrs: attrs,
|
||||
visibility: Some(clean::Inherited),
|
||||
stability: stability::lookup_stability(tcx, did).clean(cx),
|
||||
deprecation: stability::lookup_deprecation(tcx, did).clean(cx),
|
||||
stability: tcx.lookup_stability(did).clean(cx),
|
||||
deprecation: tcx.lookup_deprecation(did).clean(cx),
|
||||
def_id: did,
|
||||
});
|
||||
}
|
||||
|
@ -64,11 +64,11 @@ mod simplify;
|
||||
|
||||
// extract the stability index for a node from tcx, if possible
|
||||
fn get_stability(cx: &DocContext, def_id: DefId) -> Option<Stability> {
|
||||
cx.tcx_opt().and_then(|tcx| stability::lookup_stability(tcx, def_id)).clean(cx)
|
||||
cx.tcx_opt().and_then(|tcx| tcx.lookup_stability(def_id)).clean(cx)
|
||||
}
|
||||
|
||||
fn get_deprecation(cx: &DocContext, def_id: DefId) -> Option<Deprecation> {
|
||||
cx.tcx_opt().and_then(|tcx| stability::lookup_deprecation(tcx, def_id)).clean(cx)
|
||||
cx.tcx_opt().and_then(|tcx| tcx.lookup_deprecation(def_id)).clean(cx)
|
||||
}
|
||||
|
||||
pub trait Clean<T> {
|
||||
@ -2878,8 +2878,8 @@ impl<'tcx> Clean<Item> for ty::AssociatedType<'tcx> {
|
||||
inner: AssociatedTypeItem(bounds, self.ty.clean(cx)),
|
||||
visibility: self.vis.clean(cx),
|
||||
def_id: self.def_id,
|
||||
stability: stability::lookup_stability(cx.tcx(), self.def_id).clean(cx),
|
||||
deprecation: stability::lookup_deprecation(cx.tcx(), self.def_id).clean(cx),
|
||||
stability: cx.tcx().lookup_stability(self.def_id).clean(cx),
|
||||
deprecation: cx.tcx().lookup_deprecation(self.def_id).clean(cx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ use syntax::codemap::Span;
|
||||
|
||||
use rustc::hir::map as hir_map;
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::middle::stability;
|
||||
use rustc::middle::privacy::AccessLevel;
|
||||
|
||||
use rustc::hir;
|
||||
@ -64,7 +63,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
fn stability(&self, id: ast::NodeId) -> Option<attr::Stability> {
|
||||
self.cx.tcx_opt().and_then(|tcx| {
|
||||
self.cx.map.opt_local_def_id(id)
|
||||
.and_then(|def_id| stability::lookup_stability(tcx, def_id))
|
||||
.and_then(|def_id| tcx.lookup_stability(def_id))
|
||||
.cloned()
|
||||
})
|
||||
}
|
||||
@ -72,7 +71,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
fn deprecation(&self, id: ast::NodeId) -> Option<attr::Deprecation> {
|
||||
self.cx.tcx_opt().and_then(|tcx| {
|
||||
self.cx.map.opt_local_def_id(id)
|
||||
.and_then(|def_id| stability::lookup_deprecation(tcx, def_id))
|
||||
.and_then(|def_id| tcx.lookup_deprecation(def_id))
|
||||
})
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user