Skip to content

Commit 9b803ec

Browse files
Remove auto_traits from PartitionedBounds
1 parent bb35d50 commit 9b803ec

File tree

4 files changed

+73
-57
lines changed

4 files changed

+73
-57
lines changed

src/librustc_privacy/lib.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> {
7171
fn item_ty_level(&self, item_def_id: DefId) -> Option<AccessLevel> {
7272
let ty_def_id = match self.tcx.item_type(item_def_id).sty {
7373
ty::TyAdt(adt, _) => adt.did,
74-
ty::TyTrait(ref obj) => obj.principal.def_id(),
74+
ty::TyDynamic(ref obj, ..) if obj.principal().is_some() =>
75+
obj.principal().unwrap().def_id(),
7576
ty::TyProjection(ref proj) => proj.trait_ref.def_id,
7677
_ => return Some(AccessLevel::Public)
7778
};
@@ -359,7 +360,7 @@ impl<'b, 'a, 'tcx> TypeVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'b
359360
fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
360361
let ty_def_id = match ty.sty {
361362
ty::TyAdt(adt, _) => Some(adt.did),
362-
ty::TyTrait(ref obj) => Some(obj.principal.def_id()),
363+
ty::TyDynamic(ref obj, ..) => obj.principal().map(|p| p.def_id()),
363364
ty::TyProjection(ref proj) => Some(proj.trait_ref.def_id),
364365
ty::TyFnDef(def_id, ..) |
365366
ty::TyAnon(def_id, _) => Some(def_id),
@@ -934,7 +935,7 @@ impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'
934935
fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
935936
let ty_def_id = match ty.sty {
936937
ty::TyAdt(adt, _) => Some(adt.did),
937-
ty::TyTrait(ref obj) => Some(obj.principal.def_id()),
938+
ty::TyDynamic(ref obj, ..) => obj.principal().map(|p| p.def_id()),
938939
ty::TyProjection(ref proj) => {
939940
if self.required_visibility == ty::Visibility::PrivateExternal {
940941
// Conservatively approximate the whole type alias as public without

src/librustc_typeck/astconv.rs

+53-40
Original file line numberDiff line numberDiff line change
@@ -962,7 +962,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
962962
ty.id,
963963
path.segments.last().unwrap(),
964964
span,
965-
partition_bounds(tcx, span, bounds))
965+
partition_bounds(bounds))
966966
} else {
967967
struct_span_err!(tcx.sess, ty.span, E0172,
968968
"expected a reference to a trait")
@@ -1045,11 +1045,12 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
10451045
trait_segment,
10461046
&mut projection_bounds);
10471047

1048-
let PartitionedBounds { auto_traits,
1049-
trait_bounds,
1048+
let PartitionedBounds { trait_bounds,
10501049
region_bounds } =
10511050
partitioned_bounds;
10521051

1052+
let (auto_traits, trait_bounds) = split_auto_traits(tcx, trait_bounds);
1053+
10531054
if !trait_bounds.is_empty() {
10541055
let b = &trait_bounds[0];
10551056
let span = b.trait_ref.path.span;
@@ -1443,7 +1444,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
14431444
path_id,
14441445
path.segments.last().unwrap(),
14451446
span,
1446-
partition_bounds(tcx, span, &[]))
1447+
partition_bounds(&[]))
14471448
}
14481449
Def::Enum(did) | Def::TyAlias(did) | Def::Struct(did) | Def::Union(did) => {
14491450
assert_eq!(opt_self_ty, None);
@@ -1897,7 +1898,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
18971898
ast_bounds: &[hir::TyParamBound])
18981899
-> Ty<'tcx>
18991900
{
1900-
let mut partitioned_bounds = partition_bounds(self.tcx(), span, &ast_bounds[..]);
1901+
let mut partitioned_bounds = partition_bounds(ast_bounds);
19011902

19021903
let trait_bound = if !partitioned_bounds.trait_bounds.is_empty() {
19031904
partitioned_bounds.trait_bounds.remove(0)
@@ -1982,49 +1983,62 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
19821983
}
19831984

19841985
pub struct PartitionedBounds<'a> {
1985-
pub auto_traits: Vec<DefId>,
19861986
pub trait_bounds: Vec<&'a hir::PolyTraitRef>,
19871987
pub region_bounds: Vec<&'a hir::Lifetime>,
19881988
}
19891989

1990-
/// Divides a list of bounds from the AST into three groups: builtin bounds (Copy, Sized etc),
1991-
/// general trait bounds, and region bounds.
1992-
pub fn partition_bounds<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
1993-
_span: Span,
1994-
ast_bounds: &'b [hir::TyParamBound])
1995-
-> PartitionedBounds<'b>
1990+
/// Divides a list of general trait bounds into two groups: builtin bounds (Sync/Send) and the
1991+
/// remaining general trait bounds.
1992+
fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
1993+
trait_bounds: Vec<&'b hir::PolyTraitRef>)
1994+
-> (Vec<DefId>, Vec<&'b hir::PolyTraitRef>)
1995+
{
1996+
let (auto_traits, trait_bounds): (Vec<_>, _) = trait_bounds.into_iter().partition(|bound| {
1997+
match bound.trait_ref.path.def {
1998+
Def::Trait(trait_did) => {
1999+
// Checks whether `trait_did` refers to one of the builtin
2000+
// traits, like `Send`, and adds it to `auto_traits` if so.
2001+
if Some(trait_did) == tcx.lang_items.send_trait() ||
2002+
Some(trait_did) == tcx.lang_items.sync_trait() {
2003+
let segments = &bound.trait_ref.path.segments;
2004+
let parameters = &segments[segments.len() - 1].parameters;
2005+
if !parameters.types().is_empty() {
2006+
check_type_argument_count(tcx, bound.trait_ref.path.span,
2007+
parameters.types().len(), &[]);
2008+
}
2009+
if !parameters.lifetimes().is_empty() {
2010+
report_lifetime_number_error(tcx, bound.trait_ref.path.span,
2011+
parameters.lifetimes().len(), 0);
2012+
}
2013+
true
2014+
} else {
2015+
false
2016+
}
2017+
}
2018+
_ => false
2019+
}
2020+
});
2021+
2022+
let auto_traits = auto_traits.into_iter().map(|tr| {
2023+
if let Def::Trait(trait_did) = tr.trait_ref.path.def {
2024+
trait_did
2025+
} else {
2026+
unreachable!()
2027+
}
2028+
}).collect::<Vec<_>>();
2029+
2030+
(auto_traits, trait_bounds)
2031+
}
2032+
2033+
/// Divides a list of bounds from the AST into two groups: general trait bounds and region bounds
2034+
pub fn partition_bounds<'a, 'b, 'gcx, 'tcx>(ast_bounds: &'b [hir::TyParamBound])
2035+
-> PartitionedBounds<'b>
19962036
{
1997-
let mut auto_traits = Vec::new();
19982037
let mut region_bounds = Vec::new();
19992038
let mut trait_bounds = Vec::new();
20002039
for ast_bound in ast_bounds {
20012040
match *ast_bound {
20022041
hir::TraitTyParamBound(ref b, hir::TraitBoundModifier::None) => {
2003-
match b.trait_ref.path.def {
2004-
Def::Trait(trait_did) => {
2005-
// Checks whether `trait_did` refers to one of the builtin
2006-
// traits, like `Send`, and adds it to `auto_traits` if so.
2007-
if Some(trait_did) == tcx.lang_items.send_trait() ||
2008-
Some(trait_did) == tcx.lang_items.sync_trait() {
2009-
auto_traits.push(trait_did);
2010-
let segments = &b.trait_ref.path.segments;
2011-
let parameters = &segments[segments.len() - 1].parameters;
2012-
if !parameters.types().is_empty() {
2013-
check_type_argument_count(tcx, b.trait_ref.path.span,
2014-
parameters.types().len(), &[]);
2015-
}
2016-
if !parameters.lifetimes().is_empty() {
2017-
report_lifetime_number_error(tcx, b.trait_ref.path.span,
2018-
parameters.lifetimes().len(), 0);
2019-
}
2020-
continue; // success
2021-
}
2022-
}
2023-
_ => {
2024-
// Not a trait? that's an error, but it'll get
2025-
// reported later.
2026-
}
2027-
}
20282042
trait_bounds.push(b);
20292043
}
20302044
hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {}
@@ -2035,7 +2049,6 @@ pub fn partition_bounds<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
20352049
}
20362050

20372051
PartitionedBounds {
2038-
auto_traits: auto_traits,
20392052
trait_bounds: trait_bounds,
20402053
region_bounds: region_bounds,
20412054
}
@@ -2110,7 +2123,7 @@ fn report_lifetime_number_error(tcx: TyCtxt, span: Span, number: usize, expected
21102123
#[derive(PartialEq, Eq, Clone, Debug)]
21112124
pub struct Bounds<'tcx> {
21122125
pub region_bounds: Vec<&'tcx ty::Region>,
2113-
pub auto_traits: Vec<DefId>,
2126+
pub implicitly_sized: bool,
21142127
pub trait_bounds: Vec<ty::PolyTraitRef<'tcx>>,
21152128
pub projection_bounds: Vec<ty::PolyProjectionPredicate<'tcx>>,
21162129
}

src/librustc_typeck/collect.rs

+15-13
Original file line numberDiff line numberDiff line change
@@ -1584,11 +1584,10 @@ fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
15841584
assert!(prev_predicates.is_none());
15851585
}
15861586

1587-
// Add the Sized bound, unless the type parameter is marked as `?Sized`.
1588-
fn add_unsized_bound<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
1589-
bounds: &mut Vec<DefId>,
1590-
ast_bounds: &[hir::TyParamBound],
1591-
span: Span)
1587+
// Is it marked with ?Sized
1588+
fn is_unsized<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
1589+
ast_bounds: &[hir::TyParamBound],
1590+
span: Span) -> bool
15921591
{
15931592
let tcx = astconv.tcx();
15941593

@@ -1621,11 +1620,13 @@ fn add_unsized_bound<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
16211620
}
16221621
}
16231622
_ if kind_id.is_ok() => {
1624-
bounds.push(kind_id.unwrap());
1623+
return false;
16251624
}
16261625
// No lang item for Sized, so we can't add it as a bound.
16271626
None => {}
16281627
}
1628+
1629+
true
16291630
}
16301631

16311632
/// Returns the early-bound lifetimes declared in this generics
@@ -1907,14 +1908,9 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
19071908
{
19081909
let tcx = astconv.tcx();
19091910
let PartitionedBounds {
1910-
mut auto_traits,
19111911
trait_bounds,
19121912
region_bounds
1913-
} = partition_bounds(tcx, span, &ast_bounds);
1914-
1915-
if let SizedByDefault::Yes = sized_by_default {
1916-
add_unsized_bound(astconv, &mut auto_traits, ast_bounds, span);
1917-
}
1913+
} = partition_bounds(&ast_bounds);
19181914

19191915
let mut projection_bounds = vec![];
19201916

@@ -1932,9 +1928,15 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
19321928

19331929
trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id()));
19341930

1931+
let implicitly_sized = if let SizedByDefault::Yes = sized_by_default {
1932+
!is_unsized(astconv, ast_bounds, span)
1933+
} else {
1934+
false
1935+
};
1936+
19351937
Bounds {
19361938
region_bounds: region_bounds,
1937-
auto_traits: auto_traits,
1939+
implicitly_sized: implicitly_sized,
19381940
trait_bounds: trait_bounds,
19391941
projection_bounds: projection_bounds,
19401942
}

src/test/compile-fail/issue-16966.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// error-pattern:type annotations required
11+
// error-pattern:type annotations or generic parameter binding required
1212
fn main() {
1313
panic!(
1414
std::default::Default::default()

0 commit comments

Comments
 (0)