use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable};
use crate::hir;
-use rustc_data_structures::bit_set::GrowableBitSet;
+use rustc_index::bit_set::GrowableBitSet;
use rustc_data_structures::sync::Lock;
use rustc_target::spec::abi::Abi;
+use syntax::attr;
+use syntax::symbol::sym;
use std::cell::{Cell, RefCell};
use std::cmp;
use std::fmt::{self, Display};
trait_desc: String,
self_desc: Option<String>,
},
+ ReservationImpl {
+ message: String
+ },
}
impl IntercrateAmbiguityCause {
trait_desc, self_desc
)
}
+ &IntercrateAmbiguityCause::ReservationImpl {
+ ref message
+ } => {
+ message.clone()
+ }
}
}
}
/// 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.
+/// "type annotations needed" error.
///
/// However, with type parameters, this can be a real problem - type
/// parameters don't unify with regular types, but they *can* unify
// Treat negative impls as unimplemented, and reservation impls as ambiguity.
fn filter_negative_and_reservation_impls(
- &self,
+ &mut self,
candidate: SelectionCandidate<'tcx>,
) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
if let ImplCandidate(def_id) = candidate {
- match self.tcx().impl_polarity(def_id) {
+ let tcx = self.tcx();
+ match tcx.impl_polarity(def_id) {
ty::ImplPolarity::Negative if !self.allow_negative_impls => {
return Err(Unimplemented);
}
ty::ImplPolarity::Reservation => {
+ if let Some(intercrate_ambiguity_clauses)
+ = &mut self.intercrate_ambiguity_causes
+ {
+ let attrs = tcx.get_attrs(def_id);
+ let attr = attr::find_by_name(&attrs, sym::rustc_reservation_impl);
+ let value = attr.and_then(|a| a.value_str());
+ if let Some(value) = value {
+ debug!("filter_negative_and_reservation_impls: \
+ reservation impl ambiguity on {:?}", def_id);
+ intercrate_ambiguity_clauses.push(
+ IntercrateAmbiguityCause::ReservationImpl {
+ message: value.to_string()
+ }
+ );
+ }
+ }
return Ok(None);
}
_ => {}
// before we go into the whole placeholder thing, just
// quickly check if the self-type is a projection at all.
- match obligation.predicate.skip_binder().trait_ref.self_ty().sty {
+ match obligation.predicate.skip_binder().trait_ref.self_ty().kind {
ty::Projection(_) | ty::Opaque(..) => {}
ty::Infer(ty::TyVar(_)) => {
span_bug!(
placeholder_trait_predicate,
);
- let (def_id, substs) = match placeholder_trait_predicate.trait_ref.self_ty().sty {
+ let (def_id, substs) = match placeholder_trait_predicate.trait_ref.self_ty().kind {
ty::Projection(ref data) => (data.trait_ref(self.tcx()).def_id, data.substs),
ty::Opaque(def_id, substs) => (def_id, substs),
_ => {
// touch bound regions, they just capture the in-scope
// type/region parameters.
let self_ty = *obligation.self_ty().skip_binder();
- match self_ty.sty {
+ match self_ty.kind {
ty::Generator(..) => {
debug!(
"assemble_generator_candidates: self_ty={:?} obligation={:?}",
// Okay to skip binder because the substs on closure types never
// touch bound regions, they just capture the in-scope
// type/region parameters
- match obligation.self_ty().skip_binder().sty {
+ match obligation.self_ty().skip_binder().kind {
ty::Closure(closure_def_id, closure_substs) => {
debug!(
"assemble_unboxed_candidates: kind={:?} obligation={:?}",
kind, obligation
);
- match self.infcx.closure_kind(closure_def_id, closure_substs) {
+ match self.infcx.closure_kind(
+ closure_def_id,
+ closure_substs
+ ) {
Some(closure_kind) => {
debug!(
"assemble_unboxed_candidates: closure_kind = {:?}",
// Okay to skip binder because what we are inspecting doesn't involve bound regions
let self_ty = *obligation.self_ty().skip_binder();
- match self_ty.sty {
+ match self_ty.kind {
ty::Infer(ty::TyVar(_)) => {
debug!("assemble_fn_pointer_candidates: ambiguous self-type");
candidates.ambiguous = true; // could wind up being a fn() type
let def_id = obligation.predicate.def_id();
if self.tcx().trait_is_auto(def_id) {
- match self_ty.sty {
+ match self_ty.kind {
ty::Dynamic(..) => {
// For object types, we don't know what the closed
// over types are. This means we conservatively
// self-ty here doesn't escape this probe, so just erase
// any LBR.
let self_ty = self.tcx().erase_late_bound_regions(&obligation.self_ty());
- let poly_trait_ref = match self_ty.sty {
+ let poly_trait_ref = match self_ty.kind {
ty::Dynamic(ref data, ..) => {
if data.auto_traits()
.any(|did| did == obligation.predicate.def_id())
source, target
);
- let may_apply = match (&source.sty, &target.sty) {
+ let may_apply = match (&source.kind, &target.kind) {
// Trait+Kx+'a -> Trait+Ky+'b (upcasts).
(&ty::Dynamic(ref data_a, ..), &ty::Dynamic(ref data_b, ..)) => {
// Upcasts permit two things:
if other.evaluation.must_apply_modulo_regions() {
match victim.candidate {
ImplCandidate(victim_def) => {
- let tcx = self.tcx().global_tcx();
+ let tcx = self.tcx();
return tcx.specializes((other_def, victim_def))
|| tcx.impls_are_allowed_to_overlap(
other_def, victim_def).is_some();
let self_ty = self.infcx
.shallow_resolve(obligation.predicate.skip_binder().self_ty());
- match self_ty.sty {
+ match self_ty.kind {
ty::Infer(ty::IntVar(_))
| ty::Infer(ty::FloatVar(_))
| ty::Uint(_)
use self::BuiltinImplConditions::{Ambiguous, None, Where};
- match self_ty.sty {
+ match self_ty.kind {
ty::Infer(ty::IntVar(_))
| ty::Infer(ty::FloatVar(_))
| ty::FnDef(..)
ty::Closure(def_id, substs) => {
// (*) binder moved here
Where(ty::Binder::bind(
- substs.upvar_tys(def_id, self.tcx()).collect(),
+ substs.as_closure().upvar_tys(def_id, self.tcx()).collect(),
))
}
/// Zed<i32> where enum Zed { A(T), B(u32) } -> [i32, u32]
/// ```
fn constituent_types_for_ty(&self, t: Ty<'tcx>) -> Vec<Ty<'tcx>> {
- match t.sty {
+ match t.kind {
ty::Uint(_)
| ty::Int(_)
| ty::Bool
tys.iter().map(|k| k.expect_ty()).collect()
}
- ty::Closure(def_id, ref substs) => substs.upvar_tys(def_id, self.tcx()).collect(),
+ ty::Closure(def_id, ref substs) => substs.as_closure()
+ .upvar_tys(def_id, self.tcx())
+ .collect(),
ty::Generator(def_id, ref substs, _) => {
let witness = substs.witness(def_id, self.tcx());
// results.
let self_ty = self.infcx
.shallow_resolve(*obligation.self_ty().skip_binder());
- let poly_trait_ref = match self_ty.sty {
+ let poly_trait_ref = match self_ty.kind {
ty::Dynamic(ref data, ..) =>
data.principal().unwrap_or_else(|| {
span_bug!(obligation.cause.span, "object candidate with no principal")
// 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 (generator_def_id, substs) = match self_ty.sty {
+ let (generator_def_id, substs) = match self_ty.kind {
ty::Generator(id, substs, _) => (id, substs),
_ => bug!("closure candidate for non-closure {:?}", obligation),
};
// 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 {
+ let (closure_def_id, substs) = match self_ty.kind {
ty::Closure(id, substs) => (id, substs),
_ => bug!("closure candidate for non-closure {:?}", obligation),
};
)?);
// FIXME: chalk
+
if !self.tcx().sess.opts.debugging_opts.chalk {
obligations.push(Obligation::new(
obligation.cause.clone(),
obligation.param_env,
- ty::Predicate::ClosureKind(closure_def_id, substs, kind),
+ ty::Predicate::ClosureKind(
+ closure_def_id,
+ substs,
+ kind
+ ),
));
}
Ok(VtableClosureData {
closure_def_id,
- substs: substs.clone(),
+ substs: substs,
nested: obligations,
})
}
);
let mut nested = vec![];
- match (&source.sty, &target.sty) {
+ match (&source.kind, &target.kind) {
// Trait+Kx+'a -> Trait+Ky+'b (upcasts).
(&ty::Dynamic(ref data_a, r_a), &ty::Dynamic(ref data_b, r_b)) => {
// See assemble_candidates_for_unsizing for more info.
let mut ty_params = GrowableBitSet::new_empty();
let mut found = false;
for ty in field.walk() {
- if let ty::Param(p) = ty.sty {
+ if let ty::Param(p) = ty.kind {
ty_params.insert(p.index as usize);
found = true;
}
&mut self,
obligation: &TraitObligation<'tcx>,
closure_def_id: DefId,
- substs: ty::ClosureSubsts<'tcx>,
+ substs: SubstsRef<'tcx>,
) -> ty::PolyTraitRef<'tcx> {
debug!(
"closure_trait_ref_unnormalized(obligation={:?}, closure_def_id={:?}, substs={:?})",