Remove BuiltinBound and BuiltinBounds.
This commit is contained in:
parent
607af7218b
commit
64e97d9b33
31 changed files with 137 additions and 332 deletions
|
|
@ -24,6 +24,7 @@ use middle::free_region::FreeRegionMap;
|
|||
use middle::mem_categorization as mc;
|
||||
use middle::mem_categorization::McResult;
|
||||
use middle::region::CodeExtent;
|
||||
use middle::lang_items;
|
||||
use mir::tcx::LvalueTy;
|
||||
use ty::subst::{Kind, Subst, Substs};
|
||||
use ty::adjustment;
|
||||
|
|
@ -1492,11 +1493,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
let copy_def_id = self.tcx.lang_items.require(lang_items::CopyTraitLangItem)
|
||||
.unwrap_or_else(|msg| self.tcx.sess.fatal(&msg[..]));
|
||||
|
||||
// this can get called from typeck (by euv), and moves_by_default
|
||||
// rightly refuses to work with inference variables, but
|
||||
// moves_by_default has a cache, which we want to use in other
|
||||
// cases.
|
||||
!traits::type_known_to_meet_builtin_bound(self, ty, ty::BoundCopy, span)
|
||||
!traits::type_known_to_meet_bound(self, ty, copy_def_id, span)
|
||||
}
|
||||
|
||||
pub fn node_method_ty(&self, method_call: ty::MethodCall)
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@
|
|||
#![feature(const_fn)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![cfg_attr(stage0, feature(dotdot_in_tuple_patterns))]
|
||||
#![feature(enumset)]
|
||||
#![cfg_attr(stage0, feature(item_like_imports))]
|
||||
#![feature(libc)]
|
||||
#![feature(nonzero)]
|
||||
|
|
|
|||
|
|
@ -90,31 +90,6 @@ impl LanguageItems {
|
|||
self.require(OwnedBoxLangItem)
|
||||
}
|
||||
|
||||
pub fn from_builtin_kind(&self, bound: ty::BuiltinBound)
|
||||
-> Result<DefId, String>
|
||||
{
|
||||
match bound {
|
||||
ty::BoundSend => self.require(SendTraitLangItem),
|
||||
ty::BoundSized => self.require(SizedTraitLangItem),
|
||||
ty::BoundCopy => self.require(CopyTraitLangItem),
|
||||
ty::BoundSync => self.require(SyncTraitLangItem),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_builtin_kind(&self, id: DefId) -> Option<ty::BuiltinBound> {
|
||||
if Some(id) == self.send_trait() {
|
||||
Some(ty::BoundSend)
|
||||
} else if Some(id) == self.sized_trait() {
|
||||
Some(ty::BoundSized)
|
||||
} else if Some(id) == self.copy_trait() {
|
||||
Some(ty::BoundCopy)
|
||||
} else if Some(id) == self.sync_trait() {
|
||||
Some(ty::BoundSync)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fn_trait_kind(&self, id: DefId) -> Option<ty::ClosureKind> {
|
||||
let def_id_kinds = [
|
||||
(self.fn_trait(), ty::ClosureKind::Fn),
|
||||
|
|
|
|||
|
|
@ -905,16 +905,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
ObligationCauseCode::StructInitializerSized => {
|
||||
err.note("structs must have a statically known size to be initialized");
|
||||
}
|
||||
ObligationCauseCode::ClosureCapture(var_id, _, builtin_bound) => {
|
||||
let def_id = tcx.lang_items.from_builtin_kind(builtin_bound).unwrap();
|
||||
let trait_name = tcx.item_path_str(def_id);
|
||||
let name = tcx.local_var_name_str(var_id);
|
||||
err.note(
|
||||
&format!("the closure that captures `{}` requires that all captured variables \
|
||||
implement the trait `{}`",
|
||||
name,
|
||||
trait_name));
|
||||
}
|
||||
ObligationCauseCode::FieldSized => {
|
||||
err.note("only the last field of a struct may have a dynamically sized type");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ use rustc_data_structures::obligation_forest::{ForestObligation, ObligationProce
|
|||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
use syntax::ast;
|
||||
use util::common::ErrorReported;
|
||||
use util::nodemap::{FxHashSet, NodeMap};
|
||||
use hir::def_id::DefId;
|
||||
|
||||
use super::CodeAmbiguity;
|
||||
use super::CodeProjectionError;
|
||||
|
|
@ -230,18 +230,21 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
|
|||
normalized.value
|
||||
}
|
||||
|
||||
pub fn register_builtin_bound(&mut self,
|
||||
pub fn register_bound(&mut self,
|
||||
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
builtin_bound: ty::BuiltinBound,
|
||||
def_id: DefId,
|
||||
cause: ObligationCause<'tcx>)
|
||||
{
|
||||
match infcx.tcx.predicate_for_builtin_bound(cause, builtin_bound, 0, ty) {
|
||||
Ok(predicate) => {
|
||||
self.register_predicate_obligation(infcx, predicate);
|
||||
}
|
||||
Err(ErrorReported) => { }
|
||||
}
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: def_id,
|
||||
substs: infcx.tcx.mk_substs_trait(ty, &[]),
|
||||
};
|
||||
self.register_predicate_obligation(infcx, Obligation {
|
||||
cause: cause,
|
||||
recursion_depth: 0,
|
||||
predicate: trait_ref.to_predicate()
|
||||
});
|
||||
}
|
||||
|
||||
pub fn register_region_obligation(&mut self,
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ use hir;
|
|||
use hir::def_id::DefId;
|
||||
use middle::free_region::FreeRegionMap;
|
||||
use ty::subst::Substs;
|
||||
use ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||
use ty::{self, Ty, TyCtxt, TypeFoldable, ToPredicate};
|
||||
use infer::InferCtxt;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
|
@ -125,10 +125,6 @@ pub enum ObligationCauseCode<'tcx> {
|
|||
ReturnType, // Return type must be Sized
|
||||
RepeatVec, // [T,..n] --> T must be Copy
|
||||
|
||||
// Captures of variable the given id by a closure (span is the
|
||||
// span of the closure)
|
||||
ClosureCapture(ast::NodeId, Span, ty::BuiltinBound),
|
||||
|
||||
// Types of fields (other than the last) in a struct must be sized.
|
||||
FieldSized,
|
||||
|
||||
|
|
@ -369,27 +365,30 @@ pub fn predicates_for_generics<'tcx>(cause: ObligationCause<'tcx>,
|
|||
/// `bound` or is not known to meet bound (note that this is
|
||||
/// conservative towards *no impl*, which is the opposite of the
|
||||
/// `evaluate` methods).
|
||||
pub fn type_known_to_meet_builtin_bound<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
||||
pub fn type_known_to_meet_bound<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
bound: ty::BuiltinBound,
|
||||
def_id: DefId,
|
||||
span: Span)
|
||||
-> bool
|
||||
{
|
||||
debug!("type_known_to_meet_builtin_bound(ty={:?}, bound={:?})",
|
||||
debug!("type_known_to_meet_bound(ty={:?}, bound={:?})",
|
||||
ty,
|
||||
bound);
|
||||
infcx.tcx.item_path_str(def_id));
|
||||
|
||||
let cause = ObligationCause::misc(span, ast::DUMMY_NODE_ID);
|
||||
let obligation =
|
||||
infcx.tcx.predicate_for_builtin_bound(cause, bound, 0, ty);
|
||||
let obligation = match obligation {
|
||||
Ok(o) => o,
|
||||
Err(..) => return false
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: def_id,
|
||||
substs: infcx.tcx.mk_substs_trait(ty, &[]),
|
||||
};
|
||||
let obligation = Obligation {
|
||||
cause: ObligationCause::misc(span, ast::DUMMY_NODE_ID),
|
||||
recursion_depth: 0,
|
||||
predicate: trait_ref.to_predicate(),
|
||||
};
|
||||
|
||||
let result = SelectionContext::new(infcx)
|
||||
.evaluate_obligation_conservatively(&obligation);
|
||||
debug!("type_known_to_meet_builtin_bound: ty={:?} bound={:?} => {:?}",
|
||||
ty, bound, result);
|
||||
debug!("type_known_to_meet_ty={:?} bound={} => {:?}",
|
||||
ty, infcx.tcx.item_path_str(def_id), result);
|
||||
|
||||
if result && (ty.has_infer_types() || ty.has_closure_types()) {
|
||||
// Because of inference "guessing", selection can sometimes claim
|
||||
|
|
@ -404,22 +403,22 @@ pub fn type_known_to_meet_builtin_bound<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'g
|
|||
// anyhow).
|
||||
let cause = ObligationCause::misc(span, ast::DUMMY_NODE_ID);
|
||||
|
||||
fulfill_cx.register_builtin_bound(infcx, ty, bound, cause);
|
||||
fulfill_cx.register_bound(infcx, ty, def_id, cause);
|
||||
|
||||
// Note: we only assume something is `Copy` if we can
|
||||
// *definitively* show that it implements `Copy`. Otherwise,
|
||||
// assume it is move; linear is always ok.
|
||||
match fulfill_cx.select_all_or_error(infcx) {
|
||||
Ok(()) => {
|
||||
debug!("type_known_to_meet_builtin_bound: ty={:?} bound={:?} success",
|
||||
debug!("type_known_to_meet_bound: ty={:?} bound={} success",
|
||||
ty,
|
||||
bound);
|
||||
infcx.tcx.item_path_str(def_id));
|
||||
true
|
||||
}
|
||||
Err(e) => {
|
||||
debug!("type_known_to_meet_builtin_bound: ty={:?} bound={:?} errors={:?}",
|
||||
debug!("type_known_to_meet_bound: ty={:?} bound={} errors={:?}",
|
||||
ty,
|
||||
bound,
|
||||
infcx.tcx.item_path_str(def_id),
|
||||
e);
|
||||
false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1093,8 +1093,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
// Other bounds. Consider both in-scope bounds from fn decl
|
||||
// and applicable impls. There is a certain set of precedence rules here.
|
||||
|
||||
match self.tcx().lang_items.to_builtin_kind(obligation.predicate.def_id()) {
|
||||
Some(ty::BoundCopy) => {
|
||||
let def_id = obligation.predicate.def_id();
|
||||
match obligation.predicate.def_id() {
|
||||
_ if self.tcx().lang_items.copy_trait() == Some(def_id) => {
|
||||
debug!("obligation self ty is {:?}",
|
||||
obligation.predicate.0.self_ty());
|
||||
|
||||
|
|
@ -1106,7 +1107,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
let copy_conditions = self.copy_conditions(obligation);
|
||||
self.assemble_builtin_bound_candidates(copy_conditions, &mut candidates)?;
|
||||
}
|
||||
Some(ty::BoundSized) => {
|
||||
_ if self.tcx().lang_items.sized_trait() == Some(def_id) => {
|
||||
// Sized is never implementable by end-users, it is
|
||||
// always automatically computed.
|
||||
let sized_conditions = self.sized_conditions(obligation);
|
||||
|
|
@ -1114,14 +1115,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
&mut candidates)?;
|
||||
}
|
||||
|
||||
None if self.tcx().lang_items.unsize_trait() ==
|
||||
Some(obligation.predicate.def_id()) => {
|
||||
_ if self.tcx().lang_items.unsize_trait() == Some(def_id) => {
|
||||
self.assemble_candidates_for_unsizing(obligation, &mut candidates);
|
||||
}
|
||||
|
||||
Some(ty::BoundSend) |
|
||||
Some(ty::BoundSync) |
|
||||
None => {
|
||||
// For non-builtins and Send/Sync
|
||||
_ => {
|
||||
self.assemble_closure_candidates(obligation, &mut candidates)?;
|
||||
self.assemble_fn_pointer_candidates(obligation, &mut candidates)?;
|
||||
self.assemble_candidates_from_impls(obligation, &mut candidates)?;
|
||||
|
|
@ -2483,7 +2482,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
data_b.auto_traits().collect(),
|
||||
data_a.projection_bounds.clone(),
|
||||
));
|
||||
let origin = TypeOrigin::Misc(obligation.cause.span);
|
||||
let InferOk { obligations, .. } =
|
||||
self.infcx.sub_types(false, &obligation.cause, new_trait, target)
|
||||
.map_err(|_| Unimplemented)?;
|
||||
|
|
|
|||
|
|
@ -190,9 +190,6 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
|
|||
super::VariableType(id) => Some(super::VariableType(id)),
|
||||
super::ReturnType => Some(super::ReturnType),
|
||||
super::RepeatVec => Some(super::RepeatVec),
|
||||
super::ClosureCapture(node_id, span, bound) => {
|
||||
Some(super::ClosureCapture(node_id, span, bound))
|
||||
}
|
||||
super::FieldSized => Some(super::FieldSized),
|
||||
super::ConstSized => Some(super::ConstSized),
|
||||
super::SharedStatic => Some(super::SharedStatic),
|
||||
|
|
@ -507,7 +504,6 @@ impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCauseCode<'tcx> {
|
|||
super::VariableType(_) |
|
||||
super::ReturnType |
|
||||
super::RepeatVec |
|
||||
super::ClosureCapture(..) |
|
||||
super::FieldSized |
|
||||
super::ConstSized |
|
||||
super::SharedStatic |
|
||||
|
|
@ -552,7 +548,6 @@ impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCauseCode<'tcx> {
|
|||
super::VariableType(_) |
|
||||
super::ReturnType |
|
||||
super::RepeatVec |
|
||||
super::ClosureCapture(..) |
|
||||
super::FieldSized |
|
||||
super::ConstSized |
|
||||
super::SharedStatic |
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ use hir::def_id::DefId;
|
|||
use ty::subst::{Subst, Substs};
|
||||
use ty::{self, Ty, TyCtxt, ToPredicate, ToPolyTraitRef};
|
||||
use ty::outlives::Component;
|
||||
use util::common::ErrorReported;
|
||||
use util::nodemap::FxHashSet;
|
||||
|
||||
use super::{Obligation, ObligationCause, PredicateObligation, SelectionContext, Normalized};
|
||||
|
|
@ -408,25 +407,6 @@ pub fn predicate_for_trait_ref<'tcx>(
|
|||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
pub fn trait_ref_for_builtin_bound(self,
|
||||
builtin_bound: ty::BuiltinBound,
|
||||
param_ty: Ty<'tcx>)
|
||||
-> Result<ty::TraitRef<'tcx>, ErrorReported>
|
||||
{
|
||||
match self.lang_items.from_builtin_kind(builtin_bound) {
|
||||
Ok(def_id) => {
|
||||
Ok(ty::TraitRef {
|
||||
def_id: def_id,
|
||||
substs: self.mk_substs_trait(param_ty, &[])
|
||||
})
|
||||
}
|
||||
Err(e) => {
|
||||
self.sess.err(&e);
|
||||
Err(ErrorReported)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn predicate_for_trait_def(self,
|
||||
cause: ObligationCause<'tcx>,
|
||||
trait_def_id: DefId,
|
||||
|
|
@ -442,17 +422,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
predicate_for_trait_ref(cause, trait_ref, recursion_depth)
|
||||
}
|
||||
|
||||
pub fn predicate_for_builtin_bound(self,
|
||||
cause: ObligationCause<'tcx>,
|
||||
builtin_bound: ty::BuiltinBound,
|
||||
recursion_depth: usize,
|
||||
param_ty: Ty<'tcx>)
|
||||
-> Result<PredicateObligation<'tcx>, ErrorReported>
|
||||
{
|
||||
let trait_ref = self.trait_ref_for_builtin_bound(builtin_bound, param_ty)?;
|
||||
Ok(predicate_for_trait_ref(cause, trait_ref, recursion_depth))
|
||||
}
|
||||
|
||||
/// Cast a trait reference into a reference to one of its super
|
||||
/// traits; returns `None` if `target_trait_def_id` is not a
|
||||
/// supertrait.
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ pub enum TypeError<'tcx> {
|
|||
IntMismatch(ExpectedFound<ty::IntVarValue>),
|
||||
FloatMismatch(ExpectedFound<ast::FloatTy>),
|
||||
Traits(ExpectedFound<DefId>),
|
||||
BuiltinBoundsMismatch(ExpectedFound<ty::BuiltinBounds>),
|
||||
VariadicMismatch(ExpectedFound<bool>),
|
||||
CyclicTy,
|
||||
ProjectionNameMismatched(ExpectedFound<Name>),
|
||||
|
|
@ -135,19 +134,6 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
|
|||
format!("trait `{}`",
|
||||
tcx.item_path_str(values.found)))
|
||||
}),
|
||||
BuiltinBoundsMismatch(values) => {
|
||||
if values.expected.is_empty() {
|
||||
write!(f, "expected no bounds, found `{}`",
|
||||
values.found)
|
||||
} else if values.found.is_empty() {
|
||||
write!(f, "expected bounds `{}`, found no bounds",
|
||||
values.expected)
|
||||
} else {
|
||||
write!(f, "expected bounds `{}`, found bounds `{}`",
|
||||
values.expected,
|
||||
values.found)
|
||||
}
|
||||
}
|
||||
IntMismatch(ref values) => {
|
||||
write!(f, "expected `{:?}`, found `{:?}`",
|
||||
values.expected,
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ use hir;
|
|||
use hir::itemlikevisit::ItemLikeVisitor;
|
||||
|
||||
pub use self::sty::{Binder, DebruijnIndex};
|
||||
pub use self::sty::{BuiltinBound, BuiltinBounds};
|
||||
pub use self::sty::{BareFnTy, FnSig, PolyFnSig};
|
||||
pub use self::sty::{ClosureTy, InferTy, ParamTy, ProjectionTy, TraitObject};
|
||||
pub use self::sty::{ClosureSubsts, TypeAndMut};
|
||||
|
|
@ -68,11 +67,6 @@ pub use self::sty::InferTy::*;
|
|||
pub use self::sty::Region::*;
|
||||
pub use self::sty::TypeVariants::*;
|
||||
|
||||
pub use self::sty::BuiltinBound::Send as BoundSend;
|
||||
pub use self::sty::BuiltinBound::Sized as BoundSized;
|
||||
pub use self::sty::BuiltinBound::Copy as BoundCopy;
|
||||
pub use self::sty::BuiltinBound::Sync as BoundSync;
|
||||
|
||||
pub use self::contents::TypeContents;
|
||||
pub use self::context::{TyCtxt, tls};
|
||||
pub use self::context::{CtxtArenas, Lift, Tables};
|
||||
|
|
|
|||
|
|
@ -302,23 +302,6 @@ impl<'tcx> Relate<'tcx> for Vec<ty::PolyExistentialProjection<'tcx>> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Relate<'tcx> for ty::BuiltinBounds {
|
||||
fn relate<'a, 'gcx, R>(relation: &mut R,
|
||||
a: &ty::BuiltinBounds,
|
||||
b: &ty::BuiltinBounds)
|
||||
-> RelateResult<'tcx, ty::BuiltinBounds>
|
||||
where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
|
||||
{
|
||||
// Two sets of builtin bounds are only relatable if they are
|
||||
// precisely the same (but see the coercion code).
|
||||
if a != b {
|
||||
Err(TypeError::BuiltinBoundsMismatch(expected_found(relation, a, b)))
|
||||
} else {
|
||||
Ok(*a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Relate<'tcx> for ty::TraitRef<'tcx> {
|
||||
fn relate<'a, 'gcx, R>(relation: &mut R,
|
||||
a: &ty::TraitRef<'tcx>,
|
||||
|
|
|
|||
|
|
@ -315,7 +315,6 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
|
|||
IntMismatch(x) => IntMismatch(x),
|
||||
FloatMismatch(x) => FloatMismatch(x),
|
||||
Traits(x) => Traits(x),
|
||||
BuiltinBoundsMismatch(x) => BuiltinBoundsMismatch(x),
|
||||
VariadicMismatch(x) => VariadicMismatch(x),
|
||||
CyclicTy => CyclicTy,
|
||||
ProjectionNameMismatched(x) => ProjectionNameMismatched(x),
|
||||
|
|
@ -703,16 +702,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::AutoBorrow<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for ty::BuiltinBounds {
|
||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
|
||||
*self
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for ty::TypeParameterDef<'tcx> {
|
||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
||||
ty::TypeParameterDef {
|
||||
|
|
|
|||
|
|
@ -14,13 +14,10 @@ use hir::def_id::DefId;
|
|||
|
||||
use middle::region;
|
||||
use ty::subst::Substs;
|
||||
use ty::{self, AdtDef, ToPredicate, TypeFlags, Ty, TyCtxt, TypeFoldable};
|
||||
use ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable};
|
||||
use ty::{Slice, TyS};
|
||||
use util::common::ErrorReported;
|
||||
|
||||
use collections::enum_set::{self, EnumSet, CLike};
|
||||
use std::fmt;
|
||||
use std::ops;
|
||||
use syntax::abi;
|
||||
use syntax::ast::{self, Name, NodeId};
|
||||
use syntax::symbol::{keywords, InternedString};
|
||||
|
|
@ -770,71 +767,6 @@ impl<'a, 'tcx, 'gcx> PolyExistentialProjection<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub struct BuiltinBounds(EnumSet<BuiltinBound>);
|
||||
|
||||
impl<'a, 'gcx, 'tcx> BuiltinBounds {
|
||||
pub fn empty() -> BuiltinBounds {
|
||||
BuiltinBounds(EnumSet::new())
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> enum_set::Iter<BuiltinBound> {
|
||||
self.into_iter()
|
||||
}
|
||||
|
||||
pub fn to_predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
self_ty: Ty<'tcx>)
|
||||
-> Vec<ty::Predicate<'tcx>> {
|
||||
self.iter().filter_map(|builtin_bound|
|
||||
match tcx.trait_ref_for_builtin_bound(builtin_bound, self_ty) {
|
||||
Ok(trait_ref) => Some(trait_ref.to_predicate()),
|
||||
Err(ErrorReported) => { None }
|
||||
}
|
||||
).collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Deref for BuiltinBounds {
|
||||
type Target = EnumSet<BuiltinBound>;
|
||||
fn deref(&self) -> &Self::Target { &self.0 }
|
||||
}
|
||||
|
||||
impl ops::DerefMut for BuiltinBounds {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for &'a BuiltinBounds {
|
||||
type Item = BuiltinBound;
|
||||
type IntoIter = enum_set::Iter<BuiltinBound>;
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
(**self).into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, PartialEq, Eq, RustcDecodable, Hash,
|
||||
Debug, Copy)]
|
||||
pub enum BuiltinBound {
|
||||
Send = 0,
|
||||
Sized = 1,
|
||||
Copy = 2,
|
||||
Sync = 3,
|
||||
}
|
||||
|
||||
impl CLike for BuiltinBound {
|
||||
fn to_usize(&self) -> usize {
|
||||
*self as usize
|
||||
}
|
||||
fn from_usize(v: usize) -> BuiltinBound {
|
||||
match v {
|
||||
0 => BuiltinBound::Send,
|
||||
1 => BuiltinBound::Sized,
|
||||
2 => BuiltinBound::Copy,
|
||||
3 => BuiltinBound::Sync,
|
||||
_ => bug!("{} is not a valid BuiltinBound", v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
pub fn try_add_builtin_trait(self,
|
||||
id: DefId,
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ use ty::fold::TypeVisitor;
|
|||
use ty::layout::{Layout, LayoutError};
|
||||
use ty::TypeVariants::*;
|
||||
use util::nodemap::FxHashMap;
|
||||
use middle::lang_items;
|
||||
|
||||
use rustc_const_math::{ConstInt, ConstIsize, ConstUsize};
|
||||
|
||||
|
|
@ -599,7 +600,7 @@ impl<'a, 'gcx, 'tcx, H: Hasher> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tc
|
|||
impl<'a, 'tcx> ty::TyS<'tcx> {
|
||||
fn impls_bound(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
param_env: &ParameterEnvironment<'tcx>,
|
||||
bound: ty::BuiltinBound,
|
||||
def_id: DefId,
|
||||
cache: &RefCell<FxHashMap<Ty<'tcx>, bool>>,
|
||||
span: Span) -> bool
|
||||
{
|
||||
|
|
@ -611,7 +612,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
|
|||
let result =
|
||||
tcx.infer_ctxt(None, Some(param_env.clone()), Reveal::ExactMatch)
|
||||
.enter(|infcx| {
|
||||
traits::type_known_to_meet_builtin_bound(&infcx, self, bound, span)
|
||||
traits::type_known_to_meet_bound(&infcx, self, def_id, span)
|
||||
});
|
||||
if self.has_param_types() || self.has_self_ty() {
|
||||
cache.borrow_mut().insert(self, result);
|
||||
|
|
@ -644,8 +645,10 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
|
|||
TyClosure(..) | TyAdt(..) | TyAnon(..) |
|
||||
TyProjection(..) | TyParam(..) | TyInfer(..) | TyError => None
|
||||
}.unwrap_or_else(|| {
|
||||
!self.impls_bound(tcx, param_env, ty::BoundCopy, ¶m_env.is_copy_cache, span)
|
||||
});
|
||||
!self.impls_bound(tcx, param_env,
|
||||
tcx.lang_items.require(lang_items::CopyTraitLangItem)
|
||||
.unwrap_or_else(|msg| tcx.sess.fatal(&msg[..])),
|
||||
¶m_env.is_copy_cache, span) });
|
||||
|
||||
if !self.has_param_types() && !self.has_self_ty() {
|
||||
self.flags.set(self.flags.get() | if result {
|
||||
|
|
@ -686,8 +689,9 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
|
|||
TyAdt(..) | TyProjection(..) | TyParam(..) |
|
||||
TyInfer(..) | TyAnon(..) | TyError => None
|
||||
}.unwrap_or_else(|| {
|
||||
self.impls_bound(tcx, param_env, ty::BoundSized, ¶m_env.is_sized_cache, span)
|
||||
});
|
||||
self.impls_bound(tcx, param_env, tcx.lang_items.require(lang_items::SizedTraitLangItem)
|
||||
.unwrap_or_else(|msg| tcx.sess.fatal(&msg[..])),
|
||||
¶m_env.is_copy_cache, span) });
|
||||
|
||||
if !self.has_param_types() && !self.has_self_ty() {
|
||||
self.flags.set(self.flags.get() | if result {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable};
|
|||
use std::iter::once;
|
||||
use syntax::ast;
|
||||
use syntax_pos::Span;
|
||||
use util::common::ErrorReported;
|
||||
use middle::lang_items;
|
||||
|
||||
/// Returns the set of obligations needed to make `ty` well-formed.
|
||||
/// If `ty` contains unresolved inference variables, this may include
|
||||
|
|
@ -282,14 +282,12 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
|
|||
fn require_sized(&mut self, subty: Ty<'tcx>, cause: traits::ObligationCauseCode<'tcx>) {
|
||||
if !subty.has_escaping_regions() {
|
||||
let cause = self.cause(cause);
|
||||
match self.infcx.tcx.trait_ref_for_builtin_bound(ty::BoundSized, subty) {
|
||||
Ok(trait_ref) => {
|
||||
self.out.push(
|
||||
traits::Obligation::new(cause,
|
||||
trait_ref.to_predicate()));
|
||||
}
|
||||
Err(ErrorReported) => { }
|
||||
}
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: self.infcx.tcx.lang_items.require(lang_items::SizedTraitLangItem)
|
||||
.unwrap_or_else(|msg| self.infcx.tcx.sess.fatal(&msg[..])),
|
||||
substs: self.infcx.tcx.mk_substs_trait(subty, &[]),
|
||||
};
|
||||
self.out.push(traits::Obligation::new(cause, trait_ref.to_predicate()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -683,19 +683,6 @@ impl<'tcx> fmt::Display for ty::FnSig<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ty::BuiltinBounds {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let mut bounds = self.iter();
|
||||
if let Some(bound) = bounds.next() {
|
||||
write!(f, "{:?}", bound)?;
|
||||
for bound in bounds {
|
||||
write!(f, " + {:?}", bound)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ty::TyVid {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "_#{}t", self.index)
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ use rustc::mir::traversal::ReversePostorder;
|
|||
use rustc::mir::transform::{Pass, MirPass, MirSource};
|
||||
use rustc::mir::visit::{LvalueContext, Visitor};
|
||||
use rustc::util::nodemap::DefIdMap;
|
||||
use rustc::middle::lang_items;
|
||||
use syntax::abi::Abi;
|
||||
use syntax::feature_gate::UnstableFeatures;
|
||||
use syntax_pos::Span;
|
||||
|
|
@ -1046,7 +1047,11 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants {
|
|||
tcx.infer_ctxt(None, None, Reveal::NotSpecializable).enter(|infcx| {
|
||||
let cause = traits::ObligationCause::new(mir.span, id, traits::SharedStatic);
|
||||
let mut fulfillment_cx = traits::FulfillmentContext::new();
|
||||
fulfillment_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause);
|
||||
fulfillment_cx.register_bound(&infcx, ty,
|
||||
tcx.lang_items
|
||||
.require(lang_items::SyncTraitLangItem)
|
||||
.unwrap_or_else(|msg| tcx.sess.fatal(&msg[..])),
|
||||
cause);
|
||||
if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) {
|
||||
infcx.report_fulfillment_errors(&err);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ use rustc::hir;
|
|||
use rustc::traits;
|
||||
use rustc::ty::{self, Ty, TypeFoldable};
|
||||
use rustc::ty::cast::{CastKind, CastTy};
|
||||
use rustc::middle::lang_items;
|
||||
use syntax::ast;
|
||||
use syntax_pos::Span;
|
||||
use util::common::ErrorReported;
|
||||
|
|
@ -543,6 +544,8 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
|
|||
|
||||
impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
fn type_is_known_to_be_sized(&self, ty: Ty<'tcx>, span: Span) -> bool {
|
||||
traits::type_known_to_meet_builtin_bound(self, ty, ty::BoundSized, span)
|
||||
let lang_item = self.tcx.lang_items.require(lang_items::SizedTraitLangItem)
|
||||
.unwrap_or_else(|msg| self.tcx.sess.fatal(&msg[..]));
|
||||
traits::type_known_to_meet_bound(self, ty, lang_item, span)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,7 +119,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
self.deduce_sig_from_projection(&pb)
|
||||
})
|
||||
.next();
|
||||
let kind = self.tcx.lang_items.fn_trait_kind(object_type.principal().unwrap().def_id());
|
||||
let kind =
|
||||
self.tcx.lang_items.fn_trait_kind(object_type.principal().unwrap().def_id());
|
||||
(sig, kind)
|
||||
}
|
||||
ty::TyInfer(ty::TyVar(vid)) => self.deduce_expectations_from_obligations(vid),
|
||||
|
|
|
|||
|
|
@ -379,7 +379,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
match ty.sty {
|
||||
ty::TyAdt(def, _) => def.did.is_local(),
|
||||
|
||||
ty::TyTrait(ref tr) => tr.principal().map(|p| p.def_id().is_local()).unwrap_or(false),
|
||||
ty::TyTrait(ref tr) => tr.principal().map(|p|
|
||||
p.def_id().is_local()).unwrap_or(false),
|
||||
|
||||
ty::TyParam(_) => true,
|
||||
|
||||
|
|
|
|||
|
|
@ -123,6 +123,7 @@ use rustc::hir::intravisit::{self, Visitor};
|
|||
use rustc::hir::itemlikevisit::ItemLikeVisitor;
|
||||
use rustc::hir::{self, PatKind};
|
||||
use rustc::hir::print as pprust;
|
||||
use rustc::middle::lang_items;
|
||||
use rustc_back::slice;
|
||||
use rustc_const_eval::eval_length;
|
||||
|
||||
|
|
@ -1805,11 +1806,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
ty: Ty<'tcx>,
|
||||
span: Span,
|
||||
code: traits::ObligationCauseCode<'tcx>,
|
||||
bound: ty::BuiltinBound)
|
||||
def_id: DefId)
|
||||
{
|
||||
self.register_builtin_bound(
|
||||
self.register_bound(
|
||||
ty,
|
||||
bound,
|
||||
def_id,
|
||||
traits::ObligationCause::new(span, self.body_id, code));
|
||||
}
|
||||
|
||||
|
|
@ -1818,16 +1819,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
span: Span,
|
||||
code: traits::ObligationCauseCode<'tcx>)
|
||||
{
|
||||
self.require_type_meets(ty, span, code, ty::BoundSized);
|
||||
let lang_item = self.tcx.lang_items.require(lang_items::SizedTraitLangItem)
|
||||
.unwrap_or_else(|msg| self.tcx.sess.fatal(&msg[..]));
|
||||
self.require_type_meets(ty, span, code, lang_item);
|
||||
}
|
||||
|
||||
pub fn register_builtin_bound(&self,
|
||||
pub fn register_bound(&self,
|
||||
ty: Ty<'tcx>,
|
||||
builtin_bound: ty::BuiltinBound,
|
||||
def_id: DefId,
|
||||
cause: traits::ObligationCause<'tcx>)
|
||||
{
|
||||
self.fulfillment_cx.borrow_mut()
|
||||
.register_builtin_bound(self, ty, builtin_bound, cause);
|
||||
.register_bound(self, ty, def_id, cause);
|
||||
}
|
||||
|
||||
pub fn register_predicate(&self,
|
||||
|
|
@ -3899,7 +3902,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
if count > 1 {
|
||||
// For [foo, ..n] where n > 1, `foo` must have
|
||||
// Copy type:
|
||||
self.require_type_meets(t, expr.span, traits::RepeatVec, ty::BoundCopy);
|
||||
let lang_item = self.tcx.lang_items.require(lang_items::CopyTraitLangItem)
|
||||
.unwrap_or_else(|msg| self.tcx.sess.fatal(&msg[..]));
|
||||
self.require_type_meets(t, expr.span, traits::RepeatVec, lang_item);
|
||||
}
|
||||
|
||||
if element_ty.references_error() {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ use middle::region::{CodeExtent};
|
|||
use rustc::traits::{self, ObligationCauseCode};
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::util::nodemap::{FxHashSet, FxHashMap};
|
||||
use rustc::middle::lang_items;
|
||||
|
||||
use syntax::ast;
|
||||
use syntax_pos::Span;
|
||||
|
|
@ -118,12 +119,13 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
|
|||
|
||||
let trait_ref = ccx.tcx.impl_trait_ref(ccx.tcx.map.local_def_id(item.id)).unwrap();
|
||||
ccx.tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id);
|
||||
match ccx.tcx.lang_items.to_builtin_kind(trait_ref.def_id) {
|
||||
Some(ty::BoundSend) | Some(ty::BoundSync) => {}
|
||||
Some(_) | None => {
|
||||
if !ccx.tcx.trait_has_default_impl(trait_ref.def_id) {
|
||||
error_192(ccx, item.span);
|
||||
}
|
||||
let sync_trait = ccx.tcx.lang_items.require(lang_items::SyncTraitLangItem)
|
||||
.unwrap_or_else(|msg| ccx.tcx.sess.fatal(&msg[..]));
|
||||
let send_trait = ccx.tcx.lang_items.require(lang_items::SendTraitLangItem)
|
||||
.unwrap_or_else(|msg| ccx.tcx.sess.fatal(&msg[..]));
|
||||
if trait_ref.def_id != sync_trait && trait_ref.def_id != send_trait {
|
||||
if !ccx.tcx.trait_has_default_impl(trait_ref.def_id) {
|
||||
error_192(ccx, item.span);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -241,9 +243,10 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
|
|||
// For DST, all intermediate types must be sized.
|
||||
let unsized_len = if all_sized || variant.fields.is_empty() { 0 } else { 1 };
|
||||
for field in &variant.fields[..variant.fields.len() - unsized_len] {
|
||||
fcx.register_builtin_bound(
|
||||
fcx.register_bound(
|
||||
field.ty,
|
||||
ty::BoundSized,
|
||||
fcx.tcx.lang_items.require(lang_items::SizedTraitLangItem)
|
||||
.unwrap_or_else(|msg| fcx.tcx.sess.fatal(&msg[..])),
|
||||
traits::ObligationCause::new(field.span,
|
||||
fcx.body_id,
|
||||
traits::FieldSized));
|
||||
|
|
|
|||
|
|
@ -182,14 +182,16 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OverlapChecker<'cx, 'tcx> {
|
|||
// This is something like impl Trait1 for Trait2. Illegal
|
||||
// if Trait1 is a supertrait of Trait2 or Trait2 is not object safe.
|
||||
|
||||
if data.principal().is_none() || !self.tcx.is_object_safe(data.principal().unwrap().def_id()) {
|
||||
if data.principal().is_none() ||
|
||||
!self.tcx.is_object_safe(data.principal().unwrap().def_id()) {
|
||||
// This is an error, but it will be
|
||||
// reported by wfcheck. Ignore it
|
||||
// here. This is tested by
|
||||
// `coherence-impl-trait-for-trait-object-safe.rs`.
|
||||
} else {
|
||||
let mut supertrait_def_ids =
|
||||
traits::supertrait_def_ids(self.tcx, data.principal().unwrap().def_id());
|
||||
traits::supertrait_def_ids(self.tcx,
|
||||
data.principal().unwrap().def_id());
|
||||
if supertrait_def_ids.any(|d| d == trait_def_id) {
|
||||
span_err!(self.tcx.sess,
|
||||
item.span,
|
||||
|
|
|
|||
|
|
@ -376,7 +376,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
let contra = self.contravariant(variance);
|
||||
self.add_constraints_from_region(generics, data.region_bound, contra);
|
||||
|
||||
let poly_trait_ref = data.principal().unwrap().with_self_ty(self.tcx(), self.tcx().types.err);
|
||||
let poly_trait_ref = data.principal().unwrap().with_self_ty(self.tcx(),
|
||||
self.tcx().types.err);
|
||||
self.add_constraints_from_trait_ref(generics, poly_trait_ref.0, variance);
|
||||
|
||||
for projection in &data.projection_bounds {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ use syntax_pos::{self, DUMMY_SP, Pos};
|
|||
use rustc_trans::back::link;
|
||||
use rustc::middle::privacy::AccessLevels;
|
||||
use rustc::middle::resolve_lifetime::DefRegion::*;
|
||||
use rustc::middle::lang_items;
|
||||
use rustc::hir::def::{Def, CtorKind};
|
||||
use rustc::hir::def_id::{self, DefId, DefIndex, CRATE_DEF_INDEX};
|
||||
use rustc::hir::print as pprust;
|
||||
|
|
@ -593,12 +594,21 @@ pub enum TyParamBound {
|
|||
|
||||
impl TyParamBound {
|
||||
fn maybe_sized(cx: &DocContext) -> TyParamBound {
|
||||
use rustc::hir::TraitBoundModifier as TBM;
|
||||
let mut sized_bound = ty::BoundSized.clean(cx);
|
||||
if let TyParamBound::TraitBound(_, ref mut tbm) = sized_bound {
|
||||
*tbm = TBM::Maybe
|
||||
};
|
||||
sized_bound
|
||||
let did = cx.tcx().lang_items.require(lang_items::SizedTraitLangItem)
|
||||
.unwrap_or_else(|msg| cx.tcx().sess.fatal(&msg[..]));
|
||||
let empty = cx.tcx().intern_substs(&[]);
|
||||
let path = external_path(cx, &cx.tcx().item_name(did).as_str(),
|
||||
Some(did), false, vec![], empty);
|
||||
inline::record_extern_fqn(cx, did, TypeKind::Trait);
|
||||
TraitBound(PolyTrait {
|
||||
trait_: ResolvedPath {
|
||||
path: path,
|
||||
typarams: None,
|
||||
did: did,
|
||||
is_generic: false,
|
||||
},
|
||||
lifetimes: vec![]
|
||||
}, hir::TraitBoundModifier::Maybe)
|
||||
}
|
||||
|
||||
fn is_sized_bound(&self, cx: &DocContext) -> bool {
|
||||
|
|
@ -675,37 +685,6 @@ fn external_path(cx: &DocContext, name: &str, trait_did: Option<DefId>, has_self
|
|||
}
|
||||
}
|
||||
|
||||
impl Clean<TyParamBound> for ty::BuiltinBound {
|
||||
fn clean(&self, cx: &DocContext) -> TyParamBound {
|
||||
let tcx = cx.tcx;
|
||||
let empty = tcx.intern_substs(&[]);
|
||||
let (did, path) = match *self {
|
||||
ty::BoundSend =>
|
||||
(tcx.lang_items.send_trait().unwrap(),
|
||||
external_path(cx, "Send", None, false, vec![], empty)),
|
||||
ty::BoundSized =>
|
||||
(tcx.lang_items.sized_trait().unwrap(),
|
||||
external_path(cx, "Sized", None, false, vec![], empty)),
|
||||
ty::BoundCopy =>
|
||||
(tcx.lang_items.copy_trait().unwrap(),
|
||||
external_path(cx, "Copy", None, false, vec![], empty)),
|
||||
ty::BoundSync =>
|
||||
(tcx.lang_items.sync_trait().unwrap(),
|
||||
external_path(cx, "Sync", None, false, vec![], empty)),
|
||||
};
|
||||
inline::record_extern_fqn(cx, did, TypeKind::Trait);
|
||||
TraitBound(PolyTrait {
|
||||
trait_: ResolvedPath {
|
||||
path: path,
|
||||
typarams: None,
|
||||
did: did,
|
||||
is_generic: false,
|
||||
},
|
||||
lifetimes: vec![]
|
||||
}, hir::TraitBoundModifier::None)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> {
|
||||
fn clean(&self, cx: &DocContext) -> TyParamBound {
|
||||
inline::record_extern_fqn(cx, self.def_id, TypeKind::Trait);
|
||||
|
|
@ -1915,8 +1894,8 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
|
|||
});
|
||||
}
|
||||
|
||||
let path = external_path(cx, &cx.tcx.item_name(did).as_str(),
|
||||
Some(did), false, bindings, obj.principal.0.substs);
|
||||
let path = external_path(cx, &cx.tcx().item_name(did).as_str(), Some(did),
|
||||
false, bindings, principal.0.substs);
|
||||
ResolvedPath {
|
||||
path: path,
|
||||
typarams: Some(typarams),
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ trait Trait {}
|
|||
|
||||
pub fn main() {
|
||||
let x: Vec<Trait + Sized> = Vec::new();
|
||||
//~^ ERROR `Trait + Sized: std::marker::Sized` is not satisfied
|
||||
//~^ ERROR the trait bound `Trait + std::marker::Sized: std::marker::Sized` is not satisfied
|
||||
//~| ERROR the trait `std::marker::Sized` cannot be made into an object
|
||||
//~| ERROR `Trait + Sized: std::marker::Sized` is not satisfied
|
||||
//~| ERROR the trait bound `Trait + std::marker::Sized: std::marker::Sized` is not satisfied
|
||||
//~| ERROR the trait `std::marker::Sized` cannot be made into an object
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@
|
|||
use std::fmt::Debug;
|
||||
|
||||
const CONST_0: Debug+Sync = *(&0 as &(Debug+Sync));
|
||||
//~^ ERROR `std::fmt::Debug + Sync + 'static: std::marker::Sized` is not satisfied
|
||||
//~| NOTE the trait `std::marker::Sized` is not implemented for `std::fmt::Debug + Sync + 'static`
|
||||
//~^ ERROR `std::fmt::Debug + std::marker::Sync + 'static: std::marker::Sized` is not satisfied
|
||||
//~| NOTE the trait `std::marker::Sized` is not implemented for `std::fmt::Debug + std::marker::Syn
|
||||
//~| NOTE does not have a constant size known at compile-time
|
||||
//~| NOTE constant expressions must have a statically known size
|
||||
|
||||
|
|
@ -23,8 +23,8 @@ const CONST_FOO: str = *"foo";
|
|||
//~| NOTE constant expressions must have a statically known size
|
||||
|
||||
static STATIC_1: Debug+Sync = *(&1 as &(Debug+Sync));
|
||||
//~^ ERROR `std::fmt::Debug + Sync + 'static: std::marker::Sized` is not satisfied
|
||||
//~| NOTE the trait `std::marker::Sized` is not implemented for `std::fmt::Debug + Sync + 'static`
|
||||
//~^ ERROR `std::fmt::Debug + std::marker::Sync + 'static: std::marker::Sized` is not satisfied
|
||||
//~| NOTE the trait `std::marker::Sized` is not implemented for `std::fmt::Debug + std::marker::Syn
|
||||
//~| NOTE does not have a constant size known at compile-time
|
||||
//~| NOTE constant expressions must have a statically known size
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,6 @@ fn size_of_copy<T: Copy+?Sized>() -> usize { mem::size_of::<T>() }
|
|||
|
||||
fn main() {
|
||||
size_of_copy::<Misc+Copy>();
|
||||
//~^ ERROR `Misc + Copy: std::marker::Copy` is not satisfied
|
||||
//~^ ERROR the trait bound `Misc + std::marker::Copy: std::marker::Copy` is not satisfied
|
||||
//~| ERROR the trait `std::marker::Copy` cannot be made into an object
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,10 +21,10 @@ fn c(x: Box<Foo+Sync+Send>) {
|
|||
}
|
||||
|
||||
fn d(x: Box<Foo>) {
|
||||
a(x); //~ ERROR mismatched types
|
||||
//~| expected type `Box<Foo + Send + 'static>`
|
||||
//~| found type `Box<Foo + 'static>`
|
||||
//~| expected bounds `Send`, found no bounds
|
||||
a(x); //~ ERROR mismatched types [E0308]
|
||||
//~| NOTE expected type `Box<Foo + std::marker::Send + 'static>`
|
||||
//~| NOTE found type `Box<Foo + 'static>`
|
||||
//~| NOTE expected trait Foo, found a different trait Foo
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ trait Foo {
|
|||
// This should emit the less confusing error, not the more confusing one.
|
||||
|
||||
fn foo(_x: Foo + Send) {
|
||||
//~^ ERROR `Foo + Send + 'static: std::marker::Sized` is not satisfied
|
||||
//~^ ERROR the trait bound `Foo + std::marker::Send + 'static: std::marker::Sized` is not
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue