Remove auto_traits from PartitionedBounds
This commit is contained in:
parent
bb35d50cad
commit
9b803ec421
@ -71,7 +71,8 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> {
|
||||
fn item_ty_level(&self, item_def_id: DefId) -> Option<AccessLevel> {
|
||||
let ty_def_id = match self.tcx.item_type(item_def_id).sty {
|
||||
ty::TyAdt(adt, _) => adt.did,
|
||||
ty::TyTrait(ref obj) => obj.principal.def_id(),
|
||||
ty::TyDynamic(ref obj, ..) if obj.principal().is_some() =>
|
||||
obj.principal().unwrap().def_id(),
|
||||
ty::TyProjection(ref proj) => proj.trait_ref.def_id,
|
||||
_ => return Some(AccessLevel::Public)
|
||||
};
|
||||
@ -359,7 +360,7 @@ impl<'b, 'a, 'tcx> TypeVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'b
|
||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
|
||||
let ty_def_id = match ty.sty {
|
||||
ty::TyAdt(adt, _) => Some(adt.did),
|
||||
ty::TyTrait(ref obj) => Some(obj.principal.def_id()),
|
||||
ty::TyDynamic(ref obj, ..) => obj.principal().map(|p| p.def_id()),
|
||||
ty::TyProjection(ref proj) => Some(proj.trait_ref.def_id),
|
||||
ty::TyFnDef(def_id, ..) |
|
||||
ty::TyAnon(def_id, _) => Some(def_id),
|
||||
@ -934,7 +935,7 @@ impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'
|
||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
|
||||
let ty_def_id = match ty.sty {
|
||||
ty::TyAdt(adt, _) => Some(adt.did),
|
||||
ty::TyTrait(ref obj) => Some(obj.principal.def_id()),
|
||||
ty::TyDynamic(ref obj, ..) => obj.principal().map(|p| p.def_id()),
|
||||
ty::TyProjection(ref proj) => {
|
||||
if self.required_visibility == ty::Visibility::PrivateExternal {
|
||||
// Conservatively approximate the whole type alias as public without
|
||||
|
@ -962,7 +962,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
ty.id,
|
||||
path.segments.last().unwrap(),
|
||||
span,
|
||||
partition_bounds(tcx, span, bounds))
|
||||
partition_bounds(bounds))
|
||||
} else {
|
||||
struct_span_err!(tcx.sess, ty.span, E0172,
|
||||
"expected a reference to a trait")
|
||||
@ -1045,11 +1045,12 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
trait_segment,
|
||||
&mut projection_bounds);
|
||||
|
||||
let PartitionedBounds { auto_traits,
|
||||
trait_bounds,
|
||||
let PartitionedBounds { trait_bounds,
|
||||
region_bounds } =
|
||||
partitioned_bounds;
|
||||
|
||||
let (auto_traits, trait_bounds) = split_auto_traits(tcx, trait_bounds);
|
||||
|
||||
if !trait_bounds.is_empty() {
|
||||
let b = &trait_bounds[0];
|
||||
let span = b.trait_ref.path.span;
|
||||
@ -1443,7 +1444,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
path_id,
|
||||
path.segments.last().unwrap(),
|
||||
span,
|
||||
partition_bounds(tcx, span, &[]))
|
||||
partition_bounds(&[]))
|
||||
}
|
||||
Def::Enum(did) | Def::TyAlias(did) | Def::Struct(did) | Def::Union(did) => {
|
||||
assert_eq!(opt_self_ty, None);
|
||||
@ -1897,7 +1898,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
ast_bounds: &[hir::TyParamBound])
|
||||
-> Ty<'tcx>
|
||||
{
|
||||
let mut partitioned_bounds = partition_bounds(self.tcx(), span, &ast_bounds[..]);
|
||||
let mut partitioned_bounds = partition_bounds(ast_bounds);
|
||||
|
||||
let trait_bound = if !partitioned_bounds.trait_bounds.is_empty() {
|
||||
partitioned_bounds.trait_bounds.remove(0)
|
||||
@ -1982,49 +1983,62 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
}
|
||||
|
||||
pub struct PartitionedBounds<'a> {
|
||||
pub auto_traits: Vec<DefId>,
|
||||
pub trait_bounds: Vec<&'a hir::PolyTraitRef>,
|
||||
pub region_bounds: Vec<&'a hir::Lifetime>,
|
||||
}
|
||||
|
||||
/// Divides a list of bounds from the AST into three groups: builtin bounds (Copy, Sized etc),
|
||||
/// general trait bounds, and region bounds.
|
||||
pub fn partition_bounds<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
_span: Span,
|
||||
ast_bounds: &'b [hir::TyParamBound])
|
||||
-> PartitionedBounds<'b>
|
||||
/// Divides a list of general trait bounds into two groups: builtin bounds (Sync/Send) and the
|
||||
/// remaining general trait bounds.
|
||||
fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
trait_bounds: Vec<&'b hir::PolyTraitRef>)
|
||||
-> (Vec<DefId>, Vec<&'b hir::PolyTraitRef>)
|
||||
{
|
||||
let (auto_traits, trait_bounds): (Vec<_>, _) = trait_bounds.into_iter().partition(|bound| {
|
||||
match bound.trait_ref.path.def {
|
||||
Def::Trait(trait_did) => {
|
||||
// Checks whether `trait_did` refers to one of the builtin
|
||||
// traits, like `Send`, and adds it to `auto_traits` if so.
|
||||
if Some(trait_did) == tcx.lang_items.send_trait() ||
|
||||
Some(trait_did) == tcx.lang_items.sync_trait() {
|
||||
let segments = &bound.trait_ref.path.segments;
|
||||
let parameters = &segments[segments.len() - 1].parameters;
|
||||
if !parameters.types().is_empty() {
|
||||
check_type_argument_count(tcx, bound.trait_ref.path.span,
|
||||
parameters.types().len(), &[]);
|
||||
}
|
||||
if !parameters.lifetimes().is_empty() {
|
||||
report_lifetime_number_error(tcx, bound.trait_ref.path.span,
|
||||
parameters.lifetimes().len(), 0);
|
||||
}
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
_ => false
|
||||
}
|
||||
});
|
||||
|
||||
let auto_traits = auto_traits.into_iter().map(|tr| {
|
||||
if let Def::Trait(trait_did) = tr.trait_ref.path.def {
|
||||
trait_did
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}).collect::<Vec<_>>();
|
||||
|
||||
(auto_traits, trait_bounds)
|
||||
}
|
||||
|
||||
/// Divides a list of bounds from the AST into two groups: general trait bounds and region bounds
|
||||
pub fn partition_bounds<'a, 'b, 'gcx, 'tcx>(ast_bounds: &'b [hir::TyParamBound])
|
||||
-> PartitionedBounds<'b>
|
||||
{
|
||||
let mut auto_traits = Vec::new();
|
||||
let mut region_bounds = Vec::new();
|
||||
let mut trait_bounds = Vec::new();
|
||||
for ast_bound in ast_bounds {
|
||||
match *ast_bound {
|
||||
hir::TraitTyParamBound(ref b, hir::TraitBoundModifier::None) => {
|
||||
match b.trait_ref.path.def {
|
||||
Def::Trait(trait_did) => {
|
||||
// Checks whether `trait_did` refers to one of the builtin
|
||||
// traits, like `Send`, and adds it to `auto_traits` if so.
|
||||
if Some(trait_did) == tcx.lang_items.send_trait() ||
|
||||
Some(trait_did) == tcx.lang_items.sync_trait() {
|
||||
auto_traits.push(trait_did);
|
||||
let segments = &b.trait_ref.path.segments;
|
||||
let parameters = &segments[segments.len() - 1].parameters;
|
||||
if !parameters.types().is_empty() {
|
||||
check_type_argument_count(tcx, b.trait_ref.path.span,
|
||||
parameters.types().len(), &[]);
|
||||
}
|
||||
if !parameters.lifetimes().is_empty() {
|
||||
report_lifetime_number_error(tcx, b.trait_ref.path.span,
|
||||
parameters.lifetimes().len(), 0);
|
||||
}
|
||||
continue; // success
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// Not a trait? that's an error, but it'll get
|
||||
// reported later.
|
||||
}
|
||||
}
|
||||
trait_bounds.push(b);
|
||||
}
|
||||
hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {}
|
||||
@ -2035,7 +2049,6 @@ pub fn partition_bounds<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
}
|
||||
|
||||
PartitionedBounds {
|
||||
auto_traits: auto_traits,
|
||||
trait_bounds: trait_bounds,
|
||||
region_bounds: region_bounds,
|
||||
}
|
||||
@ -2110,7 +2123,7 @@ fn report_lifetime_number_error(tcx: TyCtxt, span: Span, number: usize, expected
|
||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||
pub struct Bounds<'tcx> {
|
||||
pub region_bounds: Vec<&'tcx ty::Region>,
|
||||
pub auto_traits: Vec<DefId>,
|
||||
pub implicitly_sized: bool,
|
||||
pub trait_bounds: Vec<ty::PolyTraitRef<'tcx>>,
|
||||
pub projection_bounds: Vec<ty::PolyProjectionPredicate<'tcx>>,
|
||||
}
|
||||
|
@ -1584,11 +1584,10 @@ fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
assert!(prev_predicates.is_none());
|
||||
}
|
||||
|
||||
// Add the Sized bound, unless the type parameter is marked as `?Sized`.
|
||||
fn add_unsized_bound<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
|
||||
bounds: &mut Vec<DefId>,
|
||||
ast_bounds: &[hir::TyParamBound],
|
||||
span: Span)
|
||||
// Is it marked with ?Sized
|
||||
fn is_unsized<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
|
||||
ast_bounds: &[hir::TyParamBound],
|
||||
span: Span) -> bool
|
||||
{
|
||||
let tcx = astconv.tcx();
|
||||
|
||||
@ -1621,11 +1620,13 @@ fn add_unsized_bound<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
|
||||
}
|
||||
}
|
||||
_ if kind_id.is_ok() => {
|
||||
bounds.push(kind_id.unwrap());
|
||||
return false;
|
||||
}
|
||||
// No lang item for Sized, so we can't add it as a bound.
|
||||
None => {}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
/// Returns the early-bound lifetimes declared in this generics
|
||||
@ -1907,14 +1908,9 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
|
||||
{
|
||||
let tcx = astconv.tcx();
|
||||
let PartitionedBounds {
|
||||
mut auto_traits,
|
||||
trait_bounds,
|
||||
region_bounds
|
||||
} = partition_bounds(tcx, span, &ast_bounds);
|
||||
|
||||
if let SizedByDefault::Yes = sized_by_default {
|
||||
add_unsized_bound(astconv, &mut auto_traits, ast_bounds, span);
|
||||
}
|
||||
} = partition_bounds(&ast_bounds);
|
||||
|
||||
let mut projection_bounds = vec![];
|
||||
|
||||
@ -1932,9 +1928,15 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
|
||||
|
||||
trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id()));
|
||||
|
||||
let implicitly_sized = if let SizedByDefault::Yes = sized_by_default {
|
||||
!is_unsized(astconv, ast_bounds, span)
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
Bounds {
|
||||
region_bounds: region_bounds,
|
||||
auto_traits: auto_traits,
|
||||
implicitly_sized: implicitly_sized,
|
||||
trait_bounds: trait_bounds,
|
||||
projection_bounds: projection_bounds,
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern:type annotations required
|
||||
// error-pattern:type annotations or generic parameter binding required
|
||||
fn main() {
|
||||
panic!(
|
||||
std::default::Default::default()
|
||||
|
Loading…
x
Reference in New Issue
Block a user