2014-09-12 10:53:35 -04:00
|
|
|
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2015-02-18 19:34:55 -08:00
|
|
|
//! See `README.md` for high-level documentation
|
2014-09-12 10:53:35 -04:00
|
|
|
|
2014-12-17 14:16:28 -05:00
|
|
|
use self::SelectionCandidate::*;
|
2014-11-06 00:05:53 -08:00
|
|
|
use self::EvaluationResult::*;
|
|
|
|
|
2017-11-22 23:01:51 +02:00
|
|
|
use super::coherence::{self, Conflict};
|
2015-02-19 10:30:45 -05:00
|
|
|
use super::DerivedObligationCause;
|
2017-11-23 19:05:23 +02:00
|
|
|
use super::IntercrateMode;
|
2015-02-19 10:30:45 -05:00
|
|
|
use super::project;
|
2017-08-20 19:16:36 +03:00
|
|
|
use super::project::{normalize_with_depth, Normalized, ProjectionCacheKey};
|
2015-02-13 15:15:05 +11:00
|
|
|
use super::{PredicateObligation, TraitObligation, ObligationCause};
|
2015-02-02 12:14:01 +01:00
|
|
|
use super::{ObligationCauseCode, BuiltinDerivedObligation, ImplDerivedObligation};
|
2015-03-20 06:48:40 -04:00
|
|
|
use super::{SelectionError, Unimplemented, OutputTypeParameterMismatch};
|
2015-04-15 11:57:29 +12:00
|
|
|
use super::{ObjectCastObligation, Obligation};
|
|
|
|
use super::TraitNotObjectSafe;
|
2015-03-28 02:23:20 -07:00
|
|
|
use super::Selection;
|
|
|
|
use super::SelectionResult;
|
2016-12-26 14:34:03 +01:00
|
|
|
use super::{VtableBuiltin, VtableImpl, VtableParam, VtableClosure, VtableGenerator,
|
2017-10-09 13:59:20 -03:00
|
|
|
VtableFnPointer, VtableObject, VtableAutoImpl};
|
2016-12-26 14:34:03 +01:00
|
|
|
use super::{VtableImplData, VtableObjectData, VtableBuiltinData, VtableGeneratorData,
|
2017-10-09 13:59:20 -03:00
|
|
|
VtableClosureData, VtableAutoImplData, VtableFnPointerData};
|
2015-03-28 02:23:20 -07:00
|
|
|
use super::util;
|
2014-09-12 10:53:35 -04:00
|
|
|
|
2017-07-10 17:10:30 -04:00
|
|
|
use dep_graph::{DepNodeIndex, DepKind};
|
2017-08-28 16:50:41 -04:00
|
|
|
use hir::def_id::DefId;
|
2016-03-22 17:30:57 +02:00
|
|
|
use infer;
|
2016-11-07 13:25:06 -05:00
|
|
|
use infer::{InferCtxt, InferOk, TypeFreshener};
|
2016-08-27 01:13:48 +03:00
|
|
|
use ty::subst::{Kind, Subst, Substs};
|
2016-03-22 17:30:57 +02:00
|
|
|
use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
|
|
|
|
use ty::fast_reject;
|
|
|
|
use ty::relate::TypeRelation;
|
2016-11-13 15:25:54 -07:00
|
|
|
use middle::lang_items;
|
2015-06-18 08:51:23 +03:00
|
|
|
|
2016-08-08 23:39:49 +03:00
|
|
|
use rustc_data_structures::bitvec::BitVector;
|
2016-05-11 14:40:24 -07:00
|
|
|
use rustc_data_structures::snapshot_vec::{SnapshotVecDelegate, SnapshotVec};
|
2016-12-26 14:34:03 +01:00
|
|
|
use std::iter;
|
2014-09-17 16:12:02 -04:00
|
|
|
use std::cell::RefCell;
|
2017-06-30 14:18:04 +03:00
|
|
|
use std::cmp;
|
2015-06-18 08:51:23 +03:00
|
|
|
use std::fmt;
|
2016-05-11 14:40:24 -07:00
|
|
|
use std::marker::PhantomData;
|
2016-04-20 19:51:56 -04:00
|
|
|
use std::mem;
|
2014-09-12 10:53:35 -04:00
|
|
|
use std::rc::Rc;
|
2016-02-05 13:13:36 +01:00
|
|
|
use syntax::abi::Abi;
|
2016-03-29 08:50:44 +03:00
|
|
|
use hir;
|
2017-01-21 15:15:23 +08:00
|
|
|
use lint;
|
2016-11-08 14:02:55 +11:00
|
|
|
use util::nodemap::FxHashMap;
|
2014-09-12 10:53:35 -04:00
|
|
|
|
2016-05-11 14:40:24 -07:00
|
|
|
struct InferredObligationsSnapshotVecDelegate<'tcx> {
|
|
|
|
phantom: PhantomData<&'tcx i32>,
|
|
|
|
}
|
|
|
|
impl<'tcx> SnapshotVecDelegate for InferredObligationsSnapshotVecDelegate<'tcx> {
|
|
|
|
type Value = PredicateObligation<'tcx>;
|
|
|
|
type Undo = ();
|
|
|
|
fn reverse(_: &mut Vec<Self::Value>, _: Self::Undo) {}
|
|
|
|
}
|
|
|
|
|
2016-05-03 05:23:22 +03:00
|
|
|
pub struct SelectionContext<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
|
|
|
|
infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
|
2015-06-25 13:08:10 -07:00
|
|
|
|
2014-12-12 06:13:42 -05:00
|
|
|
/// Freshener used specifically for skolemizing entries on the
|
2014-10-09 17:19:50 -04:00
|
|
|
/// obligation stack. This ensures that all entries on the stack
|
|
|
|
/// at one time will have the same set of skolemized entries,
|
|
|
|
/// which is important for checking for trait bounds that
|
|
|
|
/// recursively require themselves.
|
2016-04-29 06:00:23 +03:00
|
|
|
freshener: TypeFreshener<'cx, 'gcx, 'tcx>,
|
2014-11-03 14:48:03 -05:00
|
|
|
|
|
|
|
/// If true, indicates that the evaluation should be conservative
|
|
|
|
/// and consider the possibility of types outside this crate.
|
|
|
|
/// This comes up primarily when resolving ambiguity. Imagine
|
|
|
|
/// there is some trait reference `$0 : Bar` where `$0` is an
|
|
|
|
/// inference variable. If `intercrate` is true, then we can never
|
|
|
|
/// say for sure that this reference is not implemented, even if
|
|
|
|
/// there are *no impls at all for `Bar`*, because `$0` could be
|
|
|
|
/// bound to some type that in a downstream crate that implements
|
|
|
|
/// `Bar`. This is the suitable mode for coherence. Elsewhere,
|
|
|
|
/// though, we set this to false, because we are only interested
|
|
|
|
/// in types that the user could actually have written --- in
|
|
|
|
/// other words, we consider `$0 : Bar` to be unimplemented if
|
|
|
|
/// there is no type that the user could *actually name* that
|
|
|
|
/// would satisfy it. This avoids crippling inference, basically.
|
2017-11-23 19:05:23 +02:00
|
|
|
intercrate: Option<IntercrateMode>,
|
2016-05-11 14:40:24 -07:00
|
|
|
|
|
|
|
inferred_obligations: SnapshotVec<InferredObligationsSnapshotVecDelegate<'tcx>>,
|
2017-07-23 22:30:47 +09:00
|
|
|
|
2018-01-26 17:21:43 -05:00
|
|
|
intercrate_ambiguity_causes: Option<Vec<IntercrateAmbiguityCause>>,
|
2017-07-23 22:30:47 +09:00
|
|
|
}
|
|
|
|
|
2018-01-26 17:21:43 -05:00
|
|
|
#[derive(Clone, Debug)]
|
2017-07-23 22:30:47 +09:00
|
|
|
pub enum IntercrateAmbiguityCause {
|
2017-08-01 10:27:25 +04:30
|
|
|
DownstreamCrate {
|
|
|
|
trait_desc: String,
|
|
|
|
self_desc: Option<String>,
|
|
|
|
},
|
|
|
|
UpstreamCrateUpdate {
|
|
|
|
trait_desc: String,
|
|
|
|
self_desc: Option<String>,
|
|
|
|
},
|
2014-09-18 11:08:04 -04:00
|
|
|
}
|
|
|
|
|
2017-07-25 16:52:36 +09:00
|
|
|
impl IntercrateAmbiguityCause {
|
|
|
|
/// Emits notes when the overlap is caused by complex intercrate ambiguities.
|
|
|
|
/// See #23980 for details.
|
|
|
|
pub fn add_intercrate_ambiguity_hint<'a, 'tcx>(&self,
|
|
|
|
err: &mut ::errors::DiagnosticBuilder) {
|
2017-11-23 19:05:23 +02:00
|
|
|
err.note(&self.intercrate_ambiguity_hint());
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn intercrate_ambiguity_hint(&self) -> String {
|
2017-07-25 16:52:36 +09:00
|
|
|
match self {
|
2017-08-01 10:27:25 +04:30
|
|
|
&IntercrateAmbiguityCause::DownstreamCrate { ref trait_desc, ref self_desc } => {
|
|
|
|
let self_desc = if let &Some(ref ty) = self_desc {
|
|
|
|
format!(" for type `{}`", ty)
|
|
|
|
} else { "".to_string() };
|
2017-11-23 19:05:23 +02:00
|
|
|
format!("downstream crates may implement trait `{}`{}", trait_desc, self_desc)
|
2017-07-25 16:52:36 +09:00
|
|
|
}
|
2017-08-01 10:27:25 +04:30
|
|
|
&IntercrateAmbiguityCause::UpstreamCrateUpdate { ref trait_desc, ref self_desc } => {
|
|
|
|
let self_desc = if let &Some(ref ty) = self_desc {
|
|
|
|
format!(" for type `{}`", ty)
|
|
|
|
} else { "".to_string() };
|
2017-11-23 19:05:23 +02:00
|
|
|
format!("upstream crates may add new impl of trait `{}`{} \
|
|
|
|
in future versions",
|
|
|
|
trait_desc, self_desc)
|
2017-07-25 16:52:36 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-18 11:08:04 -04:00
|
|
|
// A stack that walks back up the stack frame.
|
2014-12-05 00:03:03 -05:00
|
|
|
struct TraitObligationStack<'prev, 'tcx: 'prev> {
|
|
|
|
obligation: &'prev TraitObligation<'tcx>,
|
2014-09-12 10:53:35 -04:00
|
|
|
|
2014-10-09 17:19:50 -04:00
|
|
|
/// Trait ref from `obligation` but skolemized with the
|
2014-12-12 06:13:42 -05:00
|
|
|
/// selection-context's freshener. Used to check for recursion.
|
2014-12-17 14:16:28 -05:00
|
|
|
fresh_trait_ref: ty::PolyTraitRef<'tcx>,
|
2014-09-12 10:53:35 -04:00
|
|
|
|
2015-03-30 17:46:34 -04:00
|
|
|
previous: TraitObligationStackList<'prev, 'tcx>,
|
2014-09-17 16:12:02 -04:00
|
|
|
}
|
2014-09-12 10:53:35 -04:00
|
|
|
|
2015-01-03 22:54:18 -05:00
|
|
|
#[derive(Clone)]
|
2014-09-29 22:11:30 +03:00
|
|
|
pub struct SelectionCache<'tcx> {
|
2016-11-08 14:02:55 +11:00
|
|
|
hashmap: RefCell<FxHashMap<ty::TraitRef<'tcx>,
|
2017-07-10 17:10:30 -04:00
|
|
|
WithDepNode<SelectionResult<'tcx, SelectionCandidate<'tcx>>>>>,
|
2014-09-12 10:53:35 -04:00
|
|
|
}
|
|
|
|
|
2014-11-24 20:06:06 -05:00
|
|
|
/// The selection process begins by considering all impls, where
|
|
|
|
/// clauses, and so forth that might resolve an obligation. Sometimes
|
|
|
|
/// we'll be able to say definitively that (e.g.) an impl does not
|
2015-03-25 17:06:52 -07:00
|
|
|
/// apply to the obligation: perhaps it is defined for `usize` but the
|
2014-11-24 20:06:06 -05:00
|
|
|
/// obligation is for `int`. In that case, we drop the impl out of the
|
|
|
|
/// list. But the other cases are considered *candidates*.
|
|
|
|
///
|
2015-05-07 22:21:57 +03:00
|
|
|
/// For selection to succeed, there must be exactly one matching
|
|
|
|
/// candidate. If the obligation is fully known, this is guaranteed
|
|
|
|
/// by coherence. However, if the obligation contains type parameters
|
|
|
|
/// or variables, there may be multiple such impls.
|
2014-11-24 20:06:06 -05:00
|
|
|
///
|
2015-05-07 22:21:57 +03:00
|
|
|
/// It is not a real problem if multiple matching impls exist because
|
|
|
|
/// of type variables - it just means the obligation isn't sufficiently
|
|
|
|
/// elaborated. In that case we report an ambiguity, and the caller can
|
|
|
|
/// try again after more type information has been gathered or report a
|
|
|
|
/// "type annotations required" error.
|
|
|
|
///
|
|
|
|
/// However, with type parameters, this can be a real problem - type
|
|
|
|
/// parameters don't unify with regular types, but they *can* unify
|
|
|
|
/// with variables from blanket impls, and (unless we know its bounds
|
|
|
|
/// will always be satisfied) picking the blanket impl will be wrong
|
|
|
|
/// for at least *some* substitutions. To make this concrete, if we have
|
|
|
|
///
|
|
|
|
/// trait AsDebug { type Out : fmt::Debug; fn debug(self) -> Self::Out; }
|
|
|
|
/// impl<T: fmt::Debug> AsDebug for T {
|
|
|
|
/// type Out = T;
|
|
|
|
/// fn debug(self) -> fmt::Debug { self }
|
|
|
|
/// }
|
|
|
|
/// fn foo<T: AsDebug>(t: T) { println!("{:?}", <T as AsDebug>::debug(t)); }
|
|
|
|
///
|
|
|
|
/// we can't just use the impl to resolve the <T as AsDebug> obligation
|
|
|
|
/// - a type from another crate (that doesn't implement fmt::Debug) could
|
|
|
|
/// implement AsDebug.
|
|
|
|
///
|
|
|
|
/// Because where-clauses match the type exactly, multiple clauses can
|
|
|
|
/// only match if there are unresolved variables, and we can mostly just
|
|
|
|
/// report this ambiguity in that case. This is still a problem - we can't
|
|
|
|
/// *do anything* with ambiguities that involve only regions. This is issue
|
|
|
|
/// #21974.
|
|
|
|
///
|
|
|
|
/// If a single where-clause matches and there are no inference
|
|
|
|
/// variables left, then it definitely matches and we can just select
|
|
|
|
/// it.
|
|
|
|
///
|
|
|
|
/// In fact, we even select the where-clause when the obligation contains
|
|
|
|
/// inference variables. The can lead to inference making "leaps of logic",
|
|
|
|
/// for example in this situation:
|
|
|
|
///
|
|
|
|
/// pub trait Foo<T> { fn foo(&self) -> T; }
|
|
|
|
/// impl<T> Foo<()> for T { fn foo(&self) { } }
|
|
|
|
/// impl Foo<bool> for bool { fn foo(&self) -> bool { *self } }
|
|
|
|
///
|
|
|
|
/// pub fn foo<T>(t: T) where T: Foo<bool> {
|
|
|
|
/// println!("{:?}", <T as Foo<_>>::foo(&t));
|
|
|
|
/// }
|
|
|
|
/// fn main() { foo(false); }
|
|
|
|
///
|
|
|
|
/// Here the obligation <T as Foo<$0>> can be matched by both the blanket
|
|
|
|
/// impl and the where-clause. We select the where-clause and unify $0=bool,
|
|
|
|
/// so the program prints "false". However, if the where-clause is omitted,
|
|
|
|
/// the blanket impl is selected, we unify $0=(), and the program prints
|
|
|
|
/// "()".
|
|
|
|
///
|
|
|
|
/// Exactly the same issues apply to projection and object candidates, except
|
|
|
|
/// that we can have both a projection candidate and a where-clause candidate
|
|
|
|
/// for the same obligation. In that case either would do (except that
|
|
|
|
/// different "leaps of logic" would occur if inference variables are
|
2015-08-24 23:27:00 +03:00
|
|
|
/// present), and we just pick the where-clause. This is, for example,
|
2015-05-07 22:21:57 +03:00
|
|
|
/// required for associated types to work in default impls, as the bounds
|
|
|
|
/// are visible both as projection bounds and as where-clauses from the
|
|
|
|
/// parameter environment.
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(PartialEq,Eq,Debug,Clone)]
|
2014-12-17 14:16:28 -05:00
|
|
|
enum SelectionCandidate<'tcx> {
|
2016-04-18 00:04:21 +03:00
|
|
|
BuiltinCandidate { has_nested: bool },
|
2014-12-27 04:22:29 -05:00
|
|
|
ParamCandidate(ty::PolyTraitRef<'tcx>),
|
2015-08-16 06:32:28 -04:00
|
|
|
ImplCandidate(DefId),
|
2017-10-09 13:59:20 -03:00
|
|
|
AutoImplCandidate(DefId),
|
2014-12-01 09:23:40 -05:00
|
|
|
|
2014-12-27 04:22:29 -05:00
|
|
|
/// This is a trait matching with a projected type as `Self`, and
|
|
|
|
/// we found an applicable bound in the trait definition.
|
|
|
|
ProjectionCandidate,
|
|
|
|
|
2016-04-06 00:20:59 -07:00
|
|
|
/// Implementation of a `Fn`-family trait by one of the anonymous types
|
2017-08-15 23:30:13 +03:00
|
|
|
/// generated for a `||` expression.
|
|
|
|
ClosureCandidate,
|
2014-12-01 09:23:40 -05:00
|
|
|
|
2016-12-26 14:34:03 +01:00
|
|
|
/// Implementation of a `Generator` trait by one of the anonymous types
|
|
|
|
/// generated for a generator.
|
2017-08-15 23:30:13 +03:00
|
|
|
GeneratorCandidate,
|
2016-12-26 14:34:03 +01:00
|
|
|
|
2014-12-01 09:23:40 -05:00
|
|
|
/// Implementation of a `Fn`-family trait by one of the anonymous
|
|
|
|
/// types generated for a fn pointer type (e.g., `fn(int)->int`)
|
|
|
|
FnPointerCandidate,
|
|
|
|
|
2014-12-23 05:26:34 -05:00
|
|
|
ObjectCandidate,
|
|
|
|
|
2015-02-18 11:58:44 -05:00
|
|
|
BuiltinObjectCandidate,
|
|
|
|
|
2015-04-15 11:57:29 +12:00
|
|
|
BuiltinUnsizeCandidate,
|
2014-09-12 10:53:35 -04:00
|
|
|
}
|
|
|
|
|
2016-04-29 06:00:23 +03:00
|
|
|
impl<'a, 'tcx> ty::Lift<'tcx> for SelectionCandidate<'a> {
|
|
|
|
type Lifted = SelectionCandidate<'tcx>;
|
|
|
|
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
|
|
|
|
Some(match *self {
|
|
|
|
BuiltinCandidate { has_nested } => {
|
|
|
|
BuiltinCandidate {
|
2017-07-03 11:19:51 -07:00
|
|
|
has_nested,
|
2016-04-29 06:00:23 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
ImplCandidate(def_id) => ImplCandidate(def_id),
|
2017-10-09 13:59:20 -03:00
|
|
|
AutoImplCandidate(def_id) => AutoImplCandidate(def_id),
|
2016-04-29 06:00:23 +03:00
|
|
|
ProjectionCandidate => ProjectionCandidate,
|
|
|
|
FnPointerCandidate => FnPointerCandidate,
|
|
|
|
ObjectCandidate => ObjectCandidate,
|
|
|
|
BuiltinObjectCandidate => BuiltinObjectCandidate,
|
|
|
|
BuiltinUnsizeCandidate => BuiltinUnsizeCandidate,
|
2017-08-15 23:30:13 +03:00
|
|
|
ClosureCandidate => ClosureCandidate,
|
|
|
|
GeneratorCandidate => GeneratorCandidate,
|
2016-04-29 06:00:23 +03:00
|
|
|
|
|
|
|
ParamCandidate(ref trait_ref) => {
|
|
|
|
return tcx.lift(trait_ref).map(ParamCandidate);
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-17 14:16:28 -05:00
|
|
|
struct SelectionCandidateSet<'tcx> {
|
2014-12-30 08:59:33 -05:00
|
|
|
// a list of candidates that definitely apply to the current
|
|
|
|
// obligation (meaning: types unify).
|
2014-12-17 14:16:28 -05:00
|
|
|
vec: Vec<SelectionCandidate<'tcx>>,
|
2014-12-30 08:59:33 -05:00
|
|
|
|
|
|
|
// if this is true, then there were candidates that might or might
|
|
|
|
// not have applied, but we couldn't tell. This occurs when some
|
|
|
|
// of the input types are type variables, in which case there are
|
|
|
|
// various "builtin" rules that might or might not trigger.
|
|
|
|
ambiguous: bool,
|
2014-10-09 17:19:50 -04:00
|
|
|
}
|
|
|
|
|
2015-12-22 10:20:47 -08:00
|
|
|
#[derive(PartialEq,Eq,Debug,Clone)]
|
|
|
|
struct EvaluatedCandidate<'tcx> {
|
|
|
|
candidate: SelectionCandidate<'tcx>,
|
|
|
|
evaluation: EvaluationResult,
|
|
|
|
}
|
|
|
|
|
2016-04-14 15:49:39 +03:00
|
|
|
/// When does the builtin impl for `T: Trait` apply?
|
|
|
|
enum BuiltinImplConditions<'tcx> {
|
|
|
|
/// The impl is conditional on T1,T2,.. : Trait
|
|
|
|
Where(ty::Binder<Vec<Ty<'tcx>>>),
|
|
|
|
/// There is no built-in impl. There may be some other
|
|
|
|
/// candidate (a where-clause or user-defined impl).
|
|
|
|
None,
|
|
|
|
/// There is *no* impl for this, builtin or not. Ignore
|
|
|
|
/// all where-clauses.
|
2016-04-18 00:04:21 +03:00
|
|
|
Never,
|
2016-04-14 15:49:39 +03:00
|
|
|
/// It is unknown whether there is an impl.
|
|
|
|
Ambiguous
|
2014-10-09 17:19:50 -04:00
|
|
|
}
|
|
|
|
|
2015-10-18 19:15:57 +03:00
|
|
|
#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
|
|
|
|
/// The result of trait evaluation. The order is important
|
|
|
|
/// here as the evaluation of a list is the maximum of the
|
|
|
|
/// evaluations.
|
2017-06-30 14:18:04 +03:00
|
|
|
///
|
|
|
|
/// The evaluation results are ordered:
|
|
|
|
/// - `EvaluatedToOk` implies `EvaluatedToAmbig` implies `EvaluatedToUnknown`
|
|
|
|
/// - `EvaluatedToErr` implies `EvaluatedToRecur`
|
|
|
|
/// - the "union" of evaluation results is equal to their maximum -
|
|
|
|
/// all the "potential success" candidates can potentially succeed,
|
|
|
|
/// so they are no-ops when unioned with a definite error, and within
|
|
|
|
/// the categories it's easy to see that the unions are correct.
|
2015-10-18 19:15:57 +03:00
|
|
|
enum EvaluationResult {
|
|
|
|
/// Evaluation successful
|
2014-10-09 17:19:50 -04:00
|
|
|
EvaluatedToOk,
|
2017-06-30 14:18:04 +03:00
|
|
|
/// Evaluation is known to be ambiguous - it *might* hold for some
|
|
|
|
/// assignment of inference variables, but it might not.
|
|
|
|
///
|
|
|
|
/// While this has the same meaning as `EvaluatedToUnknown` - we can't
|
|
|
|
/// know whether this obligation holds or not - it is the result we
|
|
|
|
/// would get with an empty stack, and therefore is cacheable.
|
2014-10-09 17:19:50 -04:00
|
|
|
EvaluatedToAmbig,
|
2017-06-30 14:18:04 +03:00
|
|
|
/// Evaluation failed because of recursion involving inference
|
|
|
|
/// variables. We are somewhat imprecise there, so we don't actually
|
|
|
|
/// know the real result.
|
|
|
|
///
|
|
|
|
/// This can't be trivially cached for the same reason as `EvaluatedToRecur`.
|
|
|
|
EvaluatedToUnknown,
|
|
|
|
/// Evaluation failed because we encountered an obligation we are already
|
|
|
|
/// trying to prove on this branch.
|
|
|
|
///
|
|
|
|
/// We know this branch can't be a part of a minimal proof-tree for
|
|
|
|
/// the "root" of our cycle, because then we could cut out the recursion
|
|
|
|
/// and maintain a valid proof tree. However, this does not mean
|
|
|
|
/// that all the obligations on this branch do not hold - it's possible
|
|
|
|
/// that we entered this branch "speculatively", and that there
|
|
|
|
/// might be some other way to prove this obligation that does not
|
|
|
|
/// go through this cycle - so we can't cache this as a failure.
|
|
|
|
///
|
|
|
|
/// For example, suppose we have this:
|
|
|
|
///
|
|
|
|
/// ```rust,ignore (pseudo-Rust)
|
|
|
|
/// pub trait Trait { fn xyz(); }
|
|
|
|
/// // This impl is "useless", but we can still have
|
|
|
|
/// // an `impl Trait for SomeUnsizedType` somewhere.
|
|
|
|
/// impl<T: Trait + Sized> Trait for T { fn xyz() {} }
|
|
|
|
///
|
|
|
|
/// pub fn foo<T: Trait + ?Sized>() {
|
|
|
|
/// <T as Trait>::xyz();
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// When checking `foo`, we have to prove `T: Trait`. This basically
|
|
|
|
/// translates into this:
|
|
|
|
///
|
|
|
|
/// (T: Trait + Sized →_\impl T: Trait), T: Trait ⊢ T: Trait
|
|
|
|
///
|
|
|
|
/// When we try to prove it, we first go the first option, which
|
|
|
|
/// recurses. This shows us that the impl is "useless" - it won't
|
|
|
|
/// tell us that `T: Trait` unless it already implemented `Trait`
|
|
|
|
/// by some other means. However, that does not prevent `T: Trait`
|
|
|
|
/// does not hold, because of the bound (which can indeed be satisfied
|
|
|
|
/// by `SomeUnsizedType` from another crate).
|
|
|
|
///
|
|
|
|
/// FIXME: when an `EvaluatedToRecur` goes past its parent root, we
|
|
|
|
/// ought to convert it to an `EvaluatedToErr`, because we know
|
|
|
|
/// there definitely isn't a proof tree for that obligation. Not
|
|
|
|
/// doing so is still sound - there isn't any proof tree, so the
|
|
|
|
/// branch still can't be a part of a minimal one - but does not
|
|
|
|
/// re-enable caching.
|
|
|
|
EvaluatedToRecur,
|
2015-10-18 19:15:57 +03:00
|
|
|
/// Evaluation failed
|
|
|
|
EvaluatedToErr,
|
|
|
|
}
|
|
|
|
|
2017-06-30 14:18:04 +03:00
|
|
|
impl EvaluationResult {
|
|
|
|
fn may_apply(self) -> bool {
|
|
|
|
match self {
|
|
|
|
EvaluatedToOk |
|
|
|
|
EvaluatedToAmbig |
|
|
|
|
EvaluatedToUnknown => true,
|
|
|
|
|
|
|
|
EvaluatedToErr |
|
|
|
|
EvaluatedToRecur => false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn is_stack_dependent(self) -> bool {
|
|
|
|
match self {
|
|
|
|
EvaluatedToUnknown |
|
|
|
|
EvaluatedToRecur => true,
|
|
|
|
|
|
|
|
EvaluatedToOk |
|
|
|
|
EvaluatedToAmbig |
|
|
|
|
EvaluatedToErr => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-18 19:15:57 +03:00
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct EvaluationCache<'tcx> {
|
2017-07-10 17:10:30 -04:00
|
|
|
hashmap: RefCell<FxHashMap<ty::PolyTraitRef<'tcx>, WithDepNode<EvaluationResult>>>
|
2014-09-12 10:53:35 -04:00
|
|
|
}
|
|
|
|
|
2016-04-29 06:00:23 +03:00
|
|
|
impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|
|
|
pub fn new(infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>) -> SelectionContext<'cx, 'gcx, 'tcx> {
|
2014-11-03 14:48:03 -05:00
|
|
|
SelectionContext {
|
2017-07-03 11:19:51 -07:00
|
|
|
infcx,
|
2014-12-12 06:13:42 -05:00
|
|
|
freshener: infcx.freshener(),
|
2017-11-23 19:05:23 +02:00
|
|
|
intercrate: None,
|
2016-05-11 14:40:24 -07:00
|
|
|
inferred_obligations: SnapshotVec::new(),
|
2018-01-26 17:21:43 -05:00
|
|
|
intercrate_ambiguity_causes: None,
|
2016-02-23 12:47:09 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-23 19:05:23 +02:00
|
|
|
pub fn intercrate(infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
|
|
|
|
mode: IntercrateMode) -> SelectionContext<'cx, 'gcx, 'tcx> {
|
|
|
|
debug!("intercrate({:?})", mode);
|
2016-02-23 12:47:09 -08:00
|
|
|
SelectionContext {
|
2017-07-03 11:19:51 -07:00
|
|
|
infcx,
|
2016-02-23 12:47:09 -08:00
|
|
|
freshener: infcx.freshener(),
|
2017-11-23 19:05:23 +02:00
|
|
|
intercrate: Some(mode),
|
2016-05-11 14:40:24 -07:00
|
|
|
inferred_obligations: SnapshotVec::new(),
|
2018-01-26 17:21:43 -05:00
|
|
|
intercrate_ambiguity_causes: None,
|
2014-09-18 11:08:04 -04:00
|
|
|
}
|
2014-09-12 10:53:35 -04:00
|
|
|
}
|
|
|
|
|
2018-01-26 17:21:43 -05:00
|
|
|
/// Enables tracking of intercrate ambiguity causes. These are
|
|
|
|
/// used in coherence to give improved diagnostics. We don't do
|
|
|
|
/// this until we detect a coherence error because it can lead to
|
|
|
|
/// false overflow results (#47139) and because it costs
|
|
|
|
/// computation time.
|
|
|
|
pub fn enable_tracking_intercrate_ambiguity_causes(&mut self) {
|
|
|
|
assert!(self.intercrate.is_some());
|
|
|
|
assert!(self.intercrate_ambiguity_causes.is_none());
|
|
|
|
self.intercrate_ambiguity_causes = Some(vec![]);
|
|
|
|
debug!("selcx: enable_tracking_intercrate_ambiguity_causes");
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Gets the intercrate ambiguity causes collected since tracking
|
|
|
|
/// was enabled and disables tracking at the same time. If
|
|
|
|
/// tracking is not enabled, just returns an empty vector.
|
|
|
|
pub fn take_intercrate_ambiguity_causes(&mut self) -> Vec<IntercrateAmbiguityCause> {
|
|
|
|
assert!(self.intercrate.is_some());
|
|
|
|
self.intercrate_ambiguity_causes.take().unwrap_or(vec![])
|
|
|
|
}
|
|
|
|
|
2016-04-29 06:00:23 +03:00
|
|
|
pub fn infcx(&self) -> &'cx InferCtxt<'cx, 'gcx, 'tcx> {
|
2014-12-07 11:10:48 -05:00
|
|
|
self.infcx
|
|
|
|
}
|
|
|
|
|
2016-04-29 06:00:23 +03:00
|
|
|
pub fn tcx(&self) -> TyCtxt<'cx, 'gcx, 'tcx> {
|
2014-09-12 10:53:35 -04:00
|
|
|
self.infcx.tcx
|
|
|
|
}
|
|
|
|
|
2016-04-29 06:00:23 +03:00
|
|
|
pub fn closure_typer(&self) -> &'cx InferCtxt<'cx, 'gcx, 'tcx> {
|
2015-06-30 02:18:03 -07:00
|
|
|
self.infcx
|
2015-01-10 11:54:15 -05:00
|
|
|
}
|
|
|
|
|
2016-05-11 17:22:13 -07:00
|
|
|
/// Wraps the inference context's in_snapshot s.t. snapshot handling is only from the selection
|
|
|
|
/// context's self.
|
|
|
|
fn in_snapshot<R, F>(&mut self, f: F) -> R
|
|
|
|
where F: FnOnce(&mut Self, &infer::CombinedSnapshot) -> R
|
|
|
|
{
|
|
|
|
// The irrefutable nature of the operation means we don't need to snapshot the
|
|
|
|
// inferred_obligations vector.
|
|
|
|
self.infcx.in_snapshot(|snapshot| f(self, snapshot))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Wraps a probe s.t. obligations collected during it are ignored and old obligations are
|
|
|
|
/// retained.
|
|
|
|
fn probe<R, F>(&mut self, f: F) -> R
|
|
|
|
where F: FnOnce(&mut Self, &infer::CombinedSnapshot) -> R
|
|
|
|
{
|
|
|
|
let inferred_obligations_snapshot = self.inferred_obligations.start_snapshot();
|
|
|
|
let result = self.infcx.probe(|snapshot| f(self, snapshot));
|
|
|
|
self.inferred_obligations.rollback_to(inferred_obligations_snapshot);
|
|
|
|
result
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Wraps a commit_if_ok s.t. obligations collected during it are not returned in selection if
|
|
|
|
/// the transaction fails and s.t. old obligations are retained.
|
|
|
|
fn commit_if_ok<T, E, F>(&mut self, f: F) -> Result<T, E> where
|
|
|
|
F: FnOnce(&mut Self, &infer::CombinedSnapshot) -> Result<T, E>
|
|
|
|
{
|
|
|
|
let inferred_obligations_snapshot = self.inferred_obligations.start_snapshot();
|
|
|
|
match self.infcx.commit_if_ok(|snapshot| f(self, snapshot)) {
|
|
|
|
Ok(ok) => {
|
|
|
|
self.inferred_obligations.commit(inferred_obligations_snapshot);
|
|
|
|
Ok(ok)
|
|
|
|
},
|
|
|
|
Err(err) => {
|
|
|
|
self.inferred_obligations.rollback_to(inferred_obligations_snapshot);
|
|
|
|
Err(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-09-12 10:53:35 -04:00
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// Selection
|
|
|
|
//
|
|
|
|
// The selection phase tries to identify *how* an obligation will
|
|
|
|
// be resolved. For example, it will identify which impl or
|
|
|
|
// parameter bound is to be used. The process can be inconclusive
|
|
|
|
// if the self type in the obligation is not fully inferred. Selection
|
|
|
|
// can result in an error in one of two ways:
|
|
|
|
//
|
|
|
|
// 1. If no applicable impl or parameter bound can be found.
|
|
|
|
// 2. If the output type parameters in the obligation do not match
|
|
|
|
// those specified by the impl/bound. For example, if the obligation
|
|
|
|
// is `Vec<Foo>:Iterable<Bar>`, but the impl specifies
|
|
|
|
// `impl<T> Iterable<T> for Vec<T>`, than an error would result.
|
|
|
|
|
2015-02-02 11:52:08 -05:00
|
|
|
/// Attempts to satisfy the obligation. If successful, this will affect the surrounding
|
|
|
|
/// type environment by performing unification.
|
2014-12-05 00:03:03 -05:00
|
|
|
pub fn select(&mut self, obligation: &TraitObligation<'tcx>)
|
2014-09-29 22:11:30 +03:00
|
|
|
-> SelectionResult<'tcx, Selection<'tcx>> {
|
2015-06-18 20:25:05 +03:00
|
|
|
debug!("select({:?})", obligation);
|
2014-12-17 16:00:34 -05:00
|
|
|
assert!(!obligation.predicate.has_escaping_regions());
|
2014-09-12 10:53:35 -04:00
|
|
|
|
2017-01-11 15:58:37 +08:00
|
|
|
let tcx = self.tcx();
|
2015-12-22 16:35:02 -05:00
|
|
|
|
2015-03-30 17:46:34 -04:00
|
|
|
let stack = self.push_stack(TraitObligationStackList::empty(), obligation);
|
2017-01-11 15:58:37 +08:00
|
|
|
let ret = match self.candidate_from_obligation(&stack)? {
|
|
|
|
None => None,
|
2016-05-11 17:22:13 -07:00
|
|
|
Some(candidate) => {
|
|
|
|
let mut candidate = self.confirm_candidate(obligation, candidate)?;
|
|
|
|
let inferred_obligations = (*self.inferred_obligations).into_iter().cloned();
|
|
|
|
candidate.nested_obligations_mut().extend(inferred_obligations);
|
2017-01-11 15:58:37 +08:00
|
|
|
Some(candidate)
|
2016-05-11 17:22:13 -07:00
|
|
|
},
|
2017-01-11 15:58:37 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
// Test whether this is a `()` which was produced by defaulting a
|
|
|
|
// diverging type variable with `!` disabled. If so, we may need
|
|
|
|
// to raise a warning.
|
2017-01-21 14:02:43 +08:00
|
|
|
if obligation.predicate.skip_binder().self_ty().is_defaulted_unit() {
|
2017-01-11 15:58:37 +08:00
|
|
|
let mut raise_warning = true;
|
|
|
|
// Don't raise a warning if the trait is implemented for ! and only
|
|
|
|
// permits a trivial implementation for !. This stops us warning
|
|
|
|
// about (for example) `(): Clone` becoming `!: Clone` because such
|
|
|
|
// a switch can't cause code to stop compiling or execute
|
|
|
|
// differently.
|
|
|
|
let mut never_obligation = obligation.clone();
|
|
|
|
let def_id = never_obligation.predicate.skip_binder().trait_ref.def_id;
|
|
|
|
never_obligation.predicate = never_obligation.predicate.map_bound(|mut trait_pred| {
|
|
|
|
// Swap out () with ! so we can check if the trait is impld for !
|
|
|
|
{
|
2017-08-01 13:03:03 +01:00
|
|
|
let trait_ref = &mut trait_pred.trait_ref;
|
2017-01-11 15:58:37 +08:00
|
|
|
let unit_substs = trait_ref.substs;
|
|
|
|
let mut never_substs = Vec::with_capacity(unit_substs.len());
|
|
|
|
never_substs.push(From::from(tcx.types.never));
|
|
|
|
never_substs.extend(&unit_substs[1..]);
|
|
|
|
trait_ref.substs = tcx.intern_substs(&never_substs);
|
|
|
|
}
|
|
|
|
trait_pred
|
|
|
|
});
|
|
|
|
if let Ok(Some(..)) = self.select(&never_obligation) {
|
|
|
|
if !tcx.trait_relevant_for_never(def_id) {
|
|
|
|
// The trait is also implemented for ! and the resulting
|
|
|
|
// implementation cannot actually be invoked in any way.
|
|
|
|
raise_warning = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if raise_warning {
|
2017-07-26 21:51:09 -07:00
|
|
|
tcx.lint_node(lint::builtin::RESOLVE_TRAIT_ON_DEFAULTED_UNIT,
|
|
|
|
obligation.cause.body_id,
|
|
|
|
obligation.cause.span,
|
|
|
|
&format!("code relies on type inference rules which are likely \
|
|
|
|
to change"));
|
2017-01-11 15:58:37 +08:00
|
|
|
}
|
2014-09-12 10:53:35 -04:00
|
|
|
}
|
2017-01-11 15:58:37 +08:00
|
|
|
Ok(ret)
|
2014-09-12 10:53:35 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// EVALUATION
|
|
|
|
//
|
2014-10-17 08:51:43 -04:00
|
|
|
// Tests whether an obligation can be selected or whether an impl
|
|
|
|
// can be applied to particular types. It skips the "confirmation"
|
|
|
|
// step and hence completely ignores output type parameters.
|
2014-10-09 17:19:50 -04:00
|
|
|
//
|
2014-10-25 23:10:16 -04:00
|
|
|
// The result is "true" if the obligation *may* hold and "false" if
|
2014-10-09 17:19:50 -04:00
|
|
|
// we can be sure it does not.
|
2014-09-12 10:53:35 -04:00
|
|
|
|
2014-11-25 21:17:11 -05:00
|
|
|
/// Evaluates whether the obligation `obligation` can be satisfied (by any means).
|
2014-11-03 14:48:03 -05:00
|
|
|
pub fn evaluate_obligation(&mut self,
|
2014-12-07 11:10:48 -05:00
|
|
|
obligation: &PredicateObligation<'tcx>)
|
2014-11-03 14:48:03 -05:00
|
|
|
-> bool
|
2014-09-12 10:53:35 -04:00
|
|
|
{
|
2015-06-18 20:25:05 +03:00
|
|
|
debug!("evaluate_obligation({:?})",
|
|
|
|
obligation);
|
2014-09-12 10:53:35 -04:00
|
|
|
|
2016-05-11 17:22:13 -07:00
|
|
|
self.probe(|this, _| {
|
|
|
|
this.evaluate_predicate_recursively(TraitObligationStackList::empty(), obligation)
|
2015-10-20 18:23:46 +03:00
|
|
|
.may_apply()
|
|
|
|
})
|
2014-09-18 11:08:04 -04:00
|
|
|
}
|
|
|
|
|
2015-10-20 19:14:05 +03:00
|
|
|
/// Evaluates whether the obligation `obligation` can be satisfied,
|
|
|
|
/// and returns `false` if not certain. However, this is not entirely
|
|
|
|
/// accurate if inference variables are involved.
|
|
|
|
pub fn evaluate_obligation_conservatively(&mut self,
|
|
|
|
obligation: &PredicateObligation<'tcx>)
|
2015-12-22 16:35:02 -05:00
|
|
|
-> bool
|
2015-10-20 19:14:05 +03:00
|
|
|
{
|
|
|
|
debug!("evaluate_obligation_conservatively({:?})",
|
|
|
|
obligation);
|
|
|
|
|
2016-05-11 17:22:13 -07:00
|
|
|
self.probe(|this, _| {
|
|
|
|
this.evaluate_predicate_recursively(TraitObligationStackList::empty(), obligation)
|
2015-10-20 19:14:05 +03:00
|
|
|
== EvaluatedToOk
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2015-11-15 20:11:42 +02:00
|
|
|
/// Evaluates the predicates in `predicates` recursively. Note that
|
|
|
|
/// this applies projections in the predicates, and therefore
|
|
|
|
/// is run within an inference probe.
|
2015-01-02 11:39:47 -05:00
|
|
|
fn evaluate_predicates_recursively<'a,'o,I>(&mut self,
|
2015-03-30 17:46:34 -04:00
|
|
|
stack: TraitObligationStackList<'o, 'tcx>,
|
2015-01-31 09:17:50 -05:00
|
|
|
predicates: I)
|
2015-10-18 19:15:57 +03:00
|
|
|
-> EvaluationResult
|
2015-01-01 23:26:38 -05:00
|
|
|
where I : Iterator<Item=&'a PredicateObligation<'tcx>>, 'tcx:'a
|
2015-01-02 11:39:47 -05:00
|
|
|
{
|
|
|
|
let mut result = EvaluatedToOk;
|
|
|
|
for obligation in predicates {
|
2015-10-20 18:23:46 +03:00
|
|
|
let eval = self.evaluate_predicate_recursively(stack, obligation);
|
|
|
|
debug!("evaluate_predicate_recursively({:?}) = {:?}",
|
|
|
|
obligation, eval);
|
2017-06-30 14:18:04 +03:00
|
|
|
if let EvaluatedToErr = eval {
|
|
|
|
// fast-path - EvaluatedToErr is the top of the lattice,
|
|
|
|
// so we don't need to look on the other predicates.
|
|
|
|
return EvaluatedToErr;
|
|
|
|
} else {
|
|
|
|
result = cmp::max(result, eval);
|
2015-01-02 11:39:47 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
result
|
|
|
|
}
|
|
|
|
|
2014-12-07 11:10:48 -05:00
|
|
|
fn evaluate_predicate_recursively<'o>(&mut self,
|
2015-03-30 17:46:34 -04:00
|
|
|
previous_stack: TraitObligationStackList<'o, 'tcx>,
|
2014-12-07 11:10:48 -05:00
|
|
|
obligation: &PredicateObligation<'tcx>)
|
2015-10-18 19:15:57 +03:00
|
|
|
-> EvaluationResult
|
2014-12-07 11:10:48 -05:00
|
|
|
{
|
2015-06-18 20:25:05 +03:00
|
|
|
debug!("evaluate_predicate_recursively({:?})",
|
|
|
|
obligation);
|
2014-12-07 11:10:48 -05:00
|
|
|
|
2014-12-17 16:00:34 -05:00
|
|
|
match obligation.predicate {
|
2014-12-07 11:10:48 -05:00
|
|
|
ty::Predicate::Trait(ref t) => {
|
|
|
|
assert!(!t.has_escaping_regions());
|
|
|
|
let obligation = obligation.with(t.clone());
|
2017-06-23 00:27:47 +03:00
|
|
|
self.evaluate_trait_predicate_recursively(previous_stack, obligation)
|
2014-12-07 11:10:48 -05:00
|
|
|
}
|
|
|
|
|
2014-12-13 05:34:34 -05:00
|
|
|
ty::Predicate::Equate(ref p) => {
|
2015-10-20 18:23:46 +03:00
|
|
|
// does this code ever run?
|
2017-05-23 04:19:47 -04:00
|
|
|
match self.infcx.equality_predicate(&obligation.cause, obligation.param_env, p) {
|
2016-03-29 20:06:42 -07:00
|
|
|
Ok(InferOk { obligations, .. }) => {
|
2016-05-11 17:22:13 -07:00
|
|
|
self.inferred_obligations.extend(obligations);
|
2016-03-29 20:06:42 -07:00
|
|
|
EvaluatedToOk
|
|
|
|
},
|
2015-10-18 19:15:57 +03:00
|
|
|
Err(_) => EvaluatedToErr
|
2014-12-07 11:10:48 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-09 21:47:09 -05:00
|
|
|
ty::Predicate::Subtype(ref p) => {
|
|
|
|
// does this code ever run?
|
2017-05-23 04:19:47 -04:00
|
|
|
match self.infcx.subtype_predicate(&obligation.cause, obligation.param_env, p) {
|
2017-03-09 21:47:09 -05:00
|
|
|
Some(Ok(InferOk { obligations, .. })) => {
|
|
|
|
self.inferred_obligations.extend(obligations);
|
|
|
|
EvaluatedToOk
|
|
|
|
},
|
|
|
|
Some(Err(_)) => EvaluatedToErr,
|
|
|
|
None => EvaluatedToAmbig,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-07 09:30:19 -04:00
|
|
|
ty::Predicate::WellFormed(ty) => {
|
2017-05-24 12:01:53 -04:00
|
|
|
match ty::wf::obligations(self.infcx,
|
|
|
|
obligation.param_env,
|
|
|
|
obligation.cause.body_id,
|
2015-12-15 04:31:58 -05:00
|
|
|
ty, obligation.cause.span) {
|
2015-08-07 09:30:19 -04:00
|
|
|
Some(obligations) =>
|
|
|
|
self.evaluate_predicates_recursively(previous_stack, obligations.iter()),
|
|
|
|
None =>
|
|
|
|
EvaluatedToAmbig,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-07 11:10:48 -05:00
|
|
|
ty::Predicate::TypeOutlives(..) | ty::Predicate::RegionOutlives(..) => {
|
|
|
|
// we do not consider region relationships when
|
|
|
|
// evaluating trait matches
|
|
|
|
EvaluatedToOk
|
|
|
|
}
|
2015-08-07 09:30:19 -04:00
|
|
|
|
|
|
|
ty::Predicate::ObjectSafe(trait_def_id) => {
|
2016-03-17 00:15:31 +02:00
|
|
|
if self.tcx().is_object_safe(trait_def_id) {
|
2015-08-07 09:30:19 -04:00
|
|
|
EvaluatedToOk
|
|
|
|
} else {
|
2015-10-18 19:15:57 +03:00
|
|
|
EvaluatedToErr
|
2015-08-07 09:30:19 -04:00
|
|
|
}
|
|
|
|
}
|
2014-12-17 14:16:28 -05:00
|
|
|
|
2015-01-02 11:39:47 -05:00
|
|
|
ty::Predicate::Projection(ref data) => {
|
2015-10-20 18:23:46 +03:00
|
|
|
let project_obligation = obligation.with(data.clone());
|
|
|
|
match project::poly_project_and_unify_type(self, &project_obligation) {
|
|
|
|
Ok(Some(subobligations)) => {
|
2017-08-20 19:16:36 +03:00
|
|
|
let result = self.evaluate_predicates_recursively(previous_stack,
|
|
|
|
subobligations.iter());
|
|
|
|
if let Some(key) =
|
|
|
|
ProjectionCacheKey::from_poly_projection_predicate(self, data)
|
|
|
|
{
|
|
|
|
self.infcx.projection_cache.borrow_mut().complete(key);
|
|
|
|
}
|
|
|
|
result
|
2015-01-02 11:39:47 -05:00
|
|
|
}
|
2015-10-20 18:23:46 +03:00
|
|
|
Ok(None) => {
|
|
|
|
EvaluatedToAmbig
|
|
|
|
}
|
|
|
|
Err(_) => {
|
|
|
|
EvaluatedToErr
|
|
|
|
}
|
|
|
|
}
|
2014-12-17 14:16:28 -05:00
|
|
|
}
|
2016-04-06 00:20:59 -07:00
|
|
|
|
2017-11-08 08:52:24 -05:00
|
|
|
ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
|
2017-11-08 09:45:48 -05:00
|
|
|
match self.infcx.closure_kind(closure_def_id, closure_substs) {
|
2016-04-06 00:20:59 -07:00
|
|
|
Some(closure_kind) => {
|
|
|
|
if closure_kind.extends(kind) {
|
|
|
|
EvaluatedToOk
|
|
|
|
} else {
|
|
|
|
EvaluatedToErr
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
EvaluatedToAmbig
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-08-07 08:08:53 +03:00
|
|
|
|
|
|
|
ty::Predicate::ConstEvaluatable(def_id, substs) => {
|
|
|
|
match self.tcx().lift_to_global(&(obligation.param_env, substs)) {
|
|
|
|
Some((param_env, substs)) => {
|
|
|
|
match self.tcx().const_eval(param_env.and((def_id, substs))) {
|
|
|
|
Ok(_) => EvaluatedToOk,
|
|
|
|
Err(_) => EvaluatedToErr
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
// Inference variables still left in param_env or substs.
|
|
|
|
EvaluatedToAmbig
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-12-07 11:10:48 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-23 00:27:47 +03:00
|
|
|
fn evaluate_trait_predicate_recursively<'o>(&mut self,
|
|
|
|
previous_stack: TraitObligationStackList<'o, 'tcx>,
|
|
|
|
mut obligation: TraitObligation<'tcx>)
|
|
|
|
-> EvaluationResult
|
2014-09-18 11:08:04 -04:00
|
|
|
{
|
2017-06-23 00:27:47 +03:00
|
|
|
debug!("evaluate_trait_predicate_recursively({:?})",
|
2015-06-18 20:25:05 +03:00
|
|
|
obligation);
|
2014-09-18 11:08:04 -04:00
|
|
|
|
2017-11-23 19:05:23 +02:00
|
|
|
if !self.intercrate.is_some() && obligation.is_global() {
|
2017-06-23 00:27:47 +03:00
|
|
|
// If a param env is consistent, global obligations do not depend on its particular
|
|
|
|
// value in order to work, so we can clear out the param env and get better
|
|
|
|
// caching. (If the current param env is inconsistent, we don't care what happens).
|
|
|
|
debug!("evaluate_trait_predicate_recursively({:?}) - in global", obligation);
|
|
|
|
obligation.param_env = ty::ParamEnv::empty(obligation.param_env.reveal);
|
|
|
|
}
|
|
|
|
|
|
|
|
let stack = self.push_stack(previous_stack, &obligation);
|
2015-10-18 19:15:57 +03:00
|
|
|
let fresh_trait_ref = stack.fresh_trait_ref;
|
2017-05-23 04:19:47 -04:00
|
|
|
if let Some(result) = self.check_evaluation_cache(obligation.param_env, fresh_trait_ref) {
|
2015-10-18 19:15:57 +03:00
|
|
|
debug!("CACHE HIT: EVAL({:?})={:?}",
|
|
|
|
fresh_trait_ref,
|
|
|
|
result);
|
|
|
|
return result;
|
|
|
|
}
|
2014-10-17 08:51:43 -04:00
|
|
|
|
2017-07-10 17:10:30 -04:00
|
|
|
let (result, dep_node) = self.in_task(|this| this.evaluate_stack(&stack));
|
2014-10-17 08:51:43 -04:00
|
|
|
|
2015-10-18 19:15:57 +03:00
|
|
|
debug!("CACHE MISS: EVAL({:?})={:?}",
|
|
|
|
fresh_trait_ref,
|
|
|
|
result);
|
2017-07-10 17:10:30 -04:00
|
|
|
self.insert_evaluation_cache(obligation.param_env, fresh_trait_ref, dep_node, result);
|
2015-10-18 19:15:57 +03:00
|
|
|
|
2014-10-09 17:17:49 -04:00
|
|
|
result
|
2014-10-09 17:19:50 -04:00
|
|
|
}
|
|
|
|
|
2014-09-29 22:11:30 +03:00
|
|
|
fn evaluate_stack<'o>(&mut self,
|
2014-12-05 00:03:03 -05:00
|
|
|
stack: &TraitObligationStack<'o, 'tcx>)
|
2015-10-18 19:15:57 +03:00
|
|
|
-> EvaluationResult
|
2014-10-09 17:19:50 -04:00
|
|
|
{
|
2014-11-03 14:48:03 -05:00
|
|
|
// In intercrate mode, whenever any of the types are unbound,
|
|
|
|
// there can always be an impl. Even if there are no impls in
|
|
|
|
// this crate, perhaps the type would be unified with
|
|
|
|
// something from another crate that does provide an impl.
|
|
|
|
//
|
2016-02-16 10:36:47 -08:00
|
|
|
// In intra mode, we must still be conservative. The reason is
|
2014-11-03 14:48:03 -05:00
|
|
|
// that we want to avoid cycles. Imagine an impl like:
|
|
|
|
//
|
|
|
|
// impl<T:Eq> Eq for Vec<T>
|
|
|
|
//
|
|
|
|
// and a trait reference like `$0 : Eq` where `$0` is an
|
|
|
|
// unbound variable. When we evaluate this trait-reference, we
|
|
|
|
// will unify `$0` with `Vec<$1>` (for some fresh variable
|
|
|
|
// `$1`), on the condition that `$1 : Eq`. We will then wind
|
|
|
|
// up with many candidates (since that are other `Eq` impls
|
|
|
|
// that apply) and try to winnow things down. This results in
|
2015-01-06 20:53:18 -05:00
|
|
|
// a recursive evaluation that `$1 : Eq` -- as you can
|
2014-11-03 14:48:03 -05:00
|
|
|
// imagine, this is just where we started. To avoid that, we
|
|
|
|
// check for unbound variables and return an ambiguous (hence possible)
|
|
|
|
// match if we've seen this trait before.
|
|
|
|
//
|
|
|
|
// This suffices to allow chains like `FnMut` implemented in
|
|
|
|
// terms of `Fn` etc, but we could probably make this more
|
|
|
|
// precise still.
|
2016-08-18 08:32:50 +03:00
|
|
|
let unbound_input_types = stack.fresh_trait_ref.input_types().any(|ty| ty.is_fresh());
|
2017-11-23 19:05:23 +02:00
|
|
|
// this check was an imperfect workaround for a bug n the old
|
|
|
|
// intercrate mode, it should be removed when that goes away.
|
|
|
|
if unbound_input_types &&
|
|
|
|
self.intercrate == Some(IntercrateMode::Issue43355)
|
|
|
|
{
|
2015-10-18 19:15:57 +03:00
|
|
|
debug!("evaluate_stack({:?}) --> unbound argument, intercrate --> ambiguous",
|
|
|
|
stack.fresh_trait_ref);
|
2017-07-23 22:30:47 +09:00
|
|
|
// Heuristics: show the diagnostics when there are no candidates in crate.
|
2018-01-26 17:21:43 -05:00
|
|
|
if self.intercrate_ambiguity_causes.is_some() {
|
|
|
|
debug!("evaluate_stack: intercrate_ambiguity_causes is some");
|
|
|
|
if let Ok(candidate_set) = self.assemble_candidates(stack) {
|
|
|
|
if !candidate_set.ambiguous && candidate_set.vec.is_empty() {
|
|
|
|
let trait_ref = stack.obligation.predicate.skip_binder().trait_ref;
|
|
|
|
let self_ty = trait_ref.self_ty();
|
|
|
|
let cause = IntercrateAmbiguityCause::DownstreamCrate {
|
|
|
|
trait_desc: trait_ref.to_string(),
|
|
|
|
self_desc: if self_ty.has_concrete_skeleton() {
|
|
|
|
Some(self_ty.to_string())
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
},
|
|
|
|
};
|
|
|
|
debug!("evaluate_stack: pushing cause = {:?}", cause);
|
|
|
|
self.intercrate_ambiguity_causes.as_mut().unwrap().push(cause);
|
|
|
|
}
|
2017-07-23 22:30:47 +09:00
|
|
|
}
|
|
|
|
}
|
2015-10-18 19:15:57 +03:00
|
|
|
return EvaluatedToAmbig;
|
|
|
|
}
|
|
|
|
if unbound_input_types &&
|
2014-11-03 14:48:03 -05:00
|
|
|
stack.iter().skip(1).any(
|
2017-06-23 00:27:47 +03:00
|
|
|
|prev| stack.obligation.param_env == prev.obligation.param_env &&
|
|
|
|
self.match_fresh_trait_refs(&stack.fresh_trait_ref,
|
|
|
|
&prev.fresh_trait_ref))
|
2014-11-03 14:48:03 -05:00
|
|
|
{
|
2015-10-18 19:15:57 +03:00
|
|
|
debug!("evaluate_stack({:?}) --> unbound argument, recursive --> giving up",
|
2015-06-18 20:25:05 +03:00
|
|
|
stack.fresh_trait_ref);
|
2015-10-18 19:15:57 +03:00
|
|
|
return EvaluatedToUnknown;
|
2014-10-09 17:19:50 -04:00
|
|
|
}
|
|
|
|
|
2014-09-18 11:08:04 -04:00
|
|
|
// If there is any previous entry on the stack that precisely
|
|
|
|
// matches this obligation, then we can assume that the
|
|
|
|
// obligation is satisfied for now (still all other conditions
|
|
|
|
// must be met of course). One obvious case this comes up is
|
2014-11-17 14:41:47 -05:00
|
|
|
// marker traits like `Send`. Think of a linked list:
|
2014-09-18 11:08:04 -04:00
|
|
|
//
|
|
|
|
// struct List<T> { data: T, next: Option<Box<List<T>>> {
|
|
|
|
//
|
|
|
|
// `Box<List<T>>` will be `Send` if `T` is `Send` and
|
|
|
|
// `Option<Box<List<T>>>` is `Send`, and in turn
|
|
|
|
// `Option<Box<List<T>>>` is `Send` if `Box<List<T>>` is
|
|
|
|
// `Send`.
|
2014-10-09 17:19:50 -04:00
|
|
|
//
|
2014-12-12 06:13:42 -05:00
|
|
|
// Note that we do this comparison using the `fresh_trait_ref`
|
2014-10-09 17:19:50 -04:00
|
|
|
// fields. Because these have all been skolemized using
|
2014-12-12 06:13:42 -05:00
|
|
|
// `self.freshener`, we can be sure that (a) this will not
|
2014-10-09 17:19:50 -04:00
|
|
|
// affect the inferencer state and (b) that if we see two
|
|
|
|
// skolemized types with the same index, they refer to the
|
|
|
|
// same unbound type variable.
|
2017-06-26 17:23:15 +03:00
|
|
|
if let Some(rec_index) =
|
2014-10-09 17:19:50 -04:00
|
|
|
stack.iter()
|
|
|
|
.skip(1) // skip top-most frame
|
2017-06-23 00:27:47 +03:00
|
|
|
.position(|prev| stack.obligation.param_env == prev.obligation.param_env &&
|
|
|
|
stack.fresh_trait_ref == prev.fresh_trait_ref)
|
2014-09-18 11:08:04 -04:00
|
|
|
{
|
2015-06-18 20:25:05 +03:00
|
|
|
debug!("evaluate_stack({:?}) --> recursive",
|
|
|
|
stack.fresh_trait_ref);
|
2017-06-26 17:23:15 +03:00
|
|
|
let cycle = stack.iter().skip(1).take(rec_index+1);
|
|
|
|
let cycle = cycle.map(|stack| ty::Predicate::Trait(stack.obligation.predicate));
|
|
|
|
if self.coinductive_match(cycle) {
|
|
|
|
debug!("evaluate_stack({:?}) --> recursive, coinductive",
|
|
|
|
stack.fresh_trait_ref);
|
|
|
|
return EvaluatedToOk;
|
|
|
|
} else {
|
|
|
|
debug!("evaluate_stack({:?}) --> recursive, inductive",
|
|
|
|
stack.fresh_trait_ref);
|
2017-06-30 14:18:04 +03:00
|
|
|
return EvaluatedToRecur;
|
2017-06-26 17:23:15 +03:00
|
|
|
}
|
2014-09-18 11:08:04 -04:00
|
|
|
}
|
|
|
|
|
2014-10-09 17:19:50 -04:00
|
|
|
match self.candidate_from_obligation(stack) {
|
2015-10-20 18:23:46 +03:00
|
|
|
Ok(Some(c)) => self.evaluate_candidate(stack, &c),
|
2014-10-09 17:19:50 -04:00
|
|
|
Ok(None) => EvaluatedToAmbig,
|
2015-10-18 19:15:57 +03:00
|
|
|
Err(..) => EvaluatedToErr
|
2014-09-12 10:53:35 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-26 17:23:15 +03:00
|
|
|
/// For defaulted traits, we use a co-inductive strategy to solve, so
|
|
|
|
/// that recursion is ok. This routine returns true if the top of the
|
|
|
|
/// stack (`cycle[0]`):
|
2017-12-31 17:17:01 +01:00
|
|
|
///
|
2017-06-26 17:23:15 +03:00
|
|
|
/// - is a defaulted trait, and
|
|
|
|
/// - it also appears in the backtrace at some position `X`; and,
|
|
|
|
/// - all the predicates at positions `X..` between `X` an the top are
|
|
|
|
/// also defaulted traits.
|
|
|
|
pub fn coinductive_match<I>(&mut self, cycle: I) -> bool
|
|
|
|
where I: Iterator<Item=ty::Predicate<'tcx>>
|
|
|
|
{
|
|
|
|
let mut cycle = cycle;
|
|
|
|
cycle.all(|predicate| self.coinductive_predicate(predicate))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn coinductive_predicate(&self, predicate: ty::Predicate<'tcx>) -> bool {
|
|
|
|
let result = match predicate {
|
|
|
|
ty::Predicate::Trait(ref data) => {
|
2017-10-16 17:33:45 -02:00
|
|
|
self.tcx().trait_is_auto(data.def_id())
|
2017-06-26 17:23:15 +03:00
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
};
|
|
|
|
debug!("coinductive_predicate({:?}) = {:?}", predicate, result);
|
|
|
|
result
|
|
|
|
}
|
|
|
|
|
2015-10-20 18:23:46 +03:00
|
|
|
/// Further evaluate `candidate` to decide whether all type parameters match and whether nested
|
|
|
|
/// obligations are met. Returns true if `candidate` remains viable after this further
|
|
|
|
/// scrutiny.
|
|
|
|
fn evaluate_candidate<'o>(&mut self,
|
|
|
|
stack: &TraitObligationStack<'o, 'tcx>,
|
|
|
|
candidate: &SelectionCandidate<'tcx>)
|
|
|
|
-> EvaluationResult
|
2014-09-12 10:53:35 -04:00
|
|
|
{
|
2015-10-20 18:23:46 +03:00
|
|
|
debug!("evaluate_candidate: depth={} candidate={:?}",
|
|
|
|
stack.obligation.recursion_depth, candidate);
|
2016-05-11 17:22:13 -07:00
|
|
|
let result = self.probe(|this, _| {
|
2015-10-20 18:23:46 +03:00
|
|
|
let candidate = (*candidate).clone();
|
2016-05-11 17:22:13 -07:00
|
|
|
match this.confirm_candidate(stack.obligation, candidate) {
|
2015-10-20 18:23:46 +03:00
|
|
|
Ok(selection) => {
|
2016-05-11 17:22:13 -07:00
|
|
|
this.evaluate_predicates_recursively(
|
2015-10-20 18:23:46 +03:00
|
|
|
stack.list(),
|
|
|
|
selection.nested_obligations().iter())
|
2014-10-17 08:51:43 -04:00
|
|
|
}
|
2015-10-20 18:23:46 +03:00
|
|
|
Err(..) => EvaluatedToErr
|
2014-10-17 08:51:43 -04:00
|
|
|
}
|
2015-10-20 18:23:46 +03:00
|
|
|
});
|
|
|
|
debug!("evaluate_candidate: depth={} result={:?}",
|
|
|
|
stack.obligation.recursion_depth, result);
|
|
|
|
result
|
2014-10-17 08:51:43 -04:00
|
|
|
}
|
|
|
|
|
2017-05-23 04:19:47 -04:00
|
|
|
fn check_evaluation_cache(&self,
|
|
|
|
param_env: ty::ParamEnv<'tcx>,
|
|
|
|
trait_ref: ty::PolyTraitRef<'tcx>)
|
2015-10-18 19:15:57 +03:00
|
|
|
-> Option<EvaluationResult>
|
|
|
|
{
|
2017-07-10 17:10:30 -04:00
|
|
|
let tcx = self.tcx();
|
2017-05-23 04:19:47 -04:00
|
|
|
if self.can_use_global_caches(param_env) {
|
2017-07-10 17:10:30 -04:00
|
|
|
let cache = tcx.evaluation_cache.hashmap.borrow();
|
2016-04-29 06:00:23 +03:00
|
|
|
if let Some(cached) = cache.get(&trait_ref) {
|
2017-07-10 17:10:30 -04:00
|
|
|
return Some(cached.get(tcx));
|
2016-04-29 06:00:23 +03:00
|
|
|
}
|
|
|
|
}
|
2017-07-10 17:10:30 -04:00
|
|
|
self.infcx.evaluation_cache.hashmap
|
|
|
|
.borrow()
|
|
|
|
.get(&trait_ref)
|
|
|
|
.map(|v| v.get(tcx))
|
2015-10-18 19:15:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
fn insert_evaluation_cache(&mut self,
|
2017-05-23 04:19:47 -04:00
|
|
|
param_env: ty::ParamEnv<'tcx>,
|
2015-10-18 19:15:57 +03:00
|
|
|
trait_ref: ty::PolyTraitRef<'tcx>,
|
2017-07-10 17:10:30 -04:00
|
|
|
dep_node: DepNodeIndex,
|
2015-10-18 19:15:57 +03:00
|
|
|
result: EvaluationResult)
|
|
|
|
{
|
2017-08-17 17:38:16 +03:00
|
|
|
// Avoid caching results that depend on more than just the trait-ref
|
|
|
|
// - the stack can create recursion.
|
|
|
|
if result.is_stack_dependent() {
|
2015-10-18 19:15:57 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-05-23 04:19:47 -04:00
|
|
|
if self.can_use_global_caches(param_env) {
|
2016-04-29 06:00:23 +03:00
|
|
|
let mut cache = self.tcx().evaluation_cache.hashmap.borrow_mut();
|
|
|
|
if let Some(trait_ref) = self.tcx().lift_to_global(&trait_ref) {
|
2017-07-10 17:10:30 -04:00
|
|
|
cache.insert(trait_ref, WithDepNode::new(dep_node, result));
|
2016-04-29 06:00:23 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-10 17:10:30 -04:00
|
|
|
self.infcx.evaluation_cache.hashmap
|
|
|
|
.borrow_mut()
|
|
|
|
.insert(trait_ref, WithDepNode::new(dep_node, result));
|
2015-10-18 19:15:57 +03:00
|
|
|
}
|
|
|
|
|
2014-09-12 10:53:35 -04:00
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// CANDIDATE ASSEMBLY
|
|
|
|
//
|
|
|
|
// The selection process begins by examining all in-scope impls,
|
|
|
|
// caller obligations, and so forth and assembling a list of
|
2015-02-18 19:34:55 -08:00
|
|
|
// candidates. See `README.md` and the `Candidate` type for more
|
|
|
|
// details.
|
2014-09-12 10:53:35 -04:00
|
|
|
|
2014-09-29 22:11:30 +03:00
|
|
|
fn candidate_from_obligation<'o>(&mut self,
|
2014-12-05 00:03:03 -05:00
|
|
|
stack: &TraitObligationStack<'o, 'tcx>)
|
2014-12-17 14:16:28 -05:00
|
|
|
-> SelectionResult<'tcx, SelectionCandidate<'tcx>>
|
2014-09-12 10:53:35 -04:00
|
|
|
{
|
2014-10-09 17:19:50 -04:00
|
|
|
// Watch out for overflow. This intentionally bypasses (and does
|
|
|
|
// not update) the cache.
|
|
|
|
let recursion_limit = self.infcx.tcx.sess.recursion_limit.get();
|
|
|
|
if stack.obligation.recursion_depth >= recursion_limit {
|
2016-03-17 00:15:31 +02:00
|
|
|
self.infcx().report_overflow_error(&stack.obligation, true);
|
2014-10-09 17:19:50 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Check the cache. Note that we skolemize the trait-ref
|
2014-12-12 06:13:42 -05:00
|
|
|
// separately rather than using `stack.fresh_trait_ref` -- this
|
2014-10-09 17:19:50 -04:00
|
|
|
// is because we want the unbound variables to be replaced
|
|
|
|
// with fresh skolemized types starting from index 0.
|
2014-12-17 14:16:28 -05:00
|
|
|
let cache_fresh_trait_pred =
|
2014-12-17 16:00:34 -05:00
|
|
|
self.infcx.freshen(stack.obligation.predicate.clone());
|
2015-06-18 20:25:05 +03:00
|
|
|
debug!("candidate_from_obligation(cache_fresh_trait_pred={:?}, obligation={:?})",
|
|
|
|
cache_fresh_trait_pred,
|
|
|
|
stack);
|
2014-12-17 16:00:34 -05:00
|
|
|
assert!(!stack.obligation.predicate.has_escaping_regions());
|
2014-09-12 10:53:35 -04:00
|
|
|
|
2017-05-23 04:19:47 -04:00
|
|
|
if let Some(c) = self.check_candidate_cache(stack.obligation.param_env,
|
|
|
|
&cache_fresh_trait_pred) {
|
2016-10-17 19:00:20 -07:00
|
|
|
debug!("CACHE HIT: SELECT({:?})={:?}",
|
|
|
|
cache_fresh_trait_pred,
|
|
|
|
c);
|
|
|
|
return c;
|
2014-09-12 10:53:35 -04:00
|
|
|
}
|
|
|
|
|
2014-09-18 11:08:04 -04:00
|
|
|
// If no match, compute result and insert into cache.
|
2017-07-10 17:10:30 -04:00
|
|
|
let (candidate, dep_node) = self.in_task(|this| {
|
|
|
|
this.candidate_from_obligation_no_cache(stack)
|
|
|
|
});
|
2015-01-21 17:45:52 -05:00
|
|
|
|
2017-08-17 17:38:16 +03:00
|
|
|
debug!("CACHE MISS: SELECT({:?})={:?}",
|
|
|
|
cache_fresh_trait_pred, candidate);
|
|
|
|
self.insert_candidate_cache(stack.obligation.param_env,
|
|
|
|
cache_fresh_trait_pred,
|
|
|
|
dep_node,
|
|
|
|
candidate.clone());
|
2014-10-09 17:19:50 -04:00
|
|
|
candidate
|
2014-09-18 11:08:04 -04:00
|
|
|
}
|
|
|
|
|
2017-07-10 17:10:30 -04:00
|
|
|
fn in_task<OP, R>(&mut self, op: OP) -> (R, DepNodeIndex)
|
|
|
|
where OP: FnOnce(&mut Self) -> R
|
|
|
|
{
|
|
|
|
let (result, dep_node) = self.tcx().dep_graph.with_anon_task(DepKind::TraitSelect, || {
|
|
|
|
op(self)
|
|
|
|
});
|
|
|
|
self.tcx().dep_graph.read_index(dep_node);
|
|
|
|
(result, dep_node)
|
|
|
|
}
|
|
|
|
|
2015-12-22 10:20:47 -08:00
|
|
|
// Treat negative impls as unimplemented
|
|
|
|
fn filter_negative_impls(&self, candidate: SelectionCandidate<'tcx>)
|
|
|
|
-> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
|
|
|
|
if let ImplCandidate(def_id) = candidate {
|
2017-04-24 15:20:46 +03:00
|
|
|
if self.tcx().impl_polarity(def_id) == hir::ImplPolarity::Negative {
|
2015-12-22 10:20:47 -08:00
|
|
|
return Err(Unimplemented)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(Some(candidate))
|
|
|
|
}
|
|
|
|
|
2014-09-29 22:11:30 +03:00
|
|
|
fn candidate_from_obligation_no_cache<'o>(&mut self,
|
2014-12-05 00:03:03 -05:00
|
|
|
stack: &TraitObligationStack<'o, 'tcx>)
|
2014-12-17 14:16:28 -05:00
|
|
|
-> SelectionResult<'tcx, SelectionCandidate<'tcx>>
|
2014-09-18 11:08:04 -04:00
|
|
|
{
|
2016-01-07 16:48:48 -05:00
|
|
|
if stack.obligation.predicate.references_error() {
|
|
|
|
// If we encounter a `TyError`, we generally prefer the
|
|
|
|
// most "optimistic" result in response -- that is, the
|
|
|
|
// one least likely to report downstream errors. But
|
|
|
|
// because this routine is shared by coherence and by
|
|
|
|
// trait selection, there isn't an obvious "right" choice
|
|
|
|
// here in that respect, so we opt to just return
|
|
|
|
// ambiguity and let the upstream clients sort it out.
|
|
|
|
return Ok(None);
|
2014-09-18 11:08:04 -04:00
|
|
|
}
|
|
|
|
|
2017-11-22 23:01:51 +02:00
|
|
|
match self.is_knowable(stack) {
|
|
|
|
None => {}
|
|
|
|
Some(conflict) => {
|
|
|
|
debug!("coherence stage: not knowable");
|
2018-01-26 17:21:43 -05:00
|
|
|
if self.intercrate_ambiguity_causes.is_some() {
|
|
|
|
debug!("evaluate_stack: intercrate_ambiguity_causes is some");
|
|
|
|
// Heuristics: show the diagnostics when there are no candidates in crate.
|
|
|
|
let candidate_set = self.assemble_candidates(stack)?;
|
|
|
|
if !candidate_set.ambiguous && candidate_set.vec.iter().all(|c| {
|
|
|
|
!self.evaluate_candidate(stack, &c).may_apply()
|
|
|
|
}) {
|
|
|
|
let trait_ref = stack.obligation.predicate.skip_binder().trait_ref;
|
|
|
|
let self_ty = trait_ref.self_ty();
|
|
|
|
let trait_desc = trait_ref.to_string();
|
|
|
|
let self_desc = if self_ty.has_concrete_skeleton() {
|
|
|
|
Some(self_ty.to_string())
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
};
|
|
|
|
let cause = if let Conflict::Upstream = conflict {
|
|
|
|
IntercrateAmbiguityCause::UpstreamCrateUpdate { trait_desc, self_desc }
|
|
|
|
} else {
|
|
|
|
IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc }
|
|
|
|
};
|
|
|
|
debug!("evaluate_stack: pushing cause = {:?}", cause);
|
|
|
|
self.intercrate_ambiguity_causes.as_mut().unwrap().push(cause);
|
|
|
|
}
|
2017-11-22 23:01:51 +02:00
|
|
|
}
|
|
|
|
return Ok(None);
|
2017-07-23 22:30:47 +09:00
|
|
|
}
|
2015-03-30 17:46:34 -04:00
|
|
|
}
|
|
|
|
|
2016-03-22 22:01:37 -05:00
|
|
|
let candidate_set = self.assemble_candidates(stack)?;
|
2014-10-09 17:19:50 -04:00
|
|
|
|
|
|
|
if candidate_set.ambiguous {
|
|
|
|
debug!("candidate set contains ambig");
|
|
|
|
return Ok(None);
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut candidates = candidate_set.vec;
|
2014-09-12 10:53:35 -04:00
|
|
|
|
2015-06-18 20:25:05 +03:00
|
|
|
debug!("assembled {} candidates for {:?}: {:?}",
|
2014-12-27 04:22:29 -05:00
|
|
|
candidates.len(),
|
2015-06-18 20:25:05 +03:00
|
|
|
stack,
|
|
|
|
candidates);
|
2014-09-12 10:53:35 -04:00
|
|
|
|
2014-10-09 17:19:50 -04:00
|
|
|
// At this point, we know that each of the entries in the
|
|
|
|
// candidate set is *individually* applicable. Now we have to
|
|
|
|
// figure out if they contain mutual incompatibilities. This
|
|
|
|
// frequently arises if we have an unconstrained input type --
|
|
|
|
// for example, we are looking for $0:Eq where $0 is some
|
|
|
|
// unconstrained type variable. In that case, we'll get a
|
|
|
|
// candidate which assumes $0 == int, one that assumes $0 ==
|
2015-03-25 17:06:52 -07:00
|
|
|
// usize, etc. This spells an ambiguity.
|
2014-10-09 17:19:50 -04:00
|
|
|
|
|
|
|
// If there is more than one candidate, first winnow them down
|
|
|
|
// by considering extra conditions (nested obligations and so
|
|
|
|
// forth). We don't winnow if there is exactly one
|
|
|
|
// candidate. This is a relatively minor distinction but it
|
|
|
|
// can lead to better inference and error-reporting. An
|
|
|
|
// example would be if there was an impl:
|
|
|
|
//
|
|
|
|
// impl<T:Clone> Vec<T> { fn push_clone(...) { ... } }
|
|
|
|
//
|
|
|
|
// and we were to see some code `foo.push_clone()` where `boo`
|
|
|
|
// is a `Vec<Bar>` and `Bar` does not implement `Clone`. If
|
|
|
|
// we were to winnow, we'd wind up with zero candidates.
|
|
|
|
// Instead, we select the right impl now but report `Bar does
|
|
|
|
// not implement Clone`.
|
2015-12-22 10:20:47 -08:00
|
|
|
if candidates.len() == 1 {
|
|
|
|
return self.filter_negative_impls(candidates.pop().unwrap());
|
2014-10-09 17:19:50 -04:00
|
|
|
}
|
|
|
|
|
2015-12-22 10:20:47 -08:00
|
|
|
// Winnow, but record the exact outcome of evaluation, which
|
|
|
|
// is needed for specialization.
|
|
|
|
let mut candidates: Vec<_> = candidates.into_iter().filter_map(|c| {
|
|
|
|
let eval = self.evaluate_candidate(stack, &c);
|
|
|
|
if eval.may_apply() {
|
|
|
|
Some(EvaluatedCandidate {
|
|
|
|
candidate: c,
|
|
|
|
evaluation: eval,
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}).collect();
|
|
|
|
|
|
|
|
// If there are STILL multiple candidate, we can further
|
|
|
|
// reduce the list by dropping duplicates -- including
|
|
|
|
// resolving specializations.
|
2014-10-09 17:19:50 -04:00
|
|
|
if candidates.len() > 1 {
|
|
|
|
let mut i = 0;
|
|
|
|
while i < candidates.len() {
|
|
|
|
let is_dup =
|
2015-01-26 16:05:07 -05:00
|
|
|
(0..candidates.len())
|
2014-10-09 17:19:50 -04:00
|
|
|
.filter(|&j| i != j)
|
2015-02-16 06:57:38 -05:00
|
|
|
.any(|j| self.candidate_should_be_dropped_in_favor_of(&candidates[i],
|
2014-10-09 17:19:50 -04:00
|
|
|
&candidates[j]));
|
|
|
|
if is_dup {
|
2015-06-18 20:25:05 +03:00
|
|
|
debug!("Dropping candidate #{}/{}: {:?}",
|
|
|
|
i, candidates.len(), candidates[i]);
|
2014-10-09 17:19:50 -04:00
|
|
|
candidates.swap_remove(i);
|
|
|
|
} else {
|
2015-06-18 20:25:05 +03:00
|
|
|
debug!("Retaining candidate #{}/{}: {:?}",
|
|
|
|
i, candidates.len(), candidates[i]);
|
2014-10-09 17:19:50 -04:00
|
|
|
i += 1;
|
2017-04-22 15:05:18 +03:00
|
|
|
|
|
|
|
// If there are *STILL* multiple candidates, give up
|
|
|
|
// and report ambiguity.
|
|
|
|
if i > 1 {
|
|
|
|
debug!("multiple matches, ambig");
|
|
|
|
return Ok(None);
|
|
|
|
}
|
2014-10-09 17:19:50 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-04 10:57:02 -08:00
|
|
|
// If there are *NO* candidates, then there are no impls --
|
2014-10-17 08:51:43 -04:00
|
|
|
// that we know of, anyway. Note that in the case where there
|
|
|
|
// are unbound type variables within the obligation, it might
|
|
|
|
// be the case that you could still satisfy the obligation
|
|
|
|
// from another crate by instantiating the type variables with
|
|
|
|
// a type from another crate that does have an impl. This case
|
2014-11-03 14:48:03 -05:00
|
|
|
// is checked for in `evaluate_stack` (and hence users
|
2014-10-17 08:51:43 -04:00
|
|
|
// who might care about this case, like coherence, should use
|
|
|
|
// that function).
|
2015-03-24 16:53:34 -07:00
|
|
|
if candidates.is_empty() {
|
2014-10-17 08:51:43 -04:00
|
|
|
return Err(Unimplemented);
|
2014-09-12 10:53:35 -04:00
|
|
|
}
|
2014-10-09 17:19:50 -04:00
|
|
|
|
|
|
|
// Just one candidate left.
|
2015-12-22 10:20:47 -08:00
|
|
|
self.filter_negative_impls(candidates.pop().unwrap().candidate)
|
2014-09-17 16:12:02 -04:00
|
|
|
}
|
2014-09-12 10:53:35 -04:00
|
|
|
|
2015-03-30 17:46:34 -04:00
|
|
|
fn is_knowable<'o>(&mut self,
|
|
|
|
stack: &TraitObligationStack<'o, 'tcx>)
|
2017-11-22 23:01:51 +02:00
|
|
|
-> Option<Conflict>
|
2015-03-30 17:46:34 -04:00
|
|
|
{
|
2017-11-23 19:05:23 +02:00
|
|
|
debug!("is_knowable(intercrate={:?})", self.intercrate);
|
2015-03-30 17:46:34 -04:00
|
|
|
|
2017-11-23 19:05:23 +02:00
|
|
|
if !self.intercrate.is_some() {
|
2017-11-22 23:01:51 +02:00
|
|
|
return None;
|
2015-03-30 17:46:34 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
let obligation = &stack.obligation;
|
|
|
|
let predicate = self.infcx().resolve_type_vars_if_possible(&obligation.predicate);
|
|
|
|
|
|
|
|
// ok to skip binder because of the nature of the
|
|
|
|
// trait-ref-is-knowable check, which does not care about
|
|
|
|
// bound regions
|
2017-08-28 16:50:41 -04:00
|
|
|
let trait_ref = predicate.skip_binder().trait_ref;
|
2015-03-30 17:46:34 -04:00
|
|
|
|
2017-11-23 19:05:23 +02:00
|
|
|
let result = coherence::trait_ref_is_knowable(self.tcx(), trait_ref);
|
|
|
|
if let (Some(Conflict::Downstream { used_to_be_broken: true }),
|
|
|
|
Some(IntercrateMode::Issue43355)) = (result, self.intercrate) {
|
|
|
|
debug!("is_knowable: IGNORING conflict to be bug-compatible with #43355");
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
result
|
|
|
|
}
|
2015-03-30 17:46:34 -04:00
|
|
|
}
|
|
|
|
|
2016-04-29 06:00:23 +03:00
|
|
|
/// Returns true if the global caches can be used.
|
|
|
|
/// Do note that if the type itself is not in the
|
|
|
|
/// global tcx, the local caches will be used.
|
2017-05-23 04:19:47 -04:00
|
|
|
fn can_use_global_caches(&self, param_env: ty::ParamEnv<'tcx>) -> bool {
|
2015-02-06 19:11:50 -05:00
|
|
|
// If there are any where-clauses in scope, then we always use
|
|
|
|
// a cache local to this particular scope. Otherwise, we
|
|
|
|
// switch to a global cache. We used to try and draw
|
|
|
|
// finer-grained distinctions, but that led to a serious of
|
|
|
|
// annoying and weird bugs like #22019 and #18290. This simple
|
|
|
|
// rule seems to be pretty clearly safe and also still retains
|
|
|
|
// a very high hit rate (~95% when compiling rustc).
|
2017-05-23 04:19:47 -04:00
|
|
|
if !param_env.caller_bounds.is_empty() {
|
2016-04-29 06:00:23 +03:00
|
|
|
return false;
|
2015-02-06 19:11:50 -05:00
|
|
|
}
|
2014-10-22 11:35:53 -04:00
|
|
|
|
2014-11-03 14:48:03 -05:00
|
|
|
// Avoid using the master cache during coherence and just rely
|
|
|
|
// on the local cache. This effectively disables caching
|
|
|
|
// during coherence. It is really just a simplification to
|
|
|
|
// avoid us having to fear that coherence results "pollute"
|
|
|
|
// the master cache. Since coherence executes pretty quickly,
|
|
|
|
// it's not worth going to more trouble to increase the
|
|
|
|
// hit-rate I don't think.
|
2017-11-23 19:05:23 +02:00
|
|
|
if self.intercrate.is_some() {
|
2016-04-29 06:00:23 +03:00
|
|
|
return false;
|
2014-11-03 14:48:03 -05:00
|
|
|
}
|
|
|
|
|
2014-10-22 11:35:53 -04:00
|
|
|
// Otherwise, we can use the global cache.
|
2016-04-29 06:00:23 +03:00
|
|
|
true
|
2014-09-12 10:53:35 -04:00
|
|
|
}
|
|
|
|
|
2014-09-18 11:08:04 -04:00
|
|
|
fn check_candidate_cache(&mut self,
|
2017-05-23 04:19:47 -04:00
|
|
|
param_env: ty::ParamEnv<'tcx>,
|
2014-12-17 14:16:28 -05:00
|
|
|
cache_fresh_trait_pred: &ty::PolyTraitPredicate<'tcx>)
|
|
|
|
-> Option<SelectionResult<'tcx, SelectionCandidate<'tcx>>>
|
2014-09-12 10:53:35 -04:00
|
|
|
{
|
2017-07-10 17:10:30 -04:00
|
|
|
let tcx = self.tcx();
|
2016-04-29 06:00:23 +03:00
|
|
|
let trait_ref = &cache_fresh_trait_pred.0.trait_ref;
|
2017-05-23 04:19:47 -04:00
|
|
|
if self.can_use_global_caches(param_env) {
|
2017-07-10 17:10:30 -04:00
|
|
|
let cache = tcx.selection_cache.hashmap.borrow();
|
2016-04-29 06:00:23 +03:00
|
|
|
if let Some(cached) = cache.get(&trait_ref) {
|
2017-07-10 17:10:30 -04:00
|
|
|
return Some(cached.get(tcx));
|
2016-04-29 06:00:23 +03:00
|
|
|
}
|
|
|
|
}
|
2017-07-10 17:10:30 -04:00
|
|
|
self.infcx.selection_cache.hashmap
|
|
|
|
.borrow()
|
|
|
|
.get(trait_ref)
|
|
|
|
.map(|v| v.get(tcx))
|
2014-09-12 10:53:35 -04:00
|
|
|
}
|
|
|
|
|
2014-09-18 11:08:04 -04:00
|
|
|
fn insert_candidate_cache(&mut self,
|
2017-05-23 04:19:47 -04:00
|
|
|
param_env: ty::ParamEnv<'tcx>,
|
2014-12-17 14:16:28 -05:00
|
|
|
cache_fresh_trait_pred: ty::PolyTraitPredicate<'tcx>,
|
2017-07-10 17:10:30 -04:00
|
|
|
dep_node: DepNodeIndex,
|
2014-12-17 14:16:28 -05:00
|
|
|
candidate: SelectionResult<'tcx, SelectionCandidate<'tcx>>)
|
2014-09-12 10:53:35 -04:00
|
|
|
{
|
2017-07-10 17:10:30 -04:00
|
|
|
let tcx = self.tcx();
|
2016-04-29 06:00:23 +03:00
|
|
|
let trait_ref = cache_fresh_trait_pred.0.trait_ref;
|
2017-05-23 04:19:47 -04:00
|
|
|
if self.can_use_global_caches(param_env) {
|
2017-07-10 17:10:30 -04:00
|
|
|
let mut cache = tcx.selection_cache.hashmap.borrow_mut();
|
|
|
|
if let Some(trait_ref) = tcx.lift_to_global(&trait_ref) {
|
|
|
|
if let Some(candidate) = tcx.lift_to_global(&candidate) {
|
|
|
|
cache.insert(trait_ref, WithDepNode::new(dep_node, candidate));
|
2016-04-29 06:00:23 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-10 17:10:30 -04:00
|
|
|
self.infcx.selection_cache.hashmap
|
|
|
|
.borrow_mut()
|
|
|
|
.insert(trait_ref, WithDepNode::new(dep_node, candidate));
|
2014-09-12 10:53:35 -04:00
|
|
|
}
|
|
|
|
|
2014-09-29 22:11:30 +03:00
|
|
|
fn assemble_candidates<'o>(&mut self,
|
2014-12-05 00:03:03 -05:00
|
|
|
stack: &TraitObligationStack<'o, 'tcx>)
|
2014-12-17 14:16:28 -05:00
|
|
|
-> Result<SelectionCandidateSet<'tcx>, SelectionError<'tcx>>
|
2014-09-12 10:53:35 -04:00
|
|
|
{
|
2014-12-05 00:03:03 -05:00
|
|
|
let TraitObligationStack { obligation, .. } = *stack;
|
2015-08-24 23:27:00 +03:00
|
|
|
let ref obligation = Obligation {
|
2017-05-23 04:19:47 -04:00
|
|
|
param_env: obligation.param_env,
|
2015-08-24 23:27:00 +03:00
|
|
|
cause: obligation.cause.clone(),
|
|
|
|
recursion_depth: obligation.recursion_depth,
|
|
|
|
predicate: self.infcx().resolve_type_vars_if_possible(&obligation.predicate)
|
|
|
|
};
|
|
|
|
|
|
|
|
if obligation.predicate.skip_binder().self_ty().is_ty_var() {
|
2017-10-07 13:19:34 +03:00
|
|
|
// Self is a type variable (e.g. `_: AsRef<str>`).
|
2015-08-24 23:27:00 +03:00
|
|
|
//
|
|
|
|
// This is somewhat problematic, as the current scheme can't really
|
|
|
|
// handle it turning to be a projection. This does end up as truly
|
|
|
|
// ambiguous in most cases anyway.
|
|
|
|
//
|
2017-10-07 13:19:34 +03:00
|
|
|
// Take the fast path out - this also improves
|
2015-08-24 23:27:00 +03:00
|
|
|
// performance by preventing assemble_candidates_from_impls from
|
|
|
|
// matching every impl for this trait.
|
|
|
|
return Ok(SelectionCandidateSet { vec: vec![], ambiguous: true });
|
|
|
|
}
|
2014-09-18 11:08:04 -04:00
|
|
|
|
2014-12-17 14:16:28 -05:00
|
|
|
let mut candidates = SelectionCandidateSet {
|
2014-10-09 17:19:50 -04:00
|
|
|
vec: Vec::new(),
|
|
|
|
ambiguous: false
|
|
|
|
};
|
2014-09-12 10:53:35 -04:00
|
|
|
|
2014-09-18 11:08:04 -04:00
|
|
|
// Other bounds. Consider both in-scope bounds from fn decl
|
|
|
|
// and applicable impls. There is a certain set of precedence rules here.
|
2014-09-12 10:53:35 -04:00
|
|
|
|
2016-11-13 19:42:15 -07:00
|
|
|
let def_id = obligation.predicate.def_id();
|
2017-08-31 08:57:41 -07:00
|
|
|
let lang_items = self.tcx().lang_items();
|
|
|
|
if lang_items.copy_trait() == Some(def_id) {
|
2016-11-16 09:21:49 -07:00
|
|
|
debug!("obligation self ty is {:?}",
|
|
|
|
obligation.predicate.0.self_ty());
|
|
|
|
|
|
|
|
// User-defined copy impls are permitted, but only for
|
|
|
|
// structs and enums.
|
|
|
|
self.assemble_candidates_from_impls(obligation, &mut candidates)?;
|
|
|
|
|
|
|
|
// For other types, we'll use the builtin rules.
|
2017-09-13 22:40:48 +02:00
|
|
|
let copy_conditions = self.copy_clone_conditions(obligation);
|
2016-11-16 09:21:49 -07:00
|
|
|
self.assemble_builtin_bound_candidates(copy_conditions, &mut candidates)?;
|
2017-08-31 08:57:41 -07:00
|
|
|
} else if lang_items.sized_trait() == Some(def_id) {
|
2016-11-16 09:21:49 -07:00
|
|
|
// Sized is never implementable by end-users, it is
|
|
|
|
// always automatically computed.
|
|
|
|
let sized_conditions = self.sized_conditions(obligation);
|
|
|
|
self.assemble_builtin_bound_candidates(sized_conditions,
|
|
|
|
&mut candidates)?;
|
2017-08-31 08:57:41 -07:00
|
|
|
} else if lang_items.unsize_trait() == Some(def_id) {
|
2016-11-16 09:21:49 -07:00
|
|
|
self.assemble_candidates_for_unsizing(obligation, &mut candidates);
|
|
|
|
} else {
|
2017-08-31 08:57:41 -07:00
|
|
|
if lang_items.clone_trait() == Some(def_id) {
|
2017-08-21 21:47:07 -07:00
|
|
|
// Same builtin conditions as `Copy`, i.e. every type which has builtin support
|
|
|
|
// for `Copy` also has builtin support for `Clone`, + tuples and arrays of `Clone`
|
|
|
|
// types have builtin support for `Clone`.
|
2017-09-13 22:40:48 +02:00
|
|
|
let clone_conditions = self.copy_clone_conditions(obligation);
|
2017-08-21 21:47:07 -07:00
|
|
|
self.assemble_builtin_bound_candidates(clone_conditions, &mut candidates)?;
|
|
|
|
}
|
|
|
|
|
2017-07-07 00:02:35 +02:00
|
|
|
self.assemble_generator_candidates(obligation, &mut candidates)?;
|
2016-11-16 09:21:49 -07:00
|
|
|
self.assemble_closure_candidates(obligation, &mut candidates)?;
|
|
|
|
self.assemble_fn_pointer_candidates(obligation, &mut candidates)?;
|
|
|
|
self.assemble_candidates_from_impls(obligation, &mut candidates)?;
|
|
|
|
self.assemble_candidates_from_object_ty(obligation, &mut candidates);
|
2014-09-18 11:08:04 -04:00
|
|
|
}
|
|
|
|
|
2014-12-27 04:22:29 -05:00
|
|
|
self.assemble_candidates_from_projected_tys(obligation, &mut candidates);
|
2016-03-22 22:01:37 -05:00
|
|
|
self.assemble_candidates_from_caller_bounds(stack, &mut candidates)?;
|
2017-10-09 13:59:20 -03:00
|
|
|
// Auto implementations have lower priority, so we only
|
2015-02-20 15:46:50 +01:00
|
|
|
// consider triggering a default if there is no other impl that can apply.
|
2015-03-24 16:53:34 -07:00
|
|
|
if candidates.vec.is_empty() {
|
2017-10-09 13:59:20 -03:00
|
|
|
self.assemble_candidates_from_auto_impls(obligation, &mut candidates)?;
|
2015-02-20 15:46:50 +01:00
|
|
|
}
|
librustc: Make `Copy` opt-in.
This change makes the compiler no longer infer whether types (structures
and enumerations) implement the `Copy` trait (and thus are implicitly
copyable). Rather, you must implement `Copy` yourself via `impl Copy for
MyType {}`.
A new warning has been added, `missing_copy_implementations`, to warn
you if a non-generic public type has been added that could have
implemented `Copy` but didn't.
For convenience, you may *temporarily* opt out of this behavior by using
`#![feature(opt_out_copy)]`. Note though that this feature gate will never be
accepted and will be removed by the time that 1.0 is released, so you should
transition your code away from using it.
This breaks code like:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
Change this code to:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
impl Copy for Point2D {}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
This is the backwards-incompatible part of #13231.
Part of RFC #3.
[breaking-change]
2014-12-05 17:01:33 -08:00
|
|
|
debug!("candidate list size: {}", candidates.vec.len());
|
2014-09-12 10:53:35 -04:00
|
|
|
Ok(candidates)
|
|
|
|
}
|
|
|
|
|
2014-12-27 04:22:29 -05:00
|
|
|
fn assemble_candidates_from_projected_tys(&mut self,
|
|
|
|
obligation: &TraitObligation<'tcx>,
|
|
|
|
candidates: &mut SelectionCandidateSet<'tcx>)
|
|
|
|
{
|
2015-08-24 23:27:00 +03:00
|
|
|
debug!("assemble_candidates_for_projected_tys({:?})", obligation);
|
2014-12-27 04:22:29 -05:00
|
|
|
|
|
|
|
// before we go into the whole skolemization thing, just
|
|
|
|
// quickly check if the self-type is a projection at all.
|
2016-07-22 18:56:22 +03:00
|
|
|
match obligation.predicate.0.trait_ref.self_ty().sty {
|
|
|
|
ty::TyProjection(_) | ty::TyAnon(..) => {}
|
2015-06-11 16:21:46 -07:00
|
|
|
ty::TyInfer(ty::TyVar(_)) => {
|
2016-03-25 18:31:27 +01:00
|
|
|
span_bug!(obligation.cause.span,
|
2015-08-24 23:27:00 +03:00
|
|
|
"Self=_ should have been handled by assemble_candidates");
|
2014-12-27 04:22:29 -05:00
|
|
|
}
|
2016-07-22 18:56:22 +03:00
|
|
|
_ => return
|
|
|
|
}
|
2014-12-27 04:22:29 -05:00
|
|
|
|
2016-05-11 17:22:13 -07:00
|
|
|
let result = self.probe(|this, snapshot| {
|
2016-07-22 18:56:22 +03:00
|
|
|
this.match_projection_obligation_against_definition_bounds(obligation,
|
2014-12-27 04:22:29 -05:00
|
|
|
snapshot)
|
|
|
|
});
|
|
|
|
|
|
|
|
if result {
|
|
|
|
candidates.vec.push(ProjectionCandidate);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-22 18:56:22 +03:00
|
|
|
fn match_projection_obligation_against_definition_bounds(
|
2014-12-27 04:22:29 -05:00
|
|
|
&mut self,
|
|
|
|
obligation: &TraitObligation<'tcx>,
|
|
|
|
snapshot: &infer::CombinedSnapshot)
|
|
|
|
-> bool
|
|
|
|
{
|
|
|
|
let poly_trait_predicate =
|
|
|
|
self.infcx().resolve_type_vars_if_possible(&obligation.predicate);
|
|
|
|
let (skol_trait_predicate, skol_map) =
|
|
|
|
self.infcx().skolemize_late_bound_regions(&poly_trait_predicate, snapshot);
|
2016-07-22 18:56:22 +03:00
|
|
|
debug!("match_projection_obligation_against_definition_bounds: \
|
2015-06-18 20:25:05 +03:00
|
|
|
skol_trait_predicate={:?} skol_map={:?}",
|
|
|
|
skol_trait_predicate,
|
|
|
|
skol_map);
|
2014-12-27 04:22:29 -05:00
|
|
|
|
2016-07-22 18:56:22 +03:00
|
|
|
let (def_id, substs) = match skol_trait_predicate.trait_ref.self_ty().sty {
|
2017-07-11 10:33:09 -04:00
|
|
|
ty::TyProjection(ref data) =>
|
|
|
|
(data.trait_ref(self.tcx()).def_id, data.substs),
|
2016-07-22 18:56:22 +03:00
|
|
|
ty::TyAnon(def_id, substs) => (def_id, substs),
|
2014-12-27 04:22:29 -05:00
|
|
|
_ => {
|
2016-03-25 18:31:27 +01:00
|
|
|
span_bug!(
|
2014-12-27 04:22:29 -05:00
|
|
|
obligation.cause.span,
|
2016-07-22 18:56:22 +03:00
|
|
|
"match_projection_obligation_against_definition_bounds() called \
|
2016-03-25 18:31:27 +01:00
|
|
|
but self-ty not a projection: {:?}",
|
|
|
|
skol_trait_predicate.trait_ref.self_ty());
|
2014-12-27 04:22:29 -05:00
|
|
|
}
|
|
|
|
};
|
2016-07-22 18:56:22 +03:00
|
|
|
debug!("match_projection_obligation_against_definition_bounds: \
|
|
|
|
def_id={:?}, substs={:?}",
|
|
|
|
def_id, substs);
|
2014-12-27 04:22:29 -05:00
|
|
|
|
2017-04-24 15:20:46 +03:00
|
|
|
let predicates_of = self.tcx().predicates_of(def_id);
|
|
|
|
let bounds = predicates_of.instantiate(self.tcx(), substs);
|
2016-07-22 18:56:22 +03:00
|
|
|
debug!("match_projection_obligation_against_definition_bounds: \
|
2015-06-18 20:25:05 +03:00
|
|
|
bounds={:?}",
|
|
|
|
bounds);
|
2014-12-27 04:22:29 -05:00
|
|
|
|
|
|
|
let matching_bound =
|
2016-06-13 20:10:32 +03:00
|
|
|
util::elaborate_predicates(self.tcx(), bounds.predicates)
|
2014-12-27 04:22:29 -05:00
|
|
|
.filter_to_traits()
|
|
|
|
.find(
|
2016-05-11 17:22:13 -07:00
|
|
|
|bound| self.probe(
|
|
|
|
|this, _| this.match_projection(obligation,
|
|
|
|
bound.clone(),
|
|
|
|
skol_trait_predicate.trait_ref.clone(),
|
|
|
|
&skol_map,
|
|
|
|
snapshot)));
|
2014-12-27 04:22:29 -05:00
|
|
|
|
2016-07-22 18:56:22 +03:00
|
|
|
debug!("match_projection_obligation_against_definition_bounds: \
|
2015-06-18 20:25:05 +03:00
|
|
|
matching_bound={:?}",
|
|
|
|
matching_bound);
|
2014-12-27 04:22:29 -05:00
|
|
|
match matching_bound {
|
|
|
|
None => false,
|
|
|
|
Some(bound) => {
|
|
|
|
// Repeat the successful match, if any, this time outside of a probe.
|
|
|
|
let result = self.match_projection(obligation,
|
|
|
|
bound,
|
|
|
|
skol_trait_predicate.trait_ref.clone(),
|
|
|
|
&skol_map,
|
|
|
|
snapshot);
|
2016-04-20 19:51:56 -04:00
|
|
|
|
|
|
|
self.infcx.pop_skolemized(skol_map, snapshot);
|
|
|
|
|
2014-12-27 04:22:29 -05:00
|
|
|
assert!(result);
|
|
|
|
true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn match_projection(&mut self,
|
|
|
|
obligation: &TraitObligation<'tcx>,
|
|
|
|
trait_bound: ty::PolyTraitRef<'tcx>,
|
2015-04-21 18:59:58 +03:00
|
|
|
skol_trait_ref: ty::TraitRef<'tcx>,
|
2016-08-25 23:58:52 +03:00
|
|
|
skol_map: &infer::SkolemizationMap<'tcx>,
|
2014-12-27 04:22:29 -05:00
|
|
|
snapshot: &infer::CombinedSnapshot)
|
|
|
|
-> bool
|
|
|
|
{
|
|
|
|
assert!(!skol_trait_ref.has_escaping_regions());
|
2017-05-24 09:43:20 -04:00
|
|
|
match self.infcx.at(&obligation.cause, obligation.param_env)
|
|
|
|
.sup(ty::Binder(skol_trait_ref), trait_bound) {
|
2016-03-29 20:06:42 -07:00
|
|
|
Ok(InferOk { obligations, .. }) => {
|
2016-05-11 17:22:13 -07:00
|
|
|
self.inferred_obligations.extend(obligations);
|
2016-03-29 20:06:42 -07:00
|
|
|
}
|
2014-12-27 04:22:29 -05:00
|
|
|
Err(_) => { return false; }
|
|
|
|
}
|
|
|
|
|
2016-04-20 19:51:56 -04:00
|
|
|
self.infcx.leak_check(false, obligation.cause.span, skol_map, snapshot).is_ok()
|
2014-12-27 04:22:29 -05:00
|
|
|
}
|
|
|
|
|
2014-11-25 21:17:11 -05:00
|
|
|
/// Given an obligation like `<SomeTrait for T>`, search the obligations that the caller
|
|
|
|
/// supplied to find out whether it is listed among them.
|
|
|
|
///
|
|
|
|
/// Never affects inference environment.
|
2015-01-08 21:41:42 -05:00
|
|
|
fn assemble_candidates_from_caller_bounds<'o>(&mut self,
|
|
|
|
stack: &TraitObligationStack<'o, 'tcx>,
|
|
|
|
candidates: &mut SelectionCandidateSet<'tcx>)
|
|
|
|
-> Result<(),SelectionError<'tcx>>
|
2014-09-12 10:53:35 -04:00
|
|
|
{
|
2015-06-18 20:25:05 +03:00
|
|
|
debug!("assemble_candidates_from_caller_bounds({:?})",
|
|
|
|
stack.obligation);
|
2014-09-12 10:53:35 -04:00
|
|
|
|
2014-10-09 17:19:50 -04:00
|
|
|
let all_bounds =
|
2017-05-23 04:19:47 -04:00
|
|
|
stack.obligation.param_env.caller_bounds
|
|
|
|
.iter()
|
|
|
|
.filter_map(|o| o.to_opt_poly_trait_ref());
|
2014-10-09 17:19:50 -04:00
|
|
|
|
2017-04-23 23:05:25 +03:00
|
|
|
// micro-optimization: filter out predicates relating to different
|
|
|
|
// traits.
|
2014-10-09 17:19:50 -04:00
|
|
|
let matching_bounds =
|
2017-04-23 23:05:25 +03:00
|
|
|
all_bounds.filter(|p| p.def_id() == stack.obligation.predicate.def_id());
|
|
|
|
|
|
|
|
let matching_bounds =
|
|
|
|
matching_bounds.filter(
|
2015-01-08 21:41:42 -05:00
|
|
|
|bound| self.evaluate_where_clause(stack, bound.clone()).may_apply());
|
2014-10-09 17:19:50 -04:00
|
|
|
|
|
|
|
let param_candidates =
|
2014-12-27 04:22:29 -05:00
|
|
|
matching_bounds.map(|bound| ParamCandidate(bound));
|
2014-10-09 17:19:50 -04:00
|
|
|
|
|
|
|
candidates.vec.extend(param_candidates);
|
2014-09-12 10:53:35 -04:00
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2015-01-08 21:41:42 -05:00
|
|
|
fn evaluate_where_clause<'o>(&mut self,
|
|
|
|
stack: &TraitObligationStack<'o, 'tcx>,
|
|
|
|
where_clause_trait_ref: ty::PolyTraitRef<'tcx>)
|
2015-10-18 19:15:57 +03:00
|
|
|
-> EvaluationResult
|
2015-01-08 21:41:42 -05:00
|
|
|
{
|
2016-05-11 17:22:13 -07:00
|
|
|
self.probe(move |this, _| {
|
|
|
|
match this.match_where_clause_trait_ref(stack.obligation, where_clause_trait_ref) {
|
2015-01-08 21:41:42 -05:00
|
|
|
Ok(obligations) => {
|
2016-05-11 17:22:13 -07:00
|
|
|
this.evaluate_predicates_recursively(stack.list(), obligations.iter())
|
2015-01-08 21:41:42 -05:00
|
|
|
}
|
2015-10-20 18:23:46 +03:00
|
|
|
Err(()) => EvaluatedToErr
|
2015-01-08 21:41:42 -05:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2016-12-26 14:34:03 +01:00
|
|
|
fn assemble_generator_candidates(&mut self,
|
|
|
|
obligation: &TraitObligation<'tcx>,
|
|
|
|
candidates: &mut SelectionCandidateSet<'tcx>)
|
|
|
|
-> Result<(),SelectionError<'tcx>>
|
|
|
|
{
|
2017-08-31 08:57:41 -07:00
|
|
|
if self.tcx().lang_items().gen_trait() != Some(obligation.predicate.def_id()) {
|
2017-07-07 00:02:35 +02:00
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
|
2017-07-13 02:32:36 +02:00
|
|
|
// ok to skip binder because the substs on generator types never
|
|
|
|
// touch bound regions, they just capture the in-scope
|
|
|
|
// type/region parameters
|
2016-12-26 14:34:03 +01:00
|
|
|
let self_ty = *obligation.self_ty().skip_binder();
|
2017-08-15 23:30:13 +03:00
|
|
|
match self_ty.sty {
|
|
|
|
ty::TyGenerator(..) => {
|
|
|
|
debug!("assemble_generator_candidates: self_ty={:?} obligation={:?}",
|
|
|
|
self_ty,
|
|
|
|
obligation);
|
|
|
|
|
|
|
|
candidates.vec.push(GeneratorCandidate);
|
|
|
|
Ok(())
|
|
|
|
}
|
2016-12-26 14:34:03 +01:00
|
|
|
ty::TyInfer(ty::TyVar(_)) => {
|
|
|
|
debug!("assemble_generator_candidates: ambiguous self-type");
|
|
|
|
candidates.ambiguous = true;
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
_ => { return Ok(()); }
|
2017-08-15 23:30:13 +03:00
|
|
|
}
|
2016-12-26 14:34:03 +01:00
|
|
|
}
|
|
|
|
|
2014-11-25 21:17:11 -05:00
|
|
|
/// Check for the artificial impl that the compiler will create for an obligation like `X :
|
2015-01-24 22:15:08 +02:00
|
|
|
/// FnMut<..>` where `X` is a closure type.
|
2014-11-25 21:17:11 -05:00
|
|
|
///
|
2015-01-24 22:15:08 +02:00
|
|
|
/// Note: the type parameters on a closure candidate are modeled as *output* type
|
2014-11-25 21:17:11 -05:00
|
|
|
/// parameters and hence do not affect whether this trait is a match or not. They will be
|
|
|
|
/// unified during the confirmation step.
|
2015-01-24 22:00:03 +02:00
|
|
|
fn assemble_closure_candidates(&mut self,
|
|
|
|
obligation: &TraitObligation<'tcx>,
|
|
|
|
candidates: &mut SelectionCandidateSet<'tcx>)
|
|
|
|
-> Result<(),SelectionError<'tcx>>
|
2014-09-12 10:53:35 -04:00
|
|
|
{
|
2017-08-31 08:57:41 -07:00
|
|
|
let kind = match self.tcx().lang_items().fn_trait_kind(obligation.predicate.0.def_id()) {
|
2014-12-01 09:23:40 -05:00
|
|
|
Some(k) => k,
|
|
|
|
None => { return Ok(()); }
|
2014-10-13 19:54:01 -04:00
|
|
|
};
|
|
|
|
|
2015-03-26 15:53:00 -04:00
|
|
|
// ok to skip binder because the substs on closure types never
|
|
|
|
// touch bound regions, they just capture the in-scope
|
|
|
|
// type/region parameters
|
2017-08-15 23:30:13 +03:00
|
|
|
match obligation.self_ty().skip_binder().sty {
|
2017-11-08 09:45:48 -05:00
|
|
|
ty::TyClosure(closure_def_id, closure_substs) => {
|
2017-08-15 23:30:13 +03:00
|
|
|
debug!("assemble_unboxed_candidates: kind={:?} obligation={:?}",
|
|
|
|
kind, obligation);
|
2017-11-08 09:45:48 -05:00
|
|
|
match self.infcx.closure_kind(closure_def_id, closure_substs) {
|
2017-08-15 23:30:13 +03:00
|
|
|
Some(closure_kind) => {
|
|
|
|
debug!("assemble_unboxed_candidates: closure_kind = {:?}", closure_kind);
|
|
|
|
if closure_kind.extends(kind) {
|
|
|
|
candidates.vec.push(ClosureCandidate);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
debug!("assemble_unboxed_candidates: closure_kind not yet known");
|
|
|
|
candidates.vec.push(ClosureCandidate);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Ok(())
|
|
|
|
}
|
2015-06-11 16:21:46 -07:00
|
|
|
ty::TyInfer(ty::TyVar(_)) => {
|
2015-01-21 17:45:52 -05:00
|
|
|
debug!("assemble_unboxed_closure_candidates: ambiguous self-type");
|
2014-10-09 17:19:50 -04:00
|
|
|
candidates.ambiguous = true;
|
|
|
|
return Ok(());
|
|
|
|
}
|
2014-09-12 10:53:35 -04:00
|
|
|
_ => { return Ok(()); }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-01 09:23:40 -05:00
|
|
|
/// Implement one of the `Fn()` family for a fn pointer.
|
|
|
|
fn assemble_fn_pointer_candidates(&mut self,
|
2014-12-05 00:03:03 -05:00
|
|
|
obligation: &TraitObligation<'tcx>,
|
2014-12-17 14:16:28 -05:00
|
|
|
candidates: &mut SelectionCandidateSet<'tcx>)
|
2014-12-01 09:23:40 -05:00
|
|
|
-> Result<(),SelectionError<'tcx>>
|
|
|
|
{
|
2015-02-15 15:09:26 -05:00
|
|
|
// We provide impl of all fn traits for fn pointers.
|
2017-08-31 08:57:41 -07:00
|
|
|
if self.tcx().lang_items().fn_trait_kind(obligation.predicate.def_id()).is_none() {
|
2014-12-01 09:23:40 -05:00
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
|
2015-03-26 15:53:00 -04:00
|
|
|
// ok to skip binder because what we are inspecting doesn't involve bound regions
|
2015-08-24 23:27:00 +03:00
|
|
|
let self_ty = *obligation.self_ty().skip_binder();
|
2014-12-01 09:23:40 -05:00
|
|
|
match self_ty.sty {
|
2015-06-11 16:21:46 -07:00
|
|
|
ty::TyInfer(ty::TyVar(_)) => {
|
2015-01-21 17:45:52 -05:00
|
|
|
debug!("assemble_fn_pointer_candidates: ambiguous self-type");
|
2014-12-01 09:23:40 -05:00
|
|
|
candidates.ambiguous = true; // could wind up being a fn() type
|
|
|
|
}
|
|
|
|
|
|
|
|
// provide an impl, but only for suitable `fn` pointers
|
2017-05-13 17:11:52 +03:00
|
|
|
ty::TyFnDef(..) | ty::TyFnPtr(_) => {
|
|
|
|
if let ty::Binder(ty::FnSig {
|
|
|
|
unsafety: hir::Unsafety::Normal,
|
|
|
|
abi: Abi::Rust,
|
|
|
|
variadic: false,
|
|
|
|
..
|
|
|
|
}) = self_ty.fn_sig(self.tcx()) {
|
|
|
|
candidates.vec.push(FnPointerCandidate);
|
|
|
|
}
|
2014-12-01 09:23:40 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
_ => { }
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2014-11-25 21:17:11 -05:00
|
|
|
/// Search for impls that might apply to `obligation`.
|
2014-09-18 11:08:04 -04:00
|
|
|
fn assemble_candidates_from_impls(&mut self,
|
2014-12-05 00:03:03 -05:00
|
|
|
obligation: &TraitObligation<'tcx>,
|
2015-01-08 00:41:50 +01:00
|
|
|
candidates: &mut SelectionCandidateSet<'tcx>)
|
2014-09-29 22:11:30 +03:00
|
|
|
-> Result<(), SelectionError<'tcx>>
|
2014-09-12 10:53:35 -04:00
|
|
|
{
|
2015-06-18 20:25:05 +03:00
|
|
|
debug!("assemble_candidates_from_impls(obligation={:?})", obligation);
|
2015-01-08 00:41:50 +01:00
|
|
|
|
2017-08-07 20:50:34 +00:00
|
|
|
self.tcx().for_each_relevant_impl(
|
|
|
|
obligation.predicate.def_id(),
|
2015-04-30 20:35:10 +03:00
|
|
|
obligation.predicate.0.trait_ref.self_ty(),
|
2015-04-21 19:00:12 +03:00
|
|
|
|impl_def_id| {
|
2016-04-20 19:51:56 -04:00
|
|
|
self.probe(|this, snapshot| { /* [1] */
|
|
|
|
match this.match_impl(impl_def_id, obligation, snapshot) {
|
|
|
|
Ok(skol_map) => {
|
|
|
|
candidates.vec.push(ImplCandidate(impl_def_id));
|
|
|
|
|
|
|
|
// NB: we can safely drop the skol map
|
|
|
|
// since we are in a probe [1]
|
|
|
|
mem::drop(skol_map);
|
|
|
|
}
|
|
|
|
Err(_) => { }
|
2014-09-12 10:53:35 -04:00
|
|
|
}
|
2015-04-21 19:00:12 +03:00
|
|
|
});
|
|
|
|
}
|
|
|
|
);
|
2015-01-24 14:17:24 +01:00
|
|
|
|
2015-02-20 15:46:50 +01:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2017-10-09 13:59:20 -03:00
|
|
|
fn assemble_candidates_from_auto_impls(&mut self,
|
2015-02-20 15:46:50 +01:00
|
|
|
obligation: &TraitObligation<'tcx>,
|
|
|
|
candidates: &mut SelectionCandidateSet<'tcx>)
|
|
|
|
-> Result<(), SelectionError<'tcx>>
|
|
|
|
{
|
2015-03-26 15:53:00 -04:00
|
|
|
// OK to skip binder here because the tests we do below do not involve bound regions
|
2015-08-24 23:27:00 +03:00
|
|
|
let self_ty = *obligation.self_ty().skip_binder();
|
2017-10-09 13:59:20 -03:00
|
|
|
debug!("assemble_candidates_from_auto_impls(self_ty={:?})", self_ty);
|
2015-02-20 15:46:50 +01:00
|
|
|
|
|
|
|
let def_id = obligation.predicate.def_id();
|
|
|
|
|
2017-10-16 17:33:45 -02:00
|
|
|
if self.tcx().trait_is_auto(def_id) {
|
2015-02-20 05:16:59 -05:00
|
|
|
match self_ty.sty {
|
2016-11-16 09:21:49 -07:00
|
|
|
ty::TyDynamic(..) => {
|
2015-03-24 15:55:29 -04:00
|
|
|
// For object types, we don't know what the closed
|
2017-01-15 08:42:33 +01:00
|
|
|
// over types are. This means we conservatively
|
|
|
|
// say nothing; a candidate may be added by
|
|
|
|
// `assemble_candidates_from_object_ty`.
|
2015-03-24 15:55:29 -04:00
|
|
|
}
|
2017-09-03 19:53:58 +01:00
|
|
|
ty::TyForeign(..) => {
|
|
|
|
// Since the contents of foreign types is unknown,
|
|
|
|
// we don't add any `..` impl. Default traits could
|
|
|
|
// still be provided by a manual implementation for
|
|
|
|
// this trait and type.
|
|
|
|
}
|
2015-06-11 16:21:46 -07:00
|
|
|
ty::TyParam(..) |
|
2017-02-14 11:32:00 +02:00
|
|
|
ty::TyProjection(..) => {
|
2015-02-20 05:16:59 -05:00
|
|
|
// In these cases, we don't know what the actual
|
|
|
|
// type is. Therefore, we cannot break it down
|
|
|
|
// into its constituent types. So we don't
|
|
|
|
// consider the `..` impl but instead just add no
|
|
|
|
// candidates: this means that typeck will only
|
|
|
|
// succeed if there is another reason to believe
|
|
|
|
// that this obligation holds. That could be a
|
|
|
|
// where-clause or, in the case of an object type,
|
|
|
|
// it could be that the object type lists the
|
|
|
|
// trait (e.g. `Foo+Send : Send`). See
|
|
|
|
// `compile-fail/typeck-default-trait-impl-send-param.rs`
|
|
|
|
// for an example of a test case that exercises
|
|
|
|
// this path.
|
|
|
|
}
|
2015-06-11 16:21:46 -07:00
|
|
|
ty::TyInfer(ty::TyVar(_)) => {
|
2017-10-09 13:59:20 -03:00
|
|
|
// the auto impl might apply, we don't know
|
2015-02-19 11:28:01 -05:00
|
|
|
candidates.ambiguous = true;
|
|
|
|
}
|
2015-02-20 05:16:59 -05:00
|
|
|
_ => {
|
2017-10-09 13:59:20 -03:00
|
|
|
candidates.vec.push(AutoImplCandidate(def_id.clone()))
|
2015-02-18 01:49:16 +01:00
|
|
|
}
|
|
|
|
}
|
2015-01-24 14:17:24 +01:00
|
|
|
}
|
|
|
|
|
2014-09-12 10:53:35 -04:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2014-12-23 05:26:34 -05:00
|
|
|
/// Search for impls that might apply to `obligation`.
|
|
|
|
fn assemble_candidates_from_object_ty(&mut self,
|
|
|
|
obligation: &TraitObligation<'tcx>,
|
|
|
|
candidates: &mut SelectionCandidateSet<'tcx>)
|
|
|
|
{
|
2015-06-18 20:25:05 +03:00
|
|
|
debug!("assemble_candidates_from_object_ty(self_ty={:?})",
|
2015-08-24 23:27:00 +03:00
|
|
|
obligation.self_ty().skip_binder());
|
2014-12-23 05:26:34 -05:00
|
|
|
|
|
|
|
// Object-safety candidates are only applicable to object-safe
|
|
|
|
// traits. Including this check is useful because it helps
|
|
|
|
// inference in cases of traits like `BorrowFrom`, which are
|
|
|
|
// not object-safe, and which rely on being able to infer the
|
|
|
|
// self-type from one of the other inputs. Without this check,
|
|
|
|
// these cases wind up being considered ambiguous due to a
|
|
|
|
// (spurious) ambiguity introduced here.
|
2015-03-26 15:51:11 -04:00
|
|
|
let predicate_trait_ref = obligation.predicate.to_poly_trait_ref();
|
2016-03-17 00:15:31 +02:00
|
|
|
if !self.tcx().is_object_safe(predicate_trait_ref.def_id()) {
|
2014-12-23 05:26:34 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-04-20 19:51:56 -04:00
|
|
|
self.probe(|this, _snapshot| {
|
|
|
|
// the code below doesn't care about regions, and the
|
|
|
|
// self-ty here doesn't escape this probe, so just erase
|
|
|
|
// any LBR.
|
|
|
|
let self_ty = this.tcx().erase_late_bound_regions(&obligation.self_ty());
|
2015-03-26 15:53:00 -04:00
|
|
|
let poly_trait_ref = match self_ty.sty {
|
2016-11-16 09:21:49 -07:00
|
|
|
ty::TyDynamic(ref data, ..) => {
|
2016-11-13 15:25:54 -07:00
|
|
|
if data.auto_traits().any(|did| did == obligation.predicate.def_id()) {
|
|
|
|
debug!("assemble_candidates_from_object_ty: matched builtin bound, \
|
|
|
|
pushing candidate");
|
|
|
|
candidates.vec.push(BuiltinObjectCandidate);
|
|
|
|
return;
|
2015-02-18 01:49:16 +01:00
|
|
|
}
|
2015-03-26 15:53:00 -04:00
|
|
|
|
2016-11-12 15:46:16 -07:00
|
|
|
match data.principal() {
|
2016-11-16 09:21:49 -07:00
|
|
|
Some(p) => p.with_self_ty(this.tcx(), self_ty),
|
2016-11-12 15:46:16 -07:00
|
|
|
None => return,
|
|
|
|
}
|
2015-03-26 15:53:00 -04:00
|
|
|
}
|
2015-06-11 16:21:46 -07:00
|
|
|
ty::TyInfer(ty::TyVar(_)) => {
|
2015-03-26 15:53:00 -04:00
|
|
|
debug!("assemble_candidates_from_object_ty: ambiguous");
|
|
|
|
candidates.ambiguous = true; // could wind up being an object type
|
2016-05-01 17:19:11 +03:00
|
|
|
return;
|
2015-02-18 01:49:16 +01:00
|
|
|
}
|
2015-03-26 15:53:00 -04:00
|
|
|
_ => {
|
2016-05-01 17:19:11 +03:00
|
|
|
return;
|
2015-03-26 15:53:00 -04:00
|
|
|
}
|
|
|
|
};
|
2015-02-18 01:49:16 +01:00
|
|
|
|
2015-06-18 20:25:05 +03:00
|
|
|
debug!("assemble_candidates_from_object_ty: poly_trait_ref={:?}",
|
|
|
|
poly_trait_ref);
|
2014-12-23 05:26:34 -05:00
|
|
|
|
2015-07-04 05:46:54 +03:00
|
|
|
// Count only those upcast versions that match the trait-ref
|
|
|
|
// we are looking for. Specifically, do not only check for the
|
|
|
|
// correct trait, but also the correct type parameters.
|
|
|
|
// For example, we may be trying to upcast `Foo` to `Bar<i32>`,
|
|
|
|
// but `Foo` is declared as `trait Foo : Bar<u32>`.
|
2015-07-24 10:23:35 -04:00
|
|
|
let upcast_trait_refs =
|
2016-05-11 17:22:13 -07:00
|
|
|
util::supertraits(this.tcx(), poly_trait_ref)
|
2015-07-24 10:23:35 -04:00
|
|
|
.filter(|upcast_trait_ref| {
|
2016-05-11 17:22:13 -07:00
|
|
|
this.probe(|this, _| {
|
2015-07-24 10:23:35 -04:00
|
|
|
let upcast_trait_ref = upcast_trait_ref.clone();
|
2016-05-11 17:22:13 -07:00
|
|
|
this.match_poly_trait_ref(obligation, upcast_trait_ref).is_ok()
|
2015-07-24 10:23:35 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
.count();
|
2015-07-04 05:46:54 +03:00
|
|
|
|
|
|
|
if upcast_trait_refs > 1 {
|
2015-03-26 15:53:00 -04:00
|
|
|
// can be upcast in many ways; need more type information
|
|
|
|
candidates.ambiguous = true;
|
2015-07-04 05:46:54 +03:00
|
|
|
} else if upcast_trait_refs == 1 {
|
2015-03-26 15:53:00 -04:00
|
|
|
candidates.vec.push(ObjectCandidate);
|
|
|
|
}
|
2016-05-01 17:19:11 +03:00
|
|
|
})
|
2014-12-23 05:26:34 -05:00
|
|
|
}
|
|
|
|
|
2015-04-15 11:57:29 +12:00
|
|
|
/// Search for unsizing that might apply to `obligation`.
|
|
|
|
fn assemble_candidates_for_unsizing(&mut self,
|
|
|
|
obligation: &TraitObligation<'tcx>,
|
|
|
|
candidates: &mut SelectionCandidateSet<'tcx>) {
|
2015-05-13 14:57:47 +12:00
|
|
|
// We currently never consider higher-ranked obligations e.g.
|
|
|
|
// `for<'a> &'a T: Unsize<Trait+'a>` to be implemented. This is not
|
|
|
|
// because they are a priori invalid, and we could potentially add support
|
|
|
|
// for them later, it's just that there isn't really a strong need for it.
|
|
|
|
// A `T: Unsize<U>` obligation is always used as part of a `T: CoerceUnsize<U>`
|
|
|
|
// impl, and those are generally applied to concrete types.
|
|
|
|
//
|
|
|
|
// That said, one might try to write a fn with a where clause like
|
|
|
|
// for<'a> Foo<'a, T>: Unsize<Foo<'a, Trait>>
|
|
|
|
// where the `'a` is kind of orthogonal to the relevant part of the `Unsize`.
|
|
|
|
// Still, you'd be more likely to write that where clause as
|
|
|
|
// T: Trait
|
|
|
|
// so it seems ok if we (conservatively) fail to accept that `Unsize`
|
|
|
|
// obligation above. Should be possible to extend this in the future.
|
2017-11-12 05:04:26 -05:00
|
|
|
let source = match obligation.self_ty().no_late_bound_regions() {
|
2015-05-13 14:57:47 +12:00
|
|
|
Some(t) => t,
|
|
|
|
None => {
|
|
|
|
// Don't add any candidates if there are bound regions.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
};
|
2016-08-18 08:32:50 +03:00
|
|
|
let target = obligation.predicate.skip_binder().trait_ref.substs.type_at(1);
|
2015-04-15 11:57:29 +12:00
|
|
|
|
2015-06-18 20:25:05 +03:00
|
|
|
debug!("assemble_candidates_for_unsizing(source={:?}, target={:?})",
|
|
|
|
source, target);
|
2015-04-15 11:57:29 +12:00
|
|
|
|
|
|
|
let may_apply = match (&source.sty, &target.sty) {
|
|
|
|
// Trait+Kx+'a -> Trait+Ky+'b (upcasts).
|
2016-11-16 09:21:49 -07:00
|
|
|
(&ty::TyDynamic(ref data_a, ..), &ty::TyDynamic(ref data_b, ..)) => {
|
2015-04-15 11:57:29 +12:00
|
|
|
// Upcasts permit two things:
|
|
|
|
//
|
|
|
|
// 1. Dropping builtin bounds, e.g. `Foo+Send` to `Foo`
|
|
|
|
// 2. Tightening the region bound, e.g. `Foo+'a` to `Foo+'b` if `'a : 'b`
|
|
|
|
//
|
|
|
|
// Note that neither of these changes requires any
|
|
|
|
// change at runtime. Eventually this will be
|
|
|
|
// generalized.
|
|
|
|
//
|
|
|
|
// We always upcast when we can because of reason
|
|
|
|
// #2 (region bounds).
|
2016-11-12 15:46:16 -07:00
|
|
|
match (data_a.principal(), data_b.principal()) {
|
2016-11-16 09:21:49 -07:00
|
|
|
(Some(a), Some(b)) => a.def_id() == b.def_id() &&
|
2016-11-13 15:25:54 -07:00
|
|
|
data_b.auto_traits()
|
|
|
|
// All of a's auto traits need to be in b's auto traits.
|
|
|
|
.all(|b| data_a.auto_traits().any(|a| a == b)),
|
2016-11-12 15:46:16 -07:00
|
|
|
_ => false
|
|
|
|
}
|
2015-04-15 11:57:29 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
// T -> Trait.
|
2016-11-16 09:21:49 -07:00
|
|
|
(_, &ty::TyDynamic(..)) => true,
|
2015-04-15 11:57:29 +12:00
|
|
|
|
|
|
|
// Ambiguous handling is below T -> Trait, because inference
|
|
|
|
// variables can still implement Unsize<Trait> and nested
|
|
|
|
// obligations will have the final say (likely deferred).
|
2015-06-11 16:21:46 -07:00
|
|
|
(&ty::TyInfer(ty::TyVar(_)), _) |
|
|
|
|
(_, &ty::TyInfer(ty::TyVar(_))) => {
|
2015-04-15 11:57:29 +12:00
|
|
|
debug!("assemble_candidates_for_unsizing: ambiguous");
|
|
|
|
candidates.ambiguous = true;
|
|
|
|
false
|
|
|
|
}
|
|
|
|
|
|
|
|
// [T; n] -> [T].
|
2016-08-26 19:23:42 +03:00
|
|
|
(&ty::TyArray(..), &ty::TySlice(_)) => true,
|
2015-04-15 11:57:29 +12:00
|
|
|
|
|
|
|
// Struct<T> -> Struct<U>.
|
2016-09-06 01:26:02 +03:00
|
|
|
(&ty::TyAdt(def_id_a, _), &ty::TyAdt(def_id_b, _)) if def_id_a.is_struct() => {
|
2015-04-15 11:57:29 +12:00
|
|
|
def_id_a == def_id_b
|
|
|
|
}
|
|
|
|
|
2017-06-08 14:49:54 +09:00
|
|
|
// (.., T) -> (.., U).
|
|
|
|
(&ty::TyTuple(tys_a, _), &ty::TyTuple(tys_b, _)) => {
|
|
|
|
tys_a.len() == tys_b.len()
|
|
|
|
}
|
|
|
|
|
2015-04-15 11:57:29 +12:00
|
|
|
_ => false
|
|
|
|
};
|
|
|
|
|
|
|
|
if may_apply {
|
|
|
|
candidates.vec.push(BuiltinUnsizeCandidate);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-09 17:19:50 -04:00
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// WINNOW
|
|
|
|
//
|
|
|
|
// Winnowing is the process of attempting to resolve ambiguity by
|
|
|
|
// probing further. During the winnowing process, we unify all
|
|
|
|
// type variables (ignoring skolemization) and then we also
|
|
|
|
// attempt to evaluate recursive bounds to see if they are
|
|
|
|
// satisfied.
|
|
|
|
|
2015-02-16 06:57:38 -05:00
|
|
|
/// Returns true if `candidate_i` should be dropped in favor of
|
|
|
|
/// `candidate_j`. Generally speaking we will drop duplicate
|
|
|
|
/// candidates and prefer where-clause candidates.
|
2015-05-07 22:21:57 +03:00
|
|
|
/// Returns true if `victim` should be dropped in favor of
|
|
|
|
/// `other`. Generally speaking we will drop duplicate
|
|
|
|
/// candidates and prefer where-clause candidates.
|
|
|
|
///
|
|
|
|
/// See the comment for "SelectionCandidate" for more details.
|
2015-12-22 10:20:47 -08:00
|
|
|
fn candidate_should_be_dropped_in_favor_of<'o>(
|
|
|
|
&mut self,
|
|
|
|
victim: &EvaluatedCandidate<'tcx>,
|
|
|
|
other: &EvaluatedCandidate<'tcx>)
|
|
|
|
-> bool
|
2014-10-09 17:19:50 -04:00
|
|
|
{
|
2015-12-22 10:20:47 -08:00
|
|
|
if victim.candidate == other.candidate {
|
2015-01-08 21:41:42 -05:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-12-22 10:20:47 -08:00
|
|
|
match other.candidate {
|
|
|
|
ObjectCandidate |
|
|
|
|
ParamCandidate(_) | ProjectionCandidate => match victim.candidate {
|
2017-10-09 13:59:20 -03:00
|
|
|
AutoImplCandidate(..) => {
|
2016-03-25 01:14:29 +01:00
|
|
|
bug!(
|
2015-05-07 22:21:57 +03:00
|
|
|
"default implementations shouldn't be recorded \
|
|
|
|
when there are other valid candidates");
|
|
|
|
}
|
2015-12-22 10:20:47 -08:00
|
|
|
ImplCandidate(..) |
|
2017-08-15 23:30:13 +03:00
|
|
|
ClosureCandidate |
|
|
|
|
GeneratorCandidate |
|
2015-12-22 10:20:47 -08:00
|
|
|
FnPointerCandidate |
|
|
|
|
BuiltinObjectCandidate |
|
|
|
|
BuiltinUnsizeCandidate |
|
2016-04-18 00:04:21 +03:00
|
|
|
BuiltinCandidate { .. } => {
|
2015-05-07 22:21:57 +03:00
|
|
|
// We have a where-clause so don't go around looking
|
|
|
|
// for impls.
|
|
|
|
true
|
|
|
|
}
|
2015-12-22 10:20:47 -08:00
|
|
|
ObjectCandidate |
|
|
|
|
ProjectionCandidate => {
|
2015-05-07 22:21:57 +03:00
|
|
|
// Arbitrarily give param candidates priority
|
|
|
|
// over projection and object candidates.
|
|
|
|
true
|
|
|
|
},
|
2015-12-22 10:20:47 -08:00
|
|
|
ParamCandidate(..) => false,
|
|
|
|
},
|
|
|
|
ImplCandidate(other_def) => {
|
|
|
|
// See if we can toss out `victim` based on specialization.
|
|
|
|
// This requires us to know *for sure* that the `other` impl applies
|
|
|
|
// i.e. EvaluatedToOk:
|
|
|
|
if other.evaluation == EvaluatedToOk {
|
|
|
|
if let ImplCandidate(victim_def) = victim.candidate {
|
2016-04-29 06:00:23 +03:00
|
|
|
let tcx = self.tcx().global_tcx();
|
2017-08-29 09:25:25 -07:00
|
|
|
return tcx.specializes((other_def, victim_def)) ||
|
2017-03-17 12:43:15 -04:00
|
|
|
tcx.impls_are_allowed_to_overlap(other_def, victim_def);
|
2015-12-22 10:20:47 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
false
|
2015-05-07 22:21:57 +03:00
|
|
|
},
|
|
|
|
_ => false
|
2014-09-12 10:53:35 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-18 11:08:04 -04:00
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// BUILTIN BOUNDS
|
|
|
|
//
|
|
|
|
// These cover the traits that are built-in to the language
|
|
|
|
// itself. This includes `Copy` and `Sized` for sure. For the
|
|
|
|
// moment, it also includes `Send` / `Sync` and a few others, but
|
|
|
|
// those will hopefully change to library-defined traits in the
|
|
|
|
// future.
|
|
|
|
|
2016-04-14 15:49:39 +03:00
|
|
|
// HACK: if this returns an error, selection exits without considering
|
|
|
|
// other impls.
|
2014-09-29 22:11:30 +03:00
|
|
|
fn assemble_builtin_bound_candidates<'o>(&mut self,
|
2016-04-18 00:04:21 +03:00
|
|
|
conditions: BuiltinImplConditions<'tcx>,
|
2014-12-17 14:16:28 -05:00
|
|
|
candidates: &mut SelectionCandidateSet<'tcx>)
|
2014-09-29 22:11:30 +03:00
|
|
|
-> Result<(),SelectionError<'tcx>>
|
2014-09-18 11:08:04 -04:00
|
|
|
{
|
2016-04-18 00:04:21 +03:00
|
|
|
match conditions {
|
|
|
|
BuiltinImplConditions::Where(nested) => {
|
|
|
|
debug!("builtin_bound: nested={:?}", nested);
|
|
|
|
candidates.vec.push(BuiltinCandidate {
|
|
|
|
has_nested: nested.skip_binder().len() > 0
|
|
|
|
});
|
2014-11-07 16:14:32 -05:00
|
|
|
Ok(())
|
2014-09-18 11:08:04 -04:00
|
|
|
}
|
2016-04-14 15:49:39 +03:00
|
|
|
BuiltinImplConditions::None => { Ok(()) }
|
|
|
|
BuiltinImplConditions::Ambiguous => {
|
2015-01-21 17:45:52 -05:00
|
|
|
debug!("assemble_builtin_bound_candidates: ambiguous builtin");
|
|
|
|
Ok(candidates.ambiguous = true)
|
|
|
|
}
|
2016-04-18 00:04:21 +03:00
|
|
|
BuiltinImplConditions::Never => { Err(Unimplemented) }
|
2014-10-09 17:19:50 -04:00
|
|
|
}
|
|
|
|
}
|
2014-09-18 11:08:04 -04:00
|
|
|
|
2016-04-18 00:04:21 +03:00
|
|
|
fn sized_conditions(&mut self, obligation: &TraitObligation<'tcx>)
|
2016-04-14 15:49:39 +03:00
|
|
|
-> BuiltinImplConditions<'tcx>
|
2014-10-09 17:19:50 -04:00
|
|
|
{
|
2016-04-18 00:04:21 +03:00
|
|
|
use self::BuiltinImplConditions::{Ambiguous, None, Never, Where};
|
2016-04-14 15:49:39 +03:00
|
|
|
|
2016-04-18 00:04:21 +03:00
|
|
|
// NOTE: binder moved to (*)
|
|
|
|
let self_ty = self.infcx.shallow_resolve(
|
|
|
|
obligation.predicate.skip_binder().self_ty());
|
2016-04-14 15:49:39 +03:00
|
|
|
|
2016-04-18 00:04:21 +03:00
|
|
|
match self_ty.sty {
|
|
|
|
ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) |
|
|
|
|
ty::TyUint(_) | ty::TyInt(_) | ty::TyBool | ty::TyFloat(_) |
|
|
|
|
ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyRawPtr(..) |
|
2016-12-26 14:34:03 +01:00
|
|
|
ty::TyChar | ty::TyRef(..) | ty::TyGenerator(..) |
|
2017-10-07 16:36:28 +02:00
|
|
|
ty::TyGeneratorWitness(..) | ty::TyArray(..) | ty::TyClosure(..) |
|
|
|
|
ty::TyNever | ty::TyError => {
|
2014-09-18 11:08:04 -04:00
|
|
|
// safe for everything
|
2016-04-18 00:04:21 +03:00
|
|
|
Where(ty::Binder(Vec::new()))
|
2014-09-18 11:08:04 -04:00
|
|
|
}
|
|
|
|
|
2017-09-03 19:53:58 +01:00
|
|
|
ty::TyStr | ty::TySlice(_) | ty::TyDynamic(..) | ty::TyForeign(..) => Never,
|
2014-09-18 11:08:04 -04:00
|
|
|
|
2017-01-11 15:58:37 +08:00
|
|
|
ty::TyTuple(tys, _) => {
|
2016-09-01 13:34:56 +03:00
|
|
|
Where(ty::Binder(tys.last().into_iter().cloned().collect()))
|
2016-04-22 01:46:23 +03:00
|
|
|
}
|
|
|
|
|
2016-09-06 01:26:02 +03:00
|
|
|
ty::TyAdt(def, substs) => {
|
2016-04-18 00:04:21 +03:00
|
|
|
let sized_crit = def.sized_constraint(self.tcx());
|
|
|
|
// (*) binder moved here
|
2017-04-21 20:24:32 +03:00
|
|
|
Where(ty::Binder(
|
|
|
|
sized_crit.iter().map(|ty| ty.subst(self.tcx(), substs)).collect()
|
|
|
|
))
|
2014-09-18 11:08:04 -04:00
|
|
|
}
|
|
|
|
|
2016-07-22 18:56:22 +03:00
|
|
|
ty::TyProjection(_) | ty::TyParam(_) | ty::TyAnon(..) => None,
|
2016-04-18 00:04:21 +03:00
|
|
|
ty::TyInfer(ty::TyVar(_)) => Ambiguous,
|
2014-11-16 18:20:19 +00:00
|
|
|
|
2016-04-18 00:04:21 +03:00
|
|
|
ty::TyInfer(ty::FreshTy(_))
|
|
|
|
| ty::TyInfer(ty::FreshIntTy(_))
|
|
|
|
| ty::TyInfer(ty::FreshFloatTy(_)) => {
|
|
|
|
bug!("asked to assemble builtin bounds of unexpected type: {:?}",
|
|
|
|
self_ty);
|
2014-09-18 11:08:04 -04:00
|
|
|
}
|
2016-04-18 00:04:21 +03:00
|
|
|
}
|
|
|
|
}
|
2014-09-18 11:08:04 -04:00
|
|
|
|
2017-09-13 22:40:48 +02:00
|
|
|
fn copy_clone_conditions(&mut self, obligation: &TraitObligation<'tcx>)
|
2016-04-18 00:04:21 +03:00
|
|
|
-> BuiltinImplConditions<'tcx>
|
|
|
|
{
|
|
|
|
// NOTE: binder moved to (*)
|
|
|
|
let self_ty = self.infcx.shallow_resolve(
|
|
|
|
obligation.predicate.skip_binder().self_ty());
|
2014-09-18 11:08:04 -04:00
|
|
|
|
2016-04-18 00:04:21 +03:00
|
|
|
use self::BuiltinImplConditions::{Ambiguous, None, Never, Where};
|
2014-09-18 11:08:04 -04:00
|
|
|
|
2016-04-18 00:04:21 +03:00
|
|
|
match self_ty.sty {
|
|
|
|
ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) |
|
|
|
|
ty::TyUint(_) | ty::TyInt(_) | ty::TyBool | ty::TyFloat(_) |
|
|
|
|
ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyChar |
|
2016-08-02 15:56:20 +08:00
|
|
|
ty::TyRawPtr(..) | ty::TyError | ty::TyNever |
|
2016-04-18 00:04:21 +03:00
|
|
|
ty::TyRef(_, ty::TypeAndMut { ty: _, mutbl: hir::MutImmutable }) => {
|
|
|
|
Where(ty::Binder(Vec::new()))
|
2014-09-18 11:08:04 -04:00
|
|
|
}
|
|
|
|
|
2017-09-03 19:53:58 +01:00
|
|
|
ty::TyDynamic(..) | ty::TyStr | ty::TySlice(..) |
|
2017-10-07 16:36:28 +02:00
|
|
|
ty::TyGenerator(..) | ty::TyGeneratorWitness(..) | ty::TyForeign(..) |
|
2016-04-18 00:04:21 +03:00
|
|
|
ty::TyRef(_, ty::TypeAndMut { ty: _, mutbl: hir::MutMutable }) => {
|
|
|
|
Never
|
2014-09-18 11:08:04 -04:00
|
|
|
}
|
|
|
|
|
2016-04-18 00:04:21 +03:00
|
|
|
ty::TyArray(element_ty, _) => {
|
|
|
|
// (*) binder moved here
|
|
|
|
Where(ty::Binder(vec![element_ty]))
|
2014-09-18 11:08:04 -04:00
|
|
|
}
|
|
|
|
|
2017-01-11 15:58:37 +08:00
|
|
|
ty::TyTuple(tys, _) => {
|
2016-04-18 00:04:21 +03:00
|
|
|
// (*) binder moved here
|
2016-04-29 08:30:54 +03:00
|
|
|
Where(ty::Binder(tys.to_vec()))
|
2014-09-18 11:08:04 -04:00
|
|
|
}
|
|
|
|
|
2017-09-13 22:40:48 +02:00
|
|
|
ty::TyClosure(def_id, substs) => {
|
|
|
|
let trait_id = obligation.predicate.def_id();
|
|
|
|
let copy_closures =
|
|
|
|
Some(trait_id) == self.tcx().lang_items().copy_trait() &&
|
2017-09-20 20:42:49 +02:00
|
|
|
self.tcx().has_copy_closures(def_id.krate);
|
2017-09-13 22:40:48 +02:00
|
|
|
let clone_closures =
|
|
|
|
Some(trait_id) == self.tcx().lang_items().clone_trait() &&
|
2017-09-20 20:42:49 +02:00
|
|
|
self.tcx().has_clone_closures(def_id.krate);
|
2017-09-13 22:40:48 +02:00
|
|
|
|
|
|
|
if copy_closures || clone_closures {
|
|
|
|
Where(ty::Binder(substs.upvar_tys(def_id, self.tcx()).collect()))
|
|
|
|
} else {
|
|
|
|
Never
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-06 01:26:02 +03:00
|
|
|
ty::TyAdt(..) | ty::TyProjection(..) | ty::TyParam(..) | ty::TyAnon(..) => {
|
2016-04-18 00:04:21 +03:00
|
|
|
// Fallback to whatever user-defined impls exist in this case.
|
|
|
|
None
|
2014-09-18 11:08:04 -04:00
|
|
|
}
|
|
|
|
|
2015-06-11 16:21:46 -07:00
|
|
|
ty::TyInfer(ty::TyVar(_)) => {
|
2014-10-09 17:19:50 -04:00
|
|
|
// Unbound type variable. Might or might not have
|
|
|
|
// applicable impls and so forth, depending on what
|
|
|
|
// those type variables wind up being bound to.
|
2016-04-18 00:04:21 +03:00
|
|
|
Ambiguous
|
2014-09-18 11:08:04 -04:00
|
|
|
}
|
|
|
|
|
2015-06-11 16:21:46 -07:00
|
|
|
ty::TyInfer(ty::FreshTy(_))
|
|
|
|
| ty::TyInfer(ty::FreshIntTy(_))
|
|
|
|
| ty::TyInfer(ty::FreshFloatTy(_)) => {
|
2016-03-25 01:14:29 +01:00
|
|
|
bug!("asked to assemble builtin bounds of unexpected type: {:?}",
|
|
|
|
self_ty);
|
2014-09-18 11:08:04 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-20 05:16:59 -05:00
|
|
|
/// For default impls, we need to break apart a type into its
|
|
|
|
/// "constituent types" -- meaning, the types that it contains.
|
|
|
|
///
|
|
|
|
/// Here are some (simple) examples:
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// (i32, u32) -> [i32, u32]
|
|
|
|
/// Foo where struct Foo { x: i32, y: u32 } -> [i32, u32]
|
|
|
|
/// Bar<i32> where struct Bar<T> { x: T, y: u32 } -> [i32, u32]
|
|
|
|
/// Zed<i32> where enum Zed { A(T), B(u32) } -> [i32, u32]
|
|
|
|
/// ```
|
2015-07-17 08:22:03 -04:00
|
|
|
fn constituent_types_for_ty(&self, t: Ty<'tcx>) -> Vec<Ty<'tcx>> {
|
2015-02-02 12:14:01 +01:00
|
|
|
match t.sty {
|
2015-06-11 16:21:46 -07:00
|
|
|
ty::TyUint(_) |
|
|
|
|
ty::TyInt(_) |
|
|
|
|
ty::TyBool |
|
|
|
|
ty::TyFloat(_) |
|
2015-06-13 13:15:03 -07:00
|
|
|
ty::TyFnDef(..) |
|
|
|
|
ty::TyFnPtr(_) |
|
2015-06-11 16:21:46 -07:00
|
|
|
ty::TyStr |
|
|
|
|
ty::TyError |
|
|
|
|
ty::TyInfer(ty::IntVar(_)) |
|
|
|
|
ty::TyInfer(ty::FloatVar(_)) |
|
2016-08-02 15:56:20 +08:00
|
|
|
ty::TyNever |
|
2015-06-11 16:21:46 -07:00
|
|
|
ty::TyChar => {
|
2015-07-17 08:22:03 -04:00
|
|
|
Vec::new()
|
2015-02-02 12:14:01 +01:00
|
|
|
}
|
|
|
|
|
2016-11-16 09:21:49 -07:00
|
|
|
ty::TyDynamic(..) |
|
2015-06-11 16:21:46 -07:00
|
|
|
ty::TyParam(..) |
|
2017-09-03 19:53:58 +01:00
|
|
|
ty::TyForeign(..) |
|
2015-06-11 16:21:46 -07:00
|
|
|
ty::TyProjection(..) |
|
|
|
|
ty::TyInfer(ty::TyVar(_)) |
|
|
|
|
ty::TyInfer(ty::FreshTy(_)) |
|
|
|
|
ty::TyInfer(ty::FreshIntTy(_)) |
|
|
|
|
ty::TyInfer(ty::FreshFloatTy(_)) => {
|
2016-03-25 01:14:29 +01:00
|
|
|
bug!("asked to assemble constituent types of unexpected type: {:?}",
|
|
|
|
t);
|
2015-02-02 12:14:01 +01:00
|
|
|
}
|
|
|
|
|
2015-07-10 18:27:06 -07:00
|
|
|
ty::TyRawPtr(ty::TypeAndMut { ty: element_ty, ..}) |
|
|
|
|
ty::TyRef(_, ty::TypeAndMut { ty: element_ty, ..}) => {
|
2015-07-17 08:22:03 -04:00
|
|
|
vec![element_ty]
|
2015-02-02 12:14:01 +01:00
|
|
|
},
|
2014-09-18 11:08:04 -04:00
|
|
|
|
2015-06-12 16:50:13 -07:00
|
|
|
ty::TyArray(element_ty, _) | ty::TySlice(element_ty) => {
|
2015-07-17 08:22:03 -04:00
|
|
|
vec![element_ty]
|
2015-02-02 12:14:01 +01:00
|
|
|
}
|
|
|
|
|
2017-01-11 15:58:37 +08:00
|
|
|
ty::TyTuple(ref tys, _) => {
|
2015-02-02 12:14:01 +01:00
|
|
|
// (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
|
2016-04-29 08:30:54 +03:00
|
|
|
tys.to_vec()
|
2015-02-02 12:14:01 +01:00
|
|
|
}
|
|
|
|
|
2016-11-03 22:19:33 +02:00
|
|
|
ty::TyClosure(def_id, ref substs) => {
|
|
|
|
substs.upvar_tys(def_id, self.tcx()).collect()
|
2015-02-02 12:14:01 +01:00
|
|
|
}
|
2014-09-18 11:08:04 -04:00
|
|
|
|
2016-12-26 14:34:03 +01:00
|
|
|
ty::TyGenerator(def_id, ref substs, interior) => {
|
2017-10-07 16:36:28 +02:00
|
|
|
substs.upvar_tys(def_id, self.tcx()).chain(iter::once(interior.witness)).collect()
|
|
|
|
}
|
|
|
|
|
|
|
|
ty::TyGeneratorWitness(types) => {
|
|
|
|
// This is sound because no regions in the witness can refer to
|
|
|
|
// the binder outside the witness. So we'll effectivly reuse
|
|
|
|
// the implicit binder around the witness.
|
|
|
|
types.skip_binder().to_vec()
|
2016-12-26 14:34:03 +01:00
|
|
|
}
|
|
|
|
|
2015-03-05 16:20:02 -05:00
|
|
|
// for `PhantomData<T>`, we pass `T`
|
2016-09-06 01:26:02 +03:00
|
|
|
ty::TyAdt(def, substs) if def.is_phantom_data() => {
|
2016-08-27 01:13:48 +03:00
|
|
|
substs.types().collect()
|
2015-03-05 16:20:02 -05:00
|
|
|
}
|
|
|
|
|
2016-09-06 01:26:02 +03:00
|
|
|
ty::TyAdt(def, substs) => {
|
2015-08-02 22:52:50 +03:00
|
|
|
def.all_fields()
|
|
|
|
.map(|f| f.ty(self.tcx(), substs))
|
2015-07-20 22:13:36 +03:00
|
|
|
.collect()
|
2015-02-02 12:14:01 +01:00
|
|
|
}
|
2017-02-14 11:32:00 +02:00
|
|
|
|
|
|
|
ty::TyAnon(def_id, substs) => {
|
|
|
|
// We can resolve the `impl Trait` to its concrete type,
|
|
|
|
// which enforces a DAG between the functions requiring
|
|
|
|
// the auto trait bounds in question.
|
2017-04-24 15:20:46 +03:00
|
|
|
vec![self.tcx().type_of(def_id).subst(self.tcx(), substs)]
|
2017-02-14 11:32:00 +02:00
|
|
|
}
|
2014-09-18 11:08:04 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-27 01:13:31 +01:00
|
|
|
fn collect_predicates_for_types(&mut self,
|
2017-05-23 04:19:47 -04:00
|
|
|
param_env: ty::ParamEnv<'tcx>,
|
2016-05-01 17:46:56 +03:00
|
|
|
cause: ObligationCause<'tcx>,
|
|
|
|
recursion_depth: usize,
|
2015-08-16 06:32:28 -04:00
|
|
|
trait_def_id: DefId,
|
2015-03-26 15:53:00 -04:00
|
|
|
types: ty::Binder<Vec<Ty<'tcx>>>)
|
|
|
|
-> Vec<PredicateObligation<'tcx>>
|
|
|
|
{
|
|
|
|
// Because the types were potentially derived from
|
|
|
|
// higher-ranked obligations they may reference late-bound
|
|
|
|
// regions. For example, `for<'a> Foo<&'a int> : Copy` would
|
|
|
|
// yield a type like `for<'a> &'a int`. In general, we
|
|
|
|
// maintain the invariant that we never manipulate bound
|
|
|
|
// regions, so we have to process these bound regions somehow.
|
|
|
|
//
|
|
|
|
// The strategy is to:
|
|
|
|
//
|
|
|
|
// 1. Instantiate those regions to skolemized regions (e.g.,
|
|
|
|
// `for<'a> &'a int` becomes `&0 int`.
|
|
|
|
// 2. Produce something like `&'0 int : Copy`
|
|
|
|
// 3. Re-bind the regions back to `for<'a> &'a int : Copy`
|
|
|
|
|
2016-05-01 17:19:11 +03:00
|
|
|
types.skip_binder().into_iter().flat_map(|ty| { // binder moved -\
|
|
|
|
let ty: ty::Binder<Ty<'tcx>> = ty::Binder(ty); // <----------/
|
2015-03-26 15:53:00 -04:00
|
|
|
|
2016-05-11 17:22:13 -07:00
|
|
|
self.in_snapshot(|this, snapshot| {
|
2015-02-27 01:13:31 +01:00
|
|
|
let (skol_ty, skol_map) =
|
2016-05-11 17:22:13 -07:00
|
|
|
this.infcx().skolemize_late_bound_regions(&ty, snapshot);
|
2015-03-26 15:53:00 -04:00
|
|
|
let Normalized { value: normalized_ty, mut obligations } =
|
2016-05-11 17:22:13 -07:00
|
|
|
project::normalize_with_depth(this,
|
2017-05-23 04:19:47 -04:00
|
|
|
param_env,
|
2016-05-01 17:46:56 +03:00
|
|
|
cause.clone(),
|
|
|
|
recursion_depth,
|
2015-03-26 15:53:00 -04:00
|
|
|
&skol_ty);
|
|
|
|
let skol_obligation =
|
2017-05-23 04:19:47 -04:00
|
|
|
this.tcx().predicate_for_trait_def(param_env,
|
|
|
|
cause.clone(),
|
|
|
|
trait_def_id,
|
|
|
|
recursion_depth,
|
|
|
|
normalized_ty,
|
|
|
|
&[]);
|
2015-03-26 15:53:00 -04:00
|
|
|
obligations.push(skol_obligation);
|
2016-09-30 17:44:48 +10:00
|
|
|
this.infcx().plug_leaks(skol_map, snapshot, obligations)
|
2015-02-27 01:13:31 +01:00
|
|
|
})
|
2016-05-01 17:19:11 +03:00
|
|
|
}).collect()
|
2015-02-27 01:13:31 +01:00
|
|
|
}
|
|
|
|
|
2014-09-12 10:53:35 -04:00
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// CONFIRMATION
|
|
|
|
//
|
|
|
|
// Confirmation unifies the output type parameters of the trait
|
|
|
|
// with the values found in the obligation, possibly yielding a
|
2015-02-18 19:34:55 -08:00
|
|
|
// type error. See `README.md` for more details.
|
2014-09-12 10:53:35 -04:00
|
|
|
|
2014-09-18 11:08:04 -04:00
|
|
|
fn confirm_candidate(&mut self,
|
2014-12-05 00:03:03 -05:00
|
|
|
obligation: &TraitObligation<'tcx>,
|
2014-12-17 14:16:28 -05:00
|
|
|
candidate: SelectionCandidate<'tcx>)
|
2014-09-29 22:11:30 +03:00
|
|
|
-> Result<Selection<'tcx>,SelectionError<'tcx>>
|
2014-09-12 10:53:35 -04:00
|
|
|
{
|
2015-06-18 20:25:05 +03:00
|
|
|
debug!("confirm_candidate({:?}, {:?})",
|
|
|
|
obligation,
|
|
|
|
candidate);
|
2014-09-12 10:53:35 -04:00
|
|
|
|
|
|
|
match candidate {
|
2016-04-18 00:04:21 +03:00
|
|
|
BuiltinCandidate { has_nested } => {
|
2017-08-04 14:44:12 +02:00
|
|
|
let data = self.confirm_builtin_candidate(obligation, has_nested);
|
|
|
|
Ok(VtableBuiltin(data))
|
2014-11-07 16:14:32 -05:00
|
|
|
}
|
|
|
|
|
2014-10-09 17:19:50 -04:00
|
|
|
ParamCandidate(param) => {
|
2015-01-08 21:41:42 -05:00
|
|
|
let obligations = self.confirm_param_candidate(obligation, param);
|
|
|
|
Ok(VtableParam(obligations))
|
2014-09-12 10:53:35 -04:00
|
|
|
}
|
|
|
|
|
2017-10-09 13:59:20 -03:00
|
|
|
AutoImplCandidate(trait_def_id) => {
|
|
|
|
let data = self.confirm_auto_impl_candidate(obligation, trait_def_id);
|
|
|
|
Ok(VtableAutoImpl(data))
|
2015-03-24 15:55:29 -04:00
|
|
|
}
|
|
|
|
|
2014-10-09 17:19:50 -04:00
|
|
|
ImplCandidate(impl_def_id) => {
|
2016-05-01 17:19:11 +03:00
|
|
|
Ok(VtableImpl(self.confirm_impl_candidate(obligation, impl_def_id)))
|
2014-09-12 10:53:35 -04:00
|
|
|
}
|
|
|
|
|
2017-08-15 23:30:13 +03:00
|
|
|
ClosureCandidate => {
|
|
|
|
let vtable_closure = self.confirm_closure_candidate(obligation)?;
|
2015-06-10 00:09:37 +03:00
|
|
|
Ok(VtableClosure(vtable_closure))
|
2014-09-12 10:53:35 -04:00
|
|
|
}
|
2014-12-01 09:23:40 -05:00
|
|
|
|
2017-08-15 23:30:13 +03:00
|
|
|
GeneratorCandidate => {
|
|
|
|
let vtable_generator = self.confirm_generator_candidate(obligation)?;
|
2016-12-26 14:34:03 +01:00
|
|
|
Ok(VtableGenerator(vtable_generator))
|
|
|
|
}
|
|
|
|
|
2015-02-18 11:58:44 -05:00
|
|
|
BuiltinObjectCandidate => {
|
|
|
|
// This indicates something like `(Trait+Send) :
|
|
|
|
// Send`. In this case, we know that this holds
|
|
|
|
// because that's what the object type is telling us,
|
|
|
|
// and there's really no additional obligations to
|
|
|
|
// prove and no types in particular to unify etc.
|
|
|
|
Ok(VtableParam(Vec::new()))
|
|
|
|
}
|
|
|
|
|
2014-12-23 05:26:34 -05:00
|
|
|
ObjectCandidate => {
|
|
|
|
let data = self.confirm_object_candidate(obligation);
|
|
|
|
Ok(VtableObject(data))
|
|
|
|
}
|
|
|
|
|
2014-12-01 09:23:40 -05:00
|
|
|
FnPointerCandidate => {
|
2016-05-11 14:40:24 -07:00
|
|
|
let data =
|
2016-03-22 22:01:37 -05:00
|
|
|
self.confirm_fn_pointer_candidate(obligation)?;
|
2016-05-11 14:40:24 -07:00
|
|
|
Ok(VtableFnPointer(data))
|
2014-12-01 09:23:40 -05:00
|
|
|
}
|
2014-12-27 04:22:29 -05:00
|
|
|
|
|
|
|
ProjectionCandidate => {
|
|
|
|
self.confirm_projection_candidate(obligation);
|
2015-01-08 21:41:42 -05:00
|
|
|
Ok(VtableParam(Vec::new()))
|
2014-12-27 04:22:29 -05:00
|
|
|
}
|
2015-04-15 11:57:29 +12:00
|
|
|
|
|
|
|
BuiltinUnsizeCandidate => {
|
2016-03-22 22:01:37 -05:00
|
|
|
let data = self.confirm_builtin_unsize_candidate(obligation)?;
|
2015-04-15 11:57:29 +12:00
|
|
|
Ok(VtableBuiltin(data))
|
|
|
|
}
|
2014-09-12 10:53:35 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-27 04:22:29 -05:00
|
|
|
fn confirm_projection_candidate(&mut self,
|
|
|
|
obligation: &TraitObligation<'tcx>)
|
|
|
|
{
|
2016-05-11 17:22:13 -07:00
|
|
|
self.in_snapshot(|this, snapshot| {
|
2016-05-01 17:19:11 +03:00
|
|
|
let result =
|
2016-07-22 18:56:22 +03:00
|
|
|
this.match_projection_obligation_against_definition_bounds(obligation,
|
2016-05-01 17:19:11 +03:00
|
|
|
snapshot);
|
|
|
|
assert!(result);
|
|
|
|
})
|
2014-12-27 04:22:29 -05:00
|
|
|
}
|
|
|
|
|
2014-09-18 11:08:04 -04:00
|
|
|
fn confirm_param_candidate(&mut self,
|
2014-12-05 00:03:03 -05:00
|
|
|
obligation: &TraitObligation<'tcx>,
|
2014-12-27 04:22:29 -05:00
|
|
|
param: ty::PolyTraitRef<'tcx>)
|
2015-01-08 21:41:42 -05:00
|
|
|
-> Vec<PredicateObligation<'tcx>>
|
2014-09-12 10:53:35 -04:00
|
|
|
{
|
2015-06-18 20:25:05 +03:00
|
|
|
debug!("confirm_param_candidate({:?},{:?})",
|
|
|
|
obligation,
|
|
|
|
param);
|
2014-09-12 10:53:35 -04:00
|
|
|
|
2014-12-14 07:17:23 -05:00
|
|
|
// During evaluation, we already checked that this
|
|
|
|
// where-clause trait-ref could be unified with the obligation
|
|
|
|
// trait-ref. Repeat that unification now without any
|
|
|
|
// transactional boundary; it should not fail.
|
2015-01-08 21:41:42 -05:00
|
|
|
match self.match_where_clause_trait_ref(obligation, param.clone()) {
|
|
|
|
Ok(obligations) => obligations,
|
|
|
|
Err(()) => {
|
2016-03-25 01:14:29 +01:00
|
|
|
bug!("Where clause `{:?}` was applicable to `{:?}` but now is not",
|
|
|
|
param,
|
|
|
|
obligation);
|
2014-12-14 07:17:23 -05:00
|
|
|
}
|
|
|
|
}
|
2014-09-12 10:53:35 -04:00
|
|
|
}
|
|
|
|
|
2014-10-09 17:19:50 -04:00
|
|
|
fn confirm_builtin_candidate(&mut self,
|
2014-12-05 00:03:03 -05:00
|
|
|
obligation: &TraitObligation<'tcx>,
|
2016-04-18 00:04:21 +03:00
|
|
|
has_nested: bool)
|
2016-04-14 15:49:39 +03:00
|
|
|
-> VtableBuiltinData<PredicateObligation<'tcx>>
|
2014-10-09 17:19:50 -04:00
|
|
|
{
|
2016-04-18 00:04:21 +03:00
|
|
|
debug!("confirm_builtin_candidate({:?}, {:?})",
|
|
|
|
obligation, has_nested);
|
|
|
|
|
2017-08-31 08:57:41 -07:00
|
|
|
let lang_items = self.tcx().lang_items();
|
2016-04-18 00:04:21 +03:00
|
|
|
let obligations = if has_nested {
|
|
|
|
let trait_def = obligation.predicate.def_id();
|
|
|
|
let conditions = match trait_def {
|
2017-08-31 08:57:41 -07:00
|
|
|
_ if Some(trait_def) == lang_items.sized_trait() => {
|
2016-04-18 00:04:21 +03:00
|
|
|
self.sized_conditions(obligation)
|
|
|
|
}
|
2017-08-31 08:57:41 -07:00
|
|
|
_ if Some(trait_def) == lang_items.copy_trait() => {
|
2017-09-13 22:40:48 +02:00
|
|
|
self.copy_clone_conditions(obligation)
|
2016-04-18 00:04:21 +03:00
|
|
|
}
|
2017-08-31 08:57:41 -07:00
|
|
|
_ if Some(trait_def) == lang_items.clone_trait() => {
|
2017-09-13 22:40:48 +02:00
|
|
|
self.copy_clone_conditions(obligation)
|
2017-08-04 14:44:12 +02:00
|
|
|
}
|
2016-04-18 00:04:21 +03:00
|
|
|
_ => bug!("unexpected builtin trait {:?}", trait_def)
|
|
|
|
};
|
|
|
|
let nested = match conditions {
|
|
|
|
BuiltinImplConditions::Where(nested) => nested,
|
|
|
|
_ => bug!("obligation {:?} had matched a builtin impl but now doesn't",
|
|
|
|
obligation)
|
|
|
|
};
|
2016-01-08 21:41:37 -05:00
|
|
|
|
2016-07-28 18:27:11 +03:00
|
|
|
let cause = obligation.derived_cause(BuiltinDerivedObligation);
|
2017-05-23 04:19:47 -04:00
|
|
|
self.collect_predicates_for_types(obligation.param_env,
|
|
|
|
cause,
|
2016-05-01 17:46:56 +03:00
|
|
|
obligation.recursion_depth+1,
|
|
|
|
trait_def,
|
|
|
|
nested)
|
2016-04-18 00:04:21 +03:00
|
|
|
} else {
|
|
|
|
vec![]
|
2014-10-09 17:19:50 -04:00
|
|
|
};
|
2014-12-07 11:10:48 -05:00
|
|
|
|
2016-04-18 00:04:21 +03:00
|
|
|
debug!("confirm_builtin_candidate: obligations={:?}",
|
2015-06-18 20:25:05 +03:00
|
|
|
obligations);
|
2017-08-04 14:44:12 +02:00
|
|
|
|
2014-10-09 17:19:50 -04:00
|
|
|
VtableBuiltinData { nested: obligations }
|
|
|
|
}
|
|
|
|
|
2017-12-01 10:01:23 -02:00
|
|
|
/// This handles the case where a `auto trait Foo` impl is being used.
|
2015-02-19 10:30:45 -05:00
|
|
|
/// The idea is that the impl applies to `X : Foo` if the following conditions are met:
|
|
|
|
///
|
|
|
|
/// 1. For each constituent type `Y` in `X`, `Y : Foo` holds
|
|
|
|
/// 2. For each where-clause `C` declared on `Foo`, `[Self => X] C` holds.
|
2017-10-09 13:59:20 -03:00
|
|
|
fn confirm_auto_impl_candidate(&mut self,
|
2015-02-18 23:31:03 +01:00
|
|
|
obligation: &TraitObligation<'tcx>,
|
2015-08-16 06:32:28 -04:00
|
|
|
trait_def_id: DefId)
|
2017-10-09 13:59:20 -03:00
|
|
|
-> VtableAutoImplData<PredicateObligation<'tcx>>
|
2015-02-02 12:14:01 +01:00
|
|
|
{
|
2017-10-09 13:59:20 -03:00
|
|
|
debug!("confirm_auto_impl_candidate({:?}, {:?})",
|
2015-06-18 20:25:05 +03:00
|
|
|
obligation,
|
|
|
|
trait_def_id);
|
2015-02-02 12:14:01 +01:00
|
|
|
|
2015-03-26 15:53:00 -04:00
|
|
|
// binder is moved below
|
|
|
|
let self_ty = self.infcx.shallow_resolve(obligation.predicate.skip_binder().self_ty());
|
2015-07-17 08:22:03 -04:00
|
|
|
let types = self.constituent_types_for_ty(self_ty);
|
2017-10-09 13:59:20 -03:00
|
|
|
self.vtable_auto_impl(obligation, trait_def_id, ty::Binder(types))
|
2015-02-02 12:14:01 +01:00
|
|
|
}
|
|
|
|
|
2017-10-09 13:59:20 -03:00
|
|
|
/// See `confirm_auto_impl_candidate`
|
|
|
|
fn vtable_auto_impl(&mut self,
|
2015-02-02 12:14:01 +01:00
|
|
|
obligation: &TraitObligation<'tcx>,
|
2015-08-16 06:32:28 -04:00
|
|
|
trait_def_id: DefId,
|
2015-03-26 15:53:00 -04:00
|
|
|
nested: ty::Binder<Vec<Ty<'tcx>>>)
|
2017-10-09 13:59:20 -03:00
|
|
|
-> VtableAutoImplData<PredicateObligation<'tcx>>
|
2015-02-02 12:14:01 +01:00
|
|
|
{
|
2017-10-09 13:59:20 -03:00
|
|
|
debug!("vtable_auto_impl: nested={:?}", nested);
|
2015-02-18 23:31:03 +01:00
|
|
|
|
2016-07-28 18:27:11 +03:00
|
|
|
let cause = obligation.derived_cause(BuiltinDerivedObligation);
|
2016-05-01 17:46:56 +03:00
|
|
|
let mut obligations = self.collect_predicates_for_types(
|
2017-05-23 04:19:47 -04:00
|
|
|
obligation.param_env,
|
2016-05-01 17:46:56 +03:00
|
|
|
cause,
|
|
|
|
obligation.recursion_depth+1,
|
|
|
|
trait_def_id,
|
|
|
|
nested);
|
2015-02-02 12:14:01 +01:00
|
|
|
|
2016-05-11 17:22:13 -07:00
|
|
|
let trait_obligations = self.in_snapshot(|this, snapshot| {
|
2015-03-26 15:53:00 -04:00
|
|
|
let poly_trait_ref = obligation.predicate.to_poly_trait_ref();
|
|
|
|
let (trait_ref, skol_map) =
|
2016-05-11 17:22:13 -07:00
|
|
|
this.infcx().skolemize_late_bound_regions(&poly_trait_ref, snapshot);
|
2016-07-28 18:27:11 +03:00
|
|
|
let cause = obligation.derived_cause(ImplDerivedObligation);
|
2016-05-11 17:22:13 -07:00
|
|
|
this.impl_or_trait_obligations(cause,
|
2016-05-01 17:19:11 +03:00
|
|
|
obligation.recursion_depth + 1,
|
2017-05-23 04:19:47 -04:00
|
|
|
obligation.param_env,
|
2016-05-01 17:19:11 +03:00
|
|
|
trait_def_id,
|
|
|
|
&trait_ref.substs,
|
|
|
|
skol_map,
|
|
|
|
snapshot)
|
2015-02-18 23:31:03 +01:00
|
|
|
});
|
|
|
|
|
2016-05-01 17:19:11 +03:00
|
|
|
obligations.extend(trait_obligations);
|
2015-03-26 15:53:00 -04:00
|
|
|
|
2017-10-09 13:59:20 -03:00
|
|
|
debug!("vtable_auto_impl: obligations={:?}", obligations);
|
2015-02-02 12:14:01 +01:00
|
|
|
|
2017-10-09 13:59:20 -03:00
|
|
|
VtableAutoImplData {
|
2017-07-03 11:19:51 -07:00
|
|
|
trait_def_id,
|
2015-02-02 12:14:01 +01:00
|
|
|
nested: obligations
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-18 11:08:04 -04:00
|
|
|
fn confirm_impl_candidate(&mut self,
|
2014-12-05 00:03:03 -05:00
|
|
|
obligation: &TraitObligation<'tcx>,
|
2015-08-16 06:32:28 -04:00
|
|
|
impl_def_id: DefId)
|
2016-05-01 17:19:11 +03:00
|
|
|
-> VtableImplData<'tcx, PredicateObligation<'tcx>>
|
2014-09-12 10:53:35 -04:00
|
|
|
{
|
2015-06-18 20:25:05 +03:00
|
|
|
debug!("confirm_impl_candidate({:?},{:?})",
|
|
|
|
obligation,
|
|
|
|
impl_def_id);
|
2014-09-12 10:53:35 -04:00
|
|
|
|
2014-10-09 17:19:50 -04:00
|
|
|
// First, create the substitutions by matching the impl again,
|
|
|
|
// this time not in a probe.
|
2016-05-11 17:22:13 -07:00
|
|
|
self.in_snapshot(|this, snapshot| {
|
2015-04-19 23:38:37 +03:00
|
|
|
let (substs, skol_map) =
|
2016-05-11 17:22:13 -07:00
|
|
|
this.rematch_impl(impl_def_id, obligation,
|
2015-04-19 23:38:37 +03:00
|
|
|
snapshot);
|
2015-06-18 20:25:05 +03:00
|
|
|
debug!("confirm_impl_candidate substs={:?}", substs);
|
2016-07-28 18:27:11 +03:00
|
|
|
let cause = obligation.derived_cause(ImplDerivedObligation);
|
2017-05-23 04:19:47 -04:00
|
|
|
this.vtable_impl(impl_def_id,
|
|
|
|
substs,
|
|
|
|
cause,
|
2016-05-01 17:46:56 +03:00
|
|
|
obligation.recursion_depth + 1,
|
2017-05-23 04:19:47 -04:00
|
|
|
obligation.param_env,
|
|
|
|
skol_map,
|
|
|
|
snapshot)
|
2014-12-14 07:17:23 -05:00
|
|
|
})
|
2014-09-12 10:53:35 -04:00
|
|
|
}
|
|
|
|
|
2014-10-09 17:19:50 -04:00
|
|
|
fn vtable_impl(&mut self,
|
2015-08-16 06:32:28 -04:00
|
|
|
impl_def_id: DefId,
|
2016-04-29 08:30:54 +03:00
|
|
|
mut substs: Normalized<'tcx, &'tcx Substs<'tcx>>,
|
2014-09-29 22:11:30 +03:00
|
|
|
cause: ObligationCause<'tcx>,
|
2015-03-25 17:06:52 -07:00
|
|
|
recursion_depth: usize,
|
2017-05-23 04:19:47 -04:00
|
|
|
param_env: ty::ParamEnv<'tcx>,
|
2016-08-25 23:58:52 +03:00
|
|
|
skol_map: infer::SkolemizationMap<'tcx>,
|
2014-12-14 07:17:23 -05:00
|
|
|
snapshot: &infer::CombinedSnapshot)
|
2014-12-07 11:10:48 -05:00
|
|
|
-> VtableImplData<'tcx, PredicateObligation<'tcx>>
|
2014-09-12 10:53:35 -04:00
|
|
|
{
|
2015-06-18 20:25:05 +03:00
|
|
|
debug!("vtable_impl(impl_def_id={:?}, substs={:?}, recursion_depth={}, skol_map={:?})",
|
|
|
|
impl_def_id,
|
|
|
|
substs,
|
2014-12-14 07:17:23 -05:00
|
|
|
recursion_depth,
|
2015-06-18 20:25:05 +03:00
|
|
|
skol_map);
|
2014-12-14 07:17:23 -05:00
|
|
|
|
2015-01-08 06:58:41 -05:00
|
|
|
let mut impl_obligations =
|
2015-02-19 10:30:45 -05:00
|
|
|
self.impl_or_trait_obligations(cause,
|
|
|
|
recursion_depth,
|
2017-05-23 04:19:47 -04:00
|
|
|
param_env,
|
2015-02-19 10:30:45 -05:00
|
|
|
impl_def_id,
|
|
|
|
&substs.value,
|
|
|
|
skol_map,
|
|
|
|
snapshot);
|
2014-12-14 07:17:23 -05:00
|
|
|
|
2015-06-18 20:25:05 +03:00
|
|
|
debug!("vtable_impl: impl_def_id={:?} impl_obligations={:?}",
|
|
|
|
impl_def_id,
|
|
|
|
impl_obligations);
|
2015-01-08 06:58:41 -05:00
|
|
|
|
2015-10-20 17:15:58 +03:00
|
|
|
// Because of RFC447, the impl-trait-ref and obligations
|
|
|
|
// are sufficient to determine the impl substs, without
|
|
|
|
// relying on projections in the impl-trait-ref.
|
|
|
|
//
|
|
|
|
// e.g. `impl<U: Tr, V: Iterator<Item=U>> Foo<<U as Tr>::T> for V`
|
2015-06-03 02:14:45 +03:00
|
|
|
impl_obligations.append(&mut substs.obligations);
|
2014-12-14 07:17:23 -05:00
|
|
|
|
2017-07-03 11:19:51 -07:00
|
|
|
VtableImplData { impl_def_id,
|
2016-04-29 08:30:54 +03:00
|
|
|
substs: substs.value,
|
2015-01-08 06:58:41 -05:00
|
|
|
nested: impl_obligations }
|
2014-09-12 10:53:35 -04:00
|
|
|
}
|
|
|
|
|
2014-12-23 05:26:34 -05:00
|
|
|
fn confirm_object_candidate(&mut self,
|
|
|
|
obligation: &TraitObligation<'tcx>)
|
2016-05-11 14:40:24 -07:00
|
|
|
-> VtableObjectData<'tcx, PredicateObligation<'tcx>>
|
2014-12-23 05:26:34 -05:00
|
|
|
{
|
2015-06-18 20:25:05 +03:00
|
|
|
debug!("confirm_object_candidate({:?})",
|
|
|
|
obligation);
|
2014-12-23 05:26:34 -05:00
|
|
|
|
2015-03-26 15:53:00 -04:00
|
|
|
// FIXME skipping binder here seems wrong -- we should
|
|
|
|
// probably flatten the binder from the obligation and the
|
|
|
|
// binder from the object. Have to try to make a broken test
|
|
|
|
// case that results. -nmatsakis
|
|
|
|
let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
|
2014-12-23 05:26:34 -05:00
|
|
|
let poly_trait_ref = match self_ty.sty {
|
2016-11-16 09:21:49 -07:00
|
|
|
ty::TyDynamic(ref data, ..) => {
|
2016-11-12 15:46:16 -07:00
|
|
|
data.principal().unwrap().with_self_ty(self.tcx(), self_ty)
|
2014-12-23 05:26:34 -05:00
|
|
|
}
|
|
|
|
_ => {
|
2016-03-25 18:31:27 +01:00
|
|
|
span_bug!(obligation.cause.span,
|
|
|
|
"object candidate with non-object");
|
2014-12-23 05:26:34 -05:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-07-04 05:46:54 +03:00
|
|
|
let mut upcast_trait_ref = None;
|
2015-07-24 10:23:35 -04:00
|
|
|
let vtable_base;
|
|
|
|
|
|
|
|
{
|
2016-05-11 17:22:13 -07:00
|
|
|
let tcx = self.tcx();
|
|
|
|
|
2015-07-24 10:23:35 -04:00
|
|
|
// We want to find the first supertrait in the list of
|
|
|
|
// supertraits that we can unify with, and do that
|
|
|
|
// unification. We know that there is exactly one in the list
|
|
|
|
// where we can unify because otherwise select would have
|
|
|
|
// reported an ambiguity. (When we do find a match, also
|
|
|
|
// record it for later.)
|
|
|
|
let nonmatching =
|
2016-05-11 17:22:13 -07:00
|
|
|
util::supertraits(tcx, poly_trait_ref)
|
2015-07-24 10:23:35 -04:00
|
|
|
.take_while(|&t| {
|
|
|
|
match
|
2016-05-11 17:22:13 -07:00
|
|
|
self.commit_if_ok(
|
|
|
|
|this, _| this.match_poly_trait_ref(obligation, t))
|
2015-07-24 10:23:35 -04:00
|
|
|
{
|
|
|
|
Ok(_) => { upcast_trait_ref = Some(t); false }
|
|
|
|
Err(_) => { true }
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Additionally, for each of the nonmatching predicates that
|
|
|
|
// we pass over, we sum up the set of number of vtable
|
|
|
|
// entries, so that we can compute the offset for the selected
|
|
|
|
// trait.
|
|
|
|
vtable_base =
|
2016-05-11 17:22:13 -07:00
|
|
|
nonmatching.map(|t| tcx.count_own_vtable_entries(t))
|
2015-07-24 10:23:35 -04:00
|
|
|
.sum();
|
2014-12-23 05:26:34 -05:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2015-07-04 05:46:54 +03:00
|
|
|
VtableObjectData {
|
|
|
|
upcast_trait_ref: upcast_trait_ref.unwrap(),
|
2017-07-03 11:19:51 -07:00
|
|
|
vtable_base,
|
2016-05-11 14:40:24 -07:00
|
|
|
nested: vec![]
|
2015-07-04 05:46:54 +03:00
|
|
|
}
|
2014-12-23 05:26:34 -05:00
|
|
|
}
|
|
|
|
|
2016-05-11 14:40:24 -07:00
|
|
|
fn confirm_fn_pointer_candidate(&mut self, obligation: &TraitObligation<'tcx>)
|
|
|
|
-> Result<VtableFnPointerData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>>
|
2014-12-01 09:23:40 -05:00
|
|
|
{
|
2015-06-18 20:25:05 +03:00
|
|
|
debug!("confirm_fn_pointer_candidate({:?})",
|
|
|
|
obligation);
|
2014-12-01 09:23:40 -05:00
|
|
|
|
2015-03-26 15:53:00 -04:00
|
|
|
// ok to skip binder; it is reintroduced below
|
|
|
|
let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
|
2017-05-13 17:11:52 +03:00
|
|
|
let sig = self_ty.fn_sig(self.tcx());
|
2015-03-26 15:53:00 -04:00
|
|
|
let trait_ref =
|
2016-03-17 00:15:31 +02:00
|
|
|
self.tcx().closure_trait_ref_and_return_type(obligation.predicate.def_id(),
|
|
|
|
self_ty,
|
|
|
|
sig,
|
|
|
|
util::TupleArgumentsFlag::Yes)
|
2015-03-26 15:53:00 -04:00
|
|
|
.map_bound(|(trait_ref, _)| trait_ref);
|
2014-12-01 09:23:40 -05:00
|
|
|
|
2017-05-13 17:11:52 +03:00
|
|
|
let Normalized { value: trait_ref, obligations } =
|
|
|
|
project::normalize_with_depth(self,
|
|
|
|
obligation.param_env,
|
|
|
|
obligation.cause.clone(),
|
|
|
|
obligation.recursion_depth + 1,
|
|
|
|
&trait_ref);
|
|
|
|
|
2016-03-22 22:01:37 -05:00
|
|
|
self.confirm_poly_trait_refs(obligation.cause.clone(),
|
2017-05-23 04:19:47 -04:00
|
|
|
obligation.param_env,
|
2016-03-22 17:58:45 -05:00
|
|
|
obligation.predicate.to_poly_trait_ref(),
|
|
|
|
trait_ref)?;
|
2017-05-13 17:11:52 +03:00
|
|
|
Ok(VtableFnPointerData { fn_ty: self_ty, nested: obligations })
|
2014-12-01 09:23:40 -05:00
|
|
|
}
|
|
|
|
|
2016-12-26 14:34:03 +01:00
|
|
|
fn confirm_generator_candidate(&mut self,
|
2017-08-15 23:30:13 +03:00
|
|
|
obligation: &TraitObligation<'tcx>)
|
|
|
|
-> Result<VtableGeneratorData<'tcx, PredicateObligation<'tcx>>,
|
2016-12-26 14:34:03 +01:00
|
|
|
SelectionError<'tcx>>
|
|
|
|
{
|
2017-08-15 23:30:13 +03:00
|
|
|
// ok to skip binder because the substs on generator types never
|
|
|
|
// touch bound regions, they just capture the in-scope
|
|
|
|
// type/region parameters
|
|
|
|
let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
|
|
|
|
let (closure_def_id, substs) = match self_ty.sty {
|
|
|
|
ty::TyGenerator(id, substs, _) => (id, substs),
|
|
|
|
_ => bug!("closure candidate for non-closure {:?}", obligation)
|
|
|
|
};
|
|
|
|
|
2016-12-26 14:34:03 +01:00
|
|
|
debug!("confirm_generator_candidate({:?},{:?},{:?})",
|
|
|
|
obligation,
|
|
|
|
closure_def_id,
|
|
|
|
substs);
|
|
|
|
|
2017-08-15 23:30:13 +03:00
|
|
|
let trait_ref =
|
|
|
|
self.generator_trait_ref_unnormalized(obligation, closure_def_id, substs);
|
2016-12-26 14:34:03 +01:00
|
|
|
let Normalized {
|
|
|
|
value: trait_ref,
|
|
|
|
obligations
|
2017-08-15 23:30:13 +03:00
|
|
|
} = normalize_with_depth(self,
|
|
|
|
obligation.param_env,
|
|
|
|
obligation.cause.clone(),
|
|
|
|
obligation.recursion_depth+1,
|
|
|
|
&trait_ref);
|
2017-07-05 14:57:26 -07:00
|
|
|
|
2016-12-26 14:34:03 +01:00
|
|
|
debug!("confirm_generator_candidate(closure_def_id={:?}, trait_ref={:?}, obligations={:?})",
|
|
|
|
closure_def_id,
|
|
|
|
trait_ref,
|
|
|
|
obligations);
|
|
|
|
|
|
|
|
self.confirm_poly_trait_refs(obligation.cause.clone(),
|
|
|
|
obligation.param_env,
|
|
|
|
obligation.predicate.to_poly_trait_ref(),
|
|
|
|
trait_ref)?;
|
|
|
|
|
|
|
|
Ok(VtableGeneratorData {
|
|
|
|
closure_def_id: closure_def_id,
|
|
|
|
substs: substs.clone(),
|
|
|
|
nested: obligations
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2015-01-24 22:00:03 +02:00
|
|
|
fn confirm_closure_candidate(&mut self,
|
2017-08-15 23:30:13 +03:00
|
|
|
obligation: &TraitObligation<'tcx>)
|
2015-06-10 00:09:37 +03:00
|
|
|
-> Result<VtableClosureData<'tcx, PredicateObligation<'tcx>>,
|
|
|
|
SelectionError<'tcx>>
|
2014-09-12 10:53:35 -04:00
|
|
|
{
|
2017-08-15 23:30:13 +03:00
|
|
|
debug!("confirm_closure_candidate({:?})", obligation);
|
|
|
|
|
2017-08-31 08:57:41 -07:00
|
|
|
let kind = match self.tcx().lang_items().fn_trait_kind(obligation.predicate.0.def_id()) {
|
2017-08-15 23:30:13 +03:00
|
|
|
Some(k) => k,
|
|
|
|
None => bug!("closure candidate for non-fn trait {:?}", obligation)
|
|
|
|
};
|
|
|
|
|
|
|
|
// ok to skip binder because the substs on closure types never
|
|
|
|
// touch bound regions, they just capture the in-scope
|
|
|
|
// type/region parameters
|
|
|
|
let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
|
|
|
|
let (closure_def_id, substs) = match self_ty.sty {
|
|
|
|
ty::TyClosure(id, substs) => (id, substs),
|
|
|
|
_ => bug!("closure candidate for non-closure {:?}", obligation)
|
|
|
|
};
|
2014-09-12 10:53:35 -04:00
|
|
|
|
2017-08-15 23:30:13 +03:00
|
|
|
let trait_ref =
|
|
|
|
self.closure_trait_ref_unnormalized(obligation, closure_def_id, substs);
|
2015-06-10 00:09:37 +03:00
|
|
|
let Normalized {
|
|
|
|
value: trait_ref,
|
2016-04-06 00:20:59 -07:00
|
|
|
mut obligations
|
2017-08-15 23:30:13 +03:00
|
|
|
} = normalize_with_depth(self,
|
|
|
|
obligation.param_env,
|
|
|
|
obligation.cause.clone(),
|
|
|
|
obligation.recursion_depth+1,
|
|
|
|
&trait_ref);
|
2014-09-12 10:53:35 -04:00
|
|
|
|
2015-06-18 20:25:05 +03:00
|
|
|
debug!("confirm_closure_candidate(closure_def_id={:?}, trait_ref={:?}, obligations={:?})",
|
|
|
|
closure_def_id,
|
|
|
|
trait_ref,
|
|
|
|
obligations);
|
2015-06-10 00:09:37 +03:00
|
|
|
|
2016-03-22 22:01:37 -05:00
|
|
|
self.confirm_poly_trait_refs(obligation.cause.clone(),
|
2017-05-23 04:19:47 -04:00
|
|
|
obligation.param_env,
|
2016-03-22 17:58:45 -05:00
|
|
|
obligation.predicate.to_poly_trait_ref(),
|
|
|
|
trait_ref)?;
|
2014-11-26 10:07:22 -05:00
|
|
|
|
2016-04-06 00:20:59 -07:00
|
|
|
obligations.push(Obligation::new(
|
2017-05-23 04:19:47 -04:00
|
|
|
obligation.cause.clone(),
|
|
|
|
obligation.param_env,
|
2017-11-08 08:50:59 -05:00
|
|
|
ty::Predicate::ClosureKind(closure_def_id, substs, kind)));
|
2016-04-06 00:20:59 -07:00
|
|
|
|
2015-06-10 00:09:37 +03:00
|
|
|
Ok(VtableClosureData {
|
2017-07-03 11:19:51 -07:00
|
|
|
closure_def_id,
|
2015-06-10 00:09:37 +03:00
|
|
|
substs: substs.clone(),
|
|
|
|
nested: obligations
|
|
|
|
})
|
2014-12-14 07:17:23 -05:00
|
|
|
}
|
|
|
|
|
2015-01-24 22:15:08 +02:00
|
|
|
/// In the case of closure types and fn pointers,
|
2014-12-14 07:17:23 -05:00
|
|
|
/// we currently treat the input type parameters on the trait as
|
|
|
|
/// outputs. This means that when we have a match we have only
|
|
|
|
/// considered the self type, so we have to go back and make sure
|
|
|
|
/// to relate the argument types too. This is kind of wrong, but
|
|
|
|
/// since we control the full set of impls, also not that wrong,
|
|
|
|
/// and it DOES yield better error messages (since we don't report
|
|
|
|
/// errors as if there is no applicable impl, but rather report
|
|
|
|
/// errors are about mismatched argument types.
|
|
|
|
///
|
2015-10-07 23:11:25 +01:00
|
|
|
/// Here is an example. Imagine we have a closure expression
|
2014-12-14 07:17:23 -05:00
|
|
|
/// and we desugared it so that the type of the expression is
|
|
|
|
/// `Closure`, and `Closure` expects an int as argument. Then it
|
|
|
|
/// is "as if" the compiler generated this impl:
|
|
|
|
///
|
|
|
|
/// impl Fn(int) for Closure { ... }
|
|
|
|
///
|
2015-03-25 17:06:52 -07:00
|
|
|
/// Now imagine our obligation is `Fn(usize) for Closure`. So far
|
2014-12-14 07:17:23 -05:00
|
|
|
/// we have matched the self-type `Closure`. At this point we'll
|
2015-03-25 17:06:52 -07:00
|
|
|
/// compare the `int` to `usize` and generate an error.
|
2014-12-14 07:17:23 -05:00
|
|
|
///
|
|
|
|
/// Note that this checking occurs *after* the impl has selected,
|
|
|
|
/// because these output type parameters should not affect the
|
|
|
|
/// selection of the impl. Therefore, if there is a mismatch, we
|
|
|
|
/// report an error to the user.
|
|
|
|
fn confirm_poly_trait_refs(&mut self,
|
2016-11-07 13:25:06 -05:00
|
|
|
obligation_cause: ObligationCause<'tcx>,
|
2017-05-23 04:19:47 -04:00
|
|
|
obligation_param_env: ty::ParamEnv<'tcx>,
|
2014-12-17 14:16:28 -05:00
|
|
|
obligation_trait_ref: ty::PolyTraitRef<'tcx>,
|
|
|
|
expected_trait_ref: ty::PolyTraitRef<'tcx>)
|
2014-12-14 07:17:23 -05:00
|
|
|
-> Result<(), SelectionError<'tcx>>
|
|
|
|
{
|
|
|
|
let obligation_trait_ref = obligation_trait_ref.clone();
|
2017-05-24 09:43:20 -04:00
|
|
|
self.infcx
|
|
|
|
.at(&obligation_cause, obligation_param_env)
|
|
|
|
.sup(obligation_trait_ref, expected_trait_ref)
|
2016-05-11 17:22:13 -07:00
|
|
|
.map(|InferOk { obligations, .. }| self.inferred_obligations.extend(obligations))
|
2016-03-29 20:06:42 -07:00
|
|
|
.map_err(|e| OutputTypeParameterMismatch(expected_trait_ref, obligation_trait_ref, e))
|
2014-09-12 10:53:35 -04:00
|
|
|
}
|
|
|
|
|
2015-04-15 11:57:29 +12:00
|
|
|
fn confirm_builtin_unsize_candidate(&mut self,
|
|
|
|
obligation: &TraitObligation<'tcx>,)
|
2017-08-07 13:22:48 +02:00
|
|
|
-> Result<VtableBuiltinData<PredicateObligation<'tcx>>, SelectionError<'tcx>>
|
2017-08-04 14:44:12 +02:00
|
|
|
{
|
2015-04-15 11:57:29 +12:00
|
|
|
let tcx = self.tcx();
|
|
|
|
|
2015-05-13 14:57:47 +12:00
|
|
|
// assemble_candidates_for_unsizing should ensure there are no late bound
|
|
|
|
// regions here. See the comment there for more details.
|
|
|
|
let source = self.infcx.shallow_resolve(
|
2017-11-12 05:04:26 -05:00
|
|
|
obligation.self_ty().no_late_bound_regions().unwrap());
|
2016-08-18 08:32:50 +03:00
|
|
|
let target = obligation.predicate.skip_binder().trait_ref.substs.type_at(1);
|
2016-06-13 20:13:37 +03:00
|
|
|
let target = self.infcx.shallow_resolve(target);
|
2015-04-15 11:57:29 +12:00
|
|
|
|
2015-06-18 20:25:05 +03:00
|
|
|
debug!("confirm_builtin_unsize_candidate(source={:?}, target={:?})",
|
|
|
|
source, target);
|
2015-04-15 11:57:29 +12:00
|
|
|
|
|
|
|
let mut nested = vec![];
|
|
|
|
match (&source.sty, &target.sty) {
|
|
|
|
// Trait+Kx+'a -> Trait+Ky+'b (upcasts).
|
2016-11-16 09:21:49 -07:00
|
|
|
(&ty::TyDynamic(ref data_a, r_a), &ty::TyDynamic(ref data_b, r_b)) => {
|
2015-04-15 11:57:29 +12:00
|
|
|
// See assemble_candidates_for_unsizing for more info.
|
2016-11-16 09:21:49 -07:00
|
|
|
// Binders reintroduced below in call to mk_existential_predicates.
|
|
|
|
let principal = data_a.skip_binder().principal();
|
|
|
|
let iter = principal.into_iter().map(ty::ExistentialPredicate::Trait)
|
|
|
|
.chain(data_a.skip_binder().projection_bounds()
|
|
|
|
.map(|x| ty::ExistentialPredicate::Projection(x)))
|
|
|
|
.chain(data_b.auto_traits().map(ty::ExistentialPredicate::AutoTrait));
|
|
|
|
let new_trait = tcx.mk_dynamic(
|
|
|
|
ty::Binder(tcx.mk_existential_predicates(iter)), r_b);
|
2016-03-29 20:06:42 -07:00
|
|
|
let InferOk { obligations, .. } =
|
2017-05-24 09:43:20 -04:00
|
|
|
self.infcx.at(&obligation.cause, obligation.param_env)
|
|
|
|
.eq(target, new_trait)
|
|
|
|
.map_err(|_| Unimplemented)?;
|
2016-05-11 17:22:13 -07:00
|
|
|
self.inferred_obligations.extend(obligations);
|
2015-04-15 11:57:29 +12:00
|
|
|
|
|
|
|
// Register one obligation for 'a: 'b.
|
|
|
|
let cause = ObligationCause::new(obligation.cause.span,
|
|
|
|
obligation.cause.body_id,
|
|
|
|
ObjectCastObligation(target));
|
2016-11-16 09:21:49 -07:00
|
|
|
let outlives = ty::OutlivesPredicate(r_a, r_b);
|
2015-04-15 11:57:29 +12:00
|
|
|
nested.push(Obligation::with_depth(cause,
|
|
|
|
obligation.recursion_depth + 1,
|
2017-05-23 04:19:47 -04:00
|
|
|
obligation.param_env,
|
2015-06-23 11:50:50 -07:00
|
|
|
ty::Binder(outlives).to_predicate()));
|
2015-04-15 11:57:29 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
// T -> Trait.
|
2016-11-16 09:21:49 -07:00
|
|
|
(_, &ty::TyDynamic(ref data, r)) => {
|
2016-09-01 13:34:56 +03:00
|
|
|
let mut object_dids =
|
2016-11-16 09:21:49 -07:00
|
|
|
data.auto_traits().chain(data.principal().map(|p| p.def_id()));
|
2016-04-22 02:31:04 +03:00
|
|
|
if let Some(did) = object_dids.find(|did| {
|
2016-03-17 00:15:31 +02:00
|
|
|
!tcx.is_object_safe(*did)
|
2016-04-22 02:31:04 +03:00
|
|
|
}) {
|
|
|
|
return Err(TraitNotObjectSafe(did))
|
2015-04-15 11:57:29 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
let cause = ObligationCause::new(obligation.cause.span,
|
|
|
|
obligation.cause.body_id,
|
|
|
|
ObjectCastObligation(target));
|
|
|
|
let mut push = |predicate| {
|
|
|
|
nested.push(Obligation::with_depth(cause.clone(),
|
|
|
|
obligation.recursion_depth + 1,
|
2017-05-23 04:19:47 -04:00
|
|
|
obligation.param_env,
|
2015-04-15 11:57:29 +12:00
|
|
|
predicate));
|
|
|
|
};
|
|
|
|
|
2016-11-16 09:21:49 -07:00
|
|
|
// Create obligations:
|
|
|
|
// - Casting T to Trait
|
|
|
|
// - For all the various builtin bounds attached to the object cast. (In other
|
|
|
|
// words, if the object type is Foo+Send, this would create an obligation for the
|
|
|
|
// Send check.)
|
|
|
|
// - Projection predicates
|
|
|
|
for predicate in data.iter() {
|
|
|
|
push(predicate.with_self_ty(tcx, source));
|
2015-04-15 11:57:29 +12:00
|
|
|
}
|
|
|
|
|
2016-11-16 09:21:49 -07:00
|
|
|
// We can only make objects from sized types.
|
|
|
|
let tr = ty::TraitRef {
|
2016-11-25 21:21:03 -07:00
|
|
|
def_id: tcx.require_lang_item(lang_items::SizedTraitLangItem),
|
2016-11-16 09:21:49 -07:00
|
|
|
substs: tcx.mk_substs_trait(source, &[]),
|
|
|
|
};
|
|
|
|
push(tr.to_predicate());
|
2015-04-15 11:57:29 +12:00
|
|
|
|
|
|
|
// If the type is `Foo+'a`, ensures that the type
|
|
|
|
// being cast to `Foo+'a` outlives `'a`:
|
2016-11-16 09:21:49 -07:00
|
|
|
let outlives = ty::OutlivesPredicate(source, r);
|
2015-06-23 11:50:50 -07:00
|
|
|
push(ty::Binder(outlives).to_predicate());
|
2015-04-15 11:57:29 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
// [T; n] -> [T].
|
2015-06-12 16:50:13 -07:00
|
|
|
(&ty::TyArray(a, _), &ty::TySlice(b)) => {
|
2016-03-29 20:06:42 -07:00
|
|
|
let InferOk { obligations, .. } =
|
2017-05-24 09:43:20 -04:00
|
|
|
self.infcx.at(&obligation.cause, obligation.param_env)
|
|
|
|
.eq(b, a)
|
|
|
|
.map_err(|_| Unimplemented)?;
|
2016-05-11 17:22:13 -07:00
|
|
|
self.inferred_obligations.extend(obligations);
|
2015-04-15 11:57:29 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
// Struct<T> -> Struct<U>.
|
2016-09-06 01:26:02 +03:00
|
|
|
(&ty::TyAdt(def, substs_a), &ty::TyAdt(_, substs_b)) => {
|
2015-08-02 22:52:50 +03:00
|
|
|
let fields = def
|
|
|
|
.all_fields()
|
2017-04-24 15:20:46 +03:00
|
|
|
.map(|f| tcx.type_of(f.did))
|
2015-08-02 22:52:50 +03:00
|
|
|
.collect::<Vec<_>>();
|
2015-04-15 11:57:29 +12:00
|
|
|
|
2015-06-05 20:49:23 +03:00
|
|
|
// The last field of the structure has to exist and contain type parameters.
|
|
|
|
let field = if let Some(&field) = fields.last() {
|
|
|
|
field
|
2015-04-15 11:57:29 +12:00
|
|
|
} else {
|
|
|
|
return Err(Unimplemented);
|
|
|
|
};
|
2016-08-18 08:32:50 +03:00
|
|
|
let mut ty_params = BitVector::new(substs_a.types().count());
|
2016-08-08 23:39:49 +03:00
|
|
|
let mut found = false;
|
2015-06-24 08:24:13 +03:00
|
|
|
for ty in field.walk() {
|
2015-06-11 16:21:46 -07:00
|
|
|
if let ty::TyParam(p) = ty.sty {
|
2016-08-08 23:39:49 +03:00
|
|
|
ty_params.insert(p.idx as usize);
|
|
|
|
found = true;
|
2015-06-05 20:49:23 +03:00
|
|
|
}
|
2015-06-24 08:24:13 +03:00
|
|
|
}
|
2016-08-08 23:39:49 +03:00
|
|
|
if !found {
|
2015-06-05 20:49:23 +03:00
|
|
|
return Err(Unimplemented);
|
|
|
|
}
|
2015-04-15 11:57:29 +12:00
|
|
|
|
2015-06-05 20:49:23 +03:00
|
|
|
// Replace type parameters used in unsizing with
|
2015-06-11 16:21:46 -07:00
|
|
|
// TyError and ensure they do not affect any other fields.
|
2015-04-15 11:57:29 +12:00
|
|
|
// This could be checked after type collection for any struct
|
|
|
|
// with a potentially unsized trailing field.
|
2017-02-15 21:46:23 -08:00
|
|
|
let params = substs_a.iter().enumerate().map(|(i, &k)| {
|
2016-08-08 23:39:49 +03:00
|
|
|
if ty_params.contains(i) {
|
2016-08-27 01:13:48 +03:00
|
|
|
Kind::from(tcx.types.err)
|
2016-08-08 23:39:49 +03:00
|
|
|
} else {
|
2016-08-27 01:13:48 +03:00
|
|
|
k
|
2016-08-08 23:39:49 +03:00
|
|
|
}
|
2016-08-27 01:13:48 +03:00
|
|
|
});
|
2016-10-24 18:23:29 -06:00
|
|
|
let substs = tcx.mk_substs(params);
|
2015-07-11 14:34:57 +03:00
|
|
|
for &ty in fields.split_last().unwrap().1 {
|
2016-08-08 23:39:49 +03:00
|
|
|
if ty.subst(tcx, substs).references_error() {
|
2015-04-15 11:57:29 +12:00
|
|
|
return Err(Unimplemented);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-05 20:49:23 +03:00
|
|
|
// Extract Field<T> and Field<U> from Struct<T> and Struct<U>.
|
|
|
|
let inner_source = field.subst(tcx, substs_a);
|
|
|
|
let inner_target = field.subst(tcx, substs_b);
|
2015-04-15 11:57:29 +12:00
|
|
|
|
2017-06-29 20:00:31 +09:00
|
|
|
// Check that the source struct with the target's
|
|
|
|
// unsized parameters is equal to the target.
|
2017-02-15 21:46:23 -08:00
|
|
|
let params = substs_a.iter().enumerate().map(|(i, &k)| {
|
2016-08-08 23:39:49 +03:00
|
|
|
if ty_params.contains(i) {
|
2016-08-27 01:13:48 +03:00
|
|
|
Kind::from(substs_b.type_at(i))
|
2016-08-08 23:39:49 +03:00
|
|
|
} else {
|
2016-08-27 01:13:48 +03:00
|
|
|
k
|
2016-08-08 23:39:49 +03:00
|
|
|
}
|
2016-08-27 01:13:48 +03:00
|
|
|
});
|
2016-10-24 18:23:29 -06:00
|
|
|
let new_struct = tcx.mk_adt(def, tcx.mk_substs(params));
|
2016-03-29 20:06:42 -07:00
|
|
|
let InferOk { obligations, .. } =
|
2017-05-24 09:43:20 -04:00
|
|
|
self.infcx.at(&obligation.cause, obligation.param_env)
|
|
|
|
.eq(target, new_struct)
|
|
|
|
.map_err(|_| Unimplemented)?;
|
2016-05-11 17:22:13 -07:00
|
|
|
self.inferred_obligations.extend(obligations);
|
2015-04-15 11:57:29 +12:00
|
|
|
|
2015-06-05 20:49:23 +03:00
|
|
|
// Construct the nested Field<T>: Unsize<Field<U>> predicate.
|
2016-03-17 00:15:31 +02:00
|
|
|
nested.push(tcx.predicate_for_trait_def(
|
2017-05-23 04:19:47 -04:00
|
|
|
obligation.param_env,
|
2015-04-15 11:57:29 +12:00
|
|
|
obligation.cause.clone(),
|
|
|
|
obligation.predicate.def_id(),
|
|
|
|
obligation.recursion_depth + 1,
|
|
|
|
inner_source,
|
2016-08-27 01:13:48 +03:00
|
|
|
&[inner_target]));
|
2015-04-15 11:57:29 +12:00
|
|
|
}
|
|
|
|
|
2017-06-08 14:49:54 +09:00
|
|
|
// (.., T) -> (.., U).
|
|
|
|
(&ty::TyTuple(tys_a, _), &ty::TyTuple(tys_b, _)) => {
|
|
|
|
assert_eq!(tys_a.len(), tys_b.len());
|
|
|
|
|
|
|
|
// The last field of the tuple has to exist.
|
|
|
|
let (a_last, a_mid) = if let Some(x) = tys_a.split_last() {
|
|
|
|
x
|
|
|
|
} else {
|
|
|
|
return Err(Unimplemented);
|
|
|
|
};
|
|
|
|
let b_last = tys_b.last().unwrap();
|
|
|
|
|
|
|
|
// Check that the source tuple with the target's
|
2017-06-29 20:00:31 +09:00
|
|
|
// last element is equal to the target.
|
2017-06-08 14:49:54 +09:00
|
|
|
let new_tuple = tcx.mk_tup(a_mid.iter().chain(Some(b_last)), false);
|
|
|
|
let InferOk { obligations, .. } =
|
|
|
|
self.infcx.at(&obligation.cause, obligation.param_env)
|
|
|
|
.eq(target, new_tuple)
|
|
|
|
.map_err(|_| Unimplemented)?;
|
|
|
|
self.inferred_obligations.extend(obligations);
|
|
|
|
|
|
|
|
// Construct the nested T: Unsize<U> predicate.
|
|
|
|
nested.push(tcx.predicate_for_trait_def(
|
|
|
|
obligation.param_env,
|
|
|
|
obligation.cause.clone(),
|
|
|
|
obligation.predicate.def_id(),
|
|
|
|
obligation.recursion_depth + 1,
|
|
|
|
a_last,
|
|
|
|
&[b_last]));
|
|
|
|
}
|
|
|
|
|
2016-03-25 18:46:11 +01:00
|
|
|
_ => bug!()
|
2015-04-15 11:57:29 +12:00
|
|
|
};
|
|
|
|
|
2015-06-03 02:14:45 +03:00
|
|
|
Ok(VtableBuiltinData { nested: nested })
|
2015-04-15 11:57:29 +12:00
|
|
|
}
|
|
|
|
|
2014-09-12 10:53:35 -04:00
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// Matching
|
|
|
|
//
|
|
|
|
// Matching is a common path used for both evaluation and
|
|
|
|
// confirmation. It basically unifies types that appear in impls
|
|
|
|
// and traits. This does affect the surrounding environment;
|
|
|
|
// therefore, when used during evaluation, match routines must be
|
|
|
|
// run inside of a `probe()` so that their side-effects are
|
|
|
|
// contained.
|
|
|
|
|
2014-10-09 17:19:50 -04:00
|
|
|
fn rematch_impl(&mut self,
|
2015-08-16 06:32:28 -04:00
|
|
|
impl_def_id: DefId,
|
2014-12-14 07:17:23 -05:00
|
|
|
obligation: &TraitObligation<'tcx>,
|
2015-04-19 23:38:37 +03:00
|
|
|
snapshot: &infer::CombinedSnapshot)
|
2016-08-25 23:58:52 +03:00
|
|
|
-> (Normalized<'tcx, &'tcx Substs<'tcx>>,
|
|
|
|
infer::SkolemizationMap<'tcx>)
|
2014-10-09 17:19:50 -04:00
|
|
|
{
|
2015-04-19 23:38:37 +03:00
|
|
|
match self.match_impl(impl_def_id, obligation, snapshot) {
|
|
|
|
Ok((substs, skol_map)) => (substs, skol_map),
|
2014-10-09 17:19:50 -04:00
|
|
|
Err(()) => {
|
2016-03-25 01:14:29 +01:00
|
|
|
bug!("Impl {:?} was matchable against {:?} but now is not",
|
|
|
|
impl_def_id,
|
|
|
|
obligation);
|
2014-10-09 17:19:50 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn match_impl(&mut self,
|
2015-08-16 06:32:28 -04:00
|
|
|
impl_def_id: DefId,
|
2014-12-14 07:17:23 -05:00
|
|
|
obligation: &TraitObligation<'tcx>,
|
2015-04-19 23:38:37 +03:00
|
|
|
snapshot: &infer::CombinedSnapshot)
|
2016-04-29 08:30:54 +03:00
|
|
|
-> Result<(Normalized<'tcx, &'tcx Substs<'tcx>>,
|
2016-08-25 23:58:52 +03:00
|
|
|
infer::SkolemizationMap<'tcx>), ()>
|
2014-10-09 17:19:50 -04:00
|
|
|
{
|
2015-06-25 23:42:17 +03:00
|
|
|
let impl_trait_ref = self.tcx().impl_trait_ref(impl_def_id).unwrap();
|
2014-11-16 07:10:37 -05:00
|
|
|
|
|
|
|
// Before we create the substitutions and everything, first
|
|
|
|
// consider a "quick reject". This avoids creating more types
|
|
|
|
// and so forth that we need to.
|
2015-04-21 18:59:58 +03:00
|
|
|
if self.fast_reject_trait_refs(obligation, &impl_trait_ref) {
|
2014-11-16 07:10:37 -05:00
|
|
|
return Err(());
|
|
|
|
}
|
|
|
|
|
2015-04-19 23:38:37 +03:00
|
|
|
let (skol_obligation, skol_map) = self.infcx().skolemize_late_bound_regions(
|
|
|
|
&obligation.predicate,
|
|
|
|
snapshot);
|
|
|
|
let skol_obligation_trait_ref = skol_obligation.trait_ref;
|
|
|
|
|
2016-08-08 23:39:49 +03:00
|
|
|
let impl_substs = self.infcx.fresh_substs_for_item(obligation.cause.span,
|
|
|
|
impl_def_id);
|
2014-10-09 17:19:50 -04:00
|
|
|
|
|
|
|
let impl_trait_ref = impl_trait_ref.subst(self.tcx(),
|
2016-08-08 23:39:49 +03:00
|
|
|
impl_substs);
|
2014-10-09 17:19:50 -04:00
|
|
|
|
2015-01-08 06:58:41 -05:00
|
|
|
let impl_trait_ref =
|
|
|
|
project::normalize_with_depth(self,
|
2017-05-23 04:19:47 -04:00
|
|
|
obligation.param_env,
|
2015-01-08 06:58:41 -05:00
|
|
|
obligation.cause.clone(),
|
|
|
|
obligation.recursion_depth + 1,
|
|
|
|
&impl_trait_ref);
|
|
|
|
|
2015-06-18 20:25:05 +03:00
|
|
|
debug!("match_impl(impl_def_id={:?}, obligation={:?}, \
|
|
|
|
impl_trait_ref={:?}, skol_obligation_trait_ref={:?})",
|
|
|
|
impl_def_id,
|
|
|
|
obligation,
|
|
|
|
impl_trait_ref,
|
|
|
|
skol_obligation_trait_ref);
|
2014-12-14 07:17:23 -05:00
|
|
|
|
2016-03-29 20:06:42 -07:00
|
|
|
let InferOk { obligations, .. } =
|
2017-05-24 09:43:20 -04:00
|
|
|
self.infcx.at(&obligation.cause, obligation.param_env)
|
|
|
|
.eq(skol_obligation_trait_ref, impl_trait_ref.value)
|
|
|
|
.map_err(|e| {
|
|
|
|
debug!("match_impl: failed eq_trait_refs due to `{}`", e);
|
|
|
|
()
|
|
|
|
})?;
|
2016-05-11 17:22:13 -07:00
|
|
|
self.inferred_obligations.extend(obligations);
|
2014-12-14 07:17:23 -05:00
|
|
|
|
2016-04-20 19:51:56 -04:00
|
|
|
if let Err(e) = self.infcx.leak_check(false,
|
|
|
|
obligation.cause.span,
|
|
|
|
&skol_map,
|
|
|
|
snapshot) {
|
2015-06-18 08:51:23 +03:00
|
|
|
debug!("match_impl: failed leak check due to `{}`", e);
|
2015-02-24 09:50:36 +01:00
|
|
|
return Err(());
|
2014-10-09 17:19:50 -04:00
|
|
|
}
|
2014-12-14 07:17:23 -05:00
|
|
|
|
2015-06-18 20:25:05 +03:00
|
|
|
debug!("match_impl: success impl_substs={:?}", impl_substs);
|
2015-04-19 23:38:37 +03:00
|
|
|
Ok((Normalized {
|
2015-02-24 09:50:36 +01:00
|
|
|
value: impl_substs,
|
|
|
|
obligations: impl_trait_ref.obligations
|
2015-04-19 23:38:37 +03:00
|
|
|
}, skol_map))
|
2014-10-09 17:19:50 -04:00
|
|
|
}
|
|
|
|
|
2014-11-16 07:10:37 -05:00
|
|
|
fn fast_reject_trait_refs(&mut self,
|
2014-12-05 00:03:03 -05:00
|
|
|
obligation: &TraitObligation,
|
2014-12-14 07:17:23 -05:00
|
|
|
impl_trait_ref: &ty::TraitRef)
|
2014-11-16 07:10:37 -05:00
|
|
|
-> bool
|
|
|
|
{
|
|
|
|
// We can avoid creating type variables and doing the full
|
|
|
|
// substitution if we find that any of the input types, when
|
|
|
|
// simplified, do not match.
|
|
|
|
|
2016-08-18 08:32:50 +03:00
|
|
|
obligation.predicate.skip_binder().input_types()
|
2015-06-10 17:22:20 +01:00
|
|
|
.zip(impl_trait_ref.input_types())
|
2016-08-27 01:13:48 +03:00
|
|
|
.any(|(obligation_ty, impl_ty)| {
|
2014-11-16 07:10:37 -05:00
|
|
|
let simplified_obligation_ty =
|
|
|
|
fast_reject::simplify_type(self.tcx(), obligation_ty, true);
|
|
|
|
let simplified_impl_ty =
|
|
|
|
fast_reject::simplify_type(self.tcx(), impl_ty, false);
|
|
|
|
|
|
|
|
simplified_obligation_ty.is_some() &&
|
|
|
|
simplified_impl_ty.is_some() &&
|
|
|
|
simplified_obligation_ty != simplified_impl_ty
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2015-01-08 21:41:42 -05:00
|
|
|
/// Normalize `where_clause_trait_ref` and try to match it against
|
|
|
|
/// `obligation`. If successful, return any predicates that
|
|
|
|
/// result from the normalization. Normalization is necessary
|
|
|
|
/// because where-clauses are stored in the parameter environment
|
|
|
|
/// unnormalized.
|
|
|
|
fn match_where_clause_trait_ref(&mut self,
|
|
|
|
obligation: &TraitObligation<'tcx>,
|
|
|
|
where_clause_trait_ref: ty::PolyTraitRef<'tcx>)
|
|
|
|
-> Result<Vec<PredicateObligation<'tcx>>,()>
|
|
|
|
{
|
2016-03-22 22:01:37 -05:00
|
|
|
self.match_poly_trait_ref(obligation, where_clause_trait_ref)?;
|
2015-01-26 14:20:38 -05:00
|
|
|
Ok(Vec::new())
|
2015-01-08 21:41:42 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns `Ok` if `poly_trait_ref` being true implies that the
|
|
|
|
/// obligation is satisfied.
|
2016-05-11 17:22:13 -07:00
|
|
|
fn match_poly_trait_ref(&mut self,
|
2014-12-23 05:26:34 -05:00
|
|
|
obligation: &TraitObligation<'tcx>,
|
2015-01-08 21:41:42 -05:00
|
|
|
poly_trait_ref: ty::PolyTraitRef<'tcx>)
|
2014-12-23 05:26:34 -05:00
|
|
|
-> Result<(),()>
|
2014-10-09 17:19:50 -04:00
|
|
|
{
|
2015-06-18 20:25:05 +03:00
|
|
|
debug!("match_poly_trait_ref: obligation={:?} poly_trait_ref={:?}",
|
|
|
|
obligation,
|
|
|
|
poly_trait_ref);
|
2014-10-17 08:51:43 -04:00
|
|
|
|
2017-05-24 09:43:20 -04:00
|
|
|
self.infcx.at(&obligation.cause, obligation.param_env)
|
|
|
|
.sup(obligation.predicate.to_poly_trait_ref(), poly_trait_ref)
|
|
|
|
.map(|InferOk { obligations, .. }| self.inferred_obligations.extend(obligations))
|
|
|
|
.map_err(|_| ())
|
2014-10-09 17:19:50 -04:00
|
|
|
}
|
|
|
|
|
2014-09-12 10:53:35 -04:00
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// Miscellany
|
|
|
|
|
2015-03-20 08:17:09 -04:00
|
|
|
fn match_fresh_trait_refs(&self,
|
|
|
|
previous: &ty::PolyTraitRef<'tcx>,
|
|
|
|
current: &ty::PolyTraitRef<'tcx>)
|
|
|
|
-> bool
|
|
|
|
{
|
2015-09-06 18:32:34 +03:00
|
|
|
let mut matcher = ty::_match::Match::new(self.tcx());
|
2015-03-20 08:17:09 -04:00
|
|
|
matcher.relate(previous, current).is_ok()
|
|
|
|
}
|
|
|
|
|
2014-10-09 17:19:50 -04:00
|
|
|
fn push_stack<'o,'s:'o>(&mut self,
|
2015-03-30 17:46:34 -04:00
|
|
|
previous_stack: TraitObligationStackList<'s, 'tcx>,
|
2014-12-05 00:03:03 -05:00
|
|
|
obligation: &'o TraitObligation<'tcx>)
|
|
|
|
-> TraitObligationStack<'o, 'tcx>
|
2014-09-18 11:08:04 -04:00
|
|
|
{
|
2014-12-17 14:16:28 -05:00
|
|
|
let fresh_trait_ref =
|
|
|
|
obligation.predicate.to_poly_trait_ref().fold_with(&mut self.freshener);
|
2014-10-09 17:19:50 -04:00
|
|
|
|
2014-12-05 00:03:03 -05:00
|
|
|
TraitObligationStack {
|
2017-07-03 11:19:51 -07:00
|
|
|
obligation,
|
|
|
|
fresh_trait_ref,
|
2015-03-30 17:46:34 -04:00
|
|
|
previous: previous_stack,
|
2014-09-18 11:08:04 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-10 00:09:37 +03:00
|
|
|
fn closure_trait_ref_unnormalized(&mut self,
|
|
|
|
obligation: &TraitObligation<'tcx>,
|
2015-08-16 06:32:28 -04:00
|
|
|
closure_def_id: DefId,
|
2016-04-29 08:30:54 +03:00
|
|
|
substs: ty::ClosureSubsts<'tcx>)
|
2015-06-10 00:09:37 +03:00
|
|
|
-> ty::PolyTraitRef<'tcx>
|
2015-01-10 11:54:15 -05:00
|
|
|
{
|
2017-12-01 08:51:01 -05:00
|
|
|
let closure_type = self.infcx.closure_sig(closure_def_id, substs);
|
2015-01-10 11:54:15 -05:00
|
|
|
let ty::Binder((trait_ref, _)) =
|
2016-03-17 00:15:31 +02:00
|
|
|
self.tcx().closure_trait_ref_and_return_type(obligation.predicate.def_id(),
|
|
|
|
obligation.predicate.0.self_ty(), // (1)
|
2017-02-13 10:51:06 +02:00
|
|
|
closure_type,
|
2016-03-17 00:15:31 +02:00
|
|
|
util::TupleArgumentsFlag::No);
|
2015-01-10 11:54:15 -05:00
|
|
|
// (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
|
|
|
|
// regions bound in the obligation). Still probably some
|
|
|
|
// refactoring could make this nicer.
|
|
|
|
|
|
|
|
ty::Binder(trait_ref)
|
|
|
|
}
|
|
|
|
|
2016-12-26 14:34:03 +01:00
|
|
|
fn generator_trait_ref_unnormalized(&mut self,
|
|
|
|
obligation: &TraitObligation<'tcx>,
|
|
|
|
closure_def_id: DefId,
|
|
|
|
substs: ty::ClosureSubsts<'tcx>)
|
|
|
|
-> ty::PolyTraitRef<'tcx>
|
|
|
|
{
|
2017-11-09 15:44:29 -05:00
|
|
|
let gen_sig = substs.generator_poly_sig(closure_def_id, self.tcx());
|
2016-12-26 14:34:03 +01:00
|
|
|
let ty::Binder((trait_ref, ..)) =
|
|
|
|
self.tcx().generator_trait_ref_and_outputs(obligation.predicate.def_id(),
|
|
|
|
obligation.predicate.0.self_ty(), // (1)
|
|
|
|
gen_sig);
|
|
|
|
// (1) Feels icky to skip the binder here, but OTOH we know
|
|
|
|
// that the self-type is an generator type and hence is
|
|
|
|
// in fact unparameterized (or at least does not reference any
|
|
|
|
// regions bound in the obligation). Still probably some
|
|
|
|
// refactoring could make this nicer.
|
|
|
|
|
|
|
|
ty::Binder(trait_ref)
|
|
|
|
}
|
|
|
|
|
2015-02-19 10:30:45 -05:00
|
|
|
/// Returns the obligations that are implied by instantiating an
|
|
|
|
/// impl or trait. The obligations are substituted and fully
|
|
|
|
/// normalized. This is used when confirming an impl or default
|
|
|
|
/// impl.
|
|
|
|
fn impl_or_trait_obligations(&mut self,
|
|
|
|
cause: ObligationCause<'tcx>,
|
2015-03-25 17:06:52 -07:00
|
|
|
recursion_depth: usize,
|
2017-05-23 04:19:47 -04:00
|
|
|
param_env: ty::ParamEnv<'tcx>,
|
2015-08-16 06:32:28 -04:00
|
|
|
def_id: DefId, // of impl or trait
|
2015-02-19 10:30:45 -05:00
|
|
|
substs: &Substs<'tcx>, // for impl or trait
|
2016-08-25 23:58:52 +03:00
|
|
|
skol_map: infer::SkolemizationMap<'tcx>,
|
2015-02-19 10:30:45 -05:00
|
|
|
snapshot: &infer::CombinedSnapshot)
|
2015-06-03 02:14:45 +03:00
|
|
|
-> Vec<PredicateObligation<'tcx>>
|
2014-09-12 10:53:35 -04:00
|
|
|
{
|
2015-06-18 20:25:05 +03:00
|
|
|
debug!("impl_or_trait_obligations(def_id={:?})", def_id);
|
2015-10-21 19:01:58 +03:00
|
|
|
let tcx = self.tcx();
|
2015-03-26 15:53:00 -04:00
|
|
|
|
2015-10-21 19:01:58 +03:00
|
|
|
// To allow for one-pass evaluation of the nested obligation,
|
|
|
|
// each predicate must be preceded by the obligations required
|
|
|
|
// to normalize it.
|
|
|
|
// for example, if we have:
|
|
|
|
// impl<U: Iterator, V: Iterator<Item=U>> Foo for V where U::Item: Copy
|
|
|
|
// the impl will have the following predicates:
|
|
|
|
// <V as Iterator>::Item = U,
|
|
|
|
// U: Iterator, U: Sized,
|
|
|
|
// V: Iterator, V: Sized,
|
|
|
|
// <U as Iterator>::Item: Copy
|
|
|
|
// When we substitute, say, `V => IntoIter<u32>, U => $0`, the last
|
|
|
|
// obligation will normalize to `<$0 as Iterator>::Item = $1` and
|
|
|
|
// `$1: Copy`, so we must ensure the obligations are emitted in
|
|
|
|
// that order.
|
2017-04-24 15:20:46 +03:00
|
|
|
let predicates = tcx.predicates_of(def_id);
|
2016-08-11 09:19:42 +03:00
|
|
|
assert_eq!(predicates.parent, None);
|
|
|
|
let predicates = predicates.predicates.iter().flat_map(|predicate| {
|
2017-05-23 04:19:47 -04:00
|
|
|
let predicate = normalize_with_depth(self, param_env, cause.clone(), recursion_depth,
|
2016-08-11 09:19:42 +03:00
|
|
|
&predicate.subst(tcx, substs));
|
|
|
|
predicate.obligations.into_iter().chain(
|
|
|
|
Some(Obligation {
|
|
|
|
cause: cause.clone(),
|
2017-07-03 11:19:51 -07:00
|
|
|
recursion_depth,
|
2017-05-23 04:19:47 -04:00
|
|
|
param_env,
|
2016-08-11 09:19:42 +03:00
|
|
|
predicate: predicate.value
|
|
|
|
}))
|
|
|
|
}).collect();
|
2016-09-30 17:44:48 +10:00
|
|
|
self.infcx().plug_leaks(skol_map, snapshot, predicates)
|
2014-09-12 10:53:35 -04:00
|
|
|
}
|
2016-07-28 18:27:11 +03:00
|
|
|
}
|
2014-12-01 09:23:40 -05:00
|
|
|
|
2016-07-28 18:27:11 +03:00
|
|
|
impl<'tcx> TraitObligation<'tcx> {
|
2014-12-23 10:57:44 +01:00
|
|
|
#[allow(unused_comparisons)]
|
2016-07-28 18:27:11 +03:00
|
|
|
pub fn derived_cause(&self,
|
|
|
|
variant: fn(DerivedObligationCause<'tcx>) -> ObligationCauseCode<'tcx>)
|
|
|
|
-> ObligationCause<'tcx>
|
2014-12-06 11:39:25 -05:00
|
|
|
{
|
|
|
|
/*!
|
|
|
|
* Creates a cause for obligations that are derived from
|
|
|
|
* `obligation` by a recursive search (e.g., for a builtin
|
2017-12-01 10:01:23 -02:00
|
|
|
* bound, or eventually a `auto trait Foo`). If `obligation`
|
2014-12-06 11:39:25 -05:00
|
|
|
* is itself a derived obligation, this is just a clone, but
|
|
|
|
* otherwise we create a "derived obligation" cause so as to
|
|
|
|
* keep track of the original root obligation for error
|
|
|
|
* reporting.
|
|
|
|
*/
|
|
|
|
|
2016-07-28 18:27:11 +03:00
|
|
|
let obligation = self;
|
|
|
|
|
2014-12-23 10:57:44 +01:00
|
|
|
// NOTE(flaper87): As of now, it keeps track of the whole error
|
|
|
|
// chain. Ideally, we should have a way to configure this either
|
|
|
|
// by using -Z verbose or just a CLI argument.
|
|
|
|
if obligation.recursion_depth >= 0 {
|
2015-12-15 04:31:58 -05:00
|
|
|
let derived_cause = DerivedObligationCause {
|
|
|
|
parent_trait_ref: obligation.predicate.to_poly_trait_ref(),
|
|
|
|
parent_code: Rc::new(obligation.cause.code.clone())
|
2014-12-17 14:16:28 -05:00
|
|
|
};
|
2015-12-15 04:31:58 -05:00
|
|
|
let derived_code = variant(derived_cause);
|
2015-08-07 10:28:51 -04:00
|
|
|
ObligationCause::new(obligation.cause.span, obligation.cause.body_id, derived_code)
|
2014-12-06 11:39:25 -05:00
|
|
|
} else {
|
|
|
|
obligation.cause.clone()
|
|
|
|
}
|
|
|
|
}
|
2014-09-12 10:53:35 -04:00
|
|
|
}
|
|
|
|
|
2014-09-29 22:11:30 +03:00
|
|
|
impl<'tcx> SelectionCache<'tcx> {
|
|
|
|
pub fn new() -> SelectionCache<'tcx> {
|
2014-09-17 16:12:02 -04:00
|
|
|
SelectionCache {
|
2016-11-08 14:02:55 +11:00
|
|
|
hashmap: RefCell::new(FxHashMap())
|
2014-09-17 16:12:02 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-18 19:15:57 +03:00
|
|
|
impl<'tcx> EvaluationCache<'tcx> {
|
|
|
|
pub fn new() -> EvaluationCache<'tcx> {
|
|
|
|
EvaluationCache {
|
2016-11-08 14:02:55 +11:00
|
|
|
hashmap: RefCell::new(FxHashMap())
|
2015-10-18 19:15:57 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-30 17:46:34 -04:00
|
|
|
impl<'o,'tcx> TraitObligationStack<'o,'tcx> {
|
|
|
|
fn list(&'o self) -> TraitObligationStackList<'o,'tcx> {
|
|
|
|
TraitObligationStackList::with(self)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn iter(&'o self) -> TraitObligationStackList<'o,'tcx> {
|
|
|
|
self.list()
|
2014-09-18 11:08:04 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-30 17:46:34 -04:00
|
|
|
#[derive(Copy, Clone)]
|
|
|
|
struct TraitObligationStackList<'o,'tcx:'o> {
|
|
|
|
head: Option<&'o TraitObligationStack<'o,'tcx>>
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'o,'tcx> TraitObligationStackList<'o,'tcx> {
|
|
|
|
fn empty() -> TraitObligationStackList<'o,'tcx> {
|
|
|
|
TraitObligationStackList { head: None }
|
|
|
|
}
|
|
|
|
|
|
|
|
fn with(r: &'o TraitObligationStack<'o,'tcx>) -> TraitObligationStackList<'o,'tcx> {
|
|
|
|
TraitObligationStackList { head: Some(r) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'o,'tcx> Iterator for TraitObligationStackList<'o,'tcx>{
|
2015-01-01 23:26:38 -05:00
|
|
|
type Item = &'o TraitObligationStack<'o,'tcx>;
|
|
|
|
|
2015-03-30 17:46:34 -04:00
|
|
|
fn next(&mut self) -> Option<&'o TraitObligationStack<'o,'tcx>> {
|
|
|
|
match self.head {
|
2014-09-18 11:08:04 -04:00
|
|
|
Some(o) => {
|
|
|
|
*self = o.previous;
|
|
|
|
Some(o)
|
|
|
|
}
|
2015-02-24 09:50:36 +01:00
|
|
|
None => None
|
2014-09-18 11:08:04 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-18 08:51:23 +03:00
|
|
|
impl<'o,'tcx> fmt::Debug for TraitObligationStack<'o,'tcx> {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
write!(f, "TraitObligationStack({:?})", self.obligation)
|
2014-09-18 11:08:04 -04:00
|
|
|
}
|
|
|
|
}
|
2017-07-10 17:10:30 -04:00
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct WithDepNode<T> {
|
|
|
|
dep_node: DepNodeIndex,
|
|
|
|
cached_value: T
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: Clone> WithDepNode<T> {
|
|
|
|
pub fn new(dep_node: DepNodeIndex, cached_value: T) -> Self {
|
|
|
|
WithDepNode { dep_node, cached_value }
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get(&self, tcx: TyCtxt) -> T {
|
|
|
|
tcx.dep_graph.read_index(self.dep_node);
|
|
|
|
self.cached_value.clone()
|
|
|
|
}
|
|
|
|
}
|