Skip to content

Commit 0e912b2

Browse files
authored
Rollup merge of rust-lang#55687 - alexreg:fix-24010, r=scalexm
Take supertraits into account when calculating associated types Fixes rust-lang#24010 and rust-lang#23856. Applies to trait aliases too. As a by-product, this PR also makes repeated bindings of the same associated item in the same definition a hard error. This was previously a warning with a note about it becoming a hard error in the future. See rust-lang#50589 for more info. I talked about this with @nikomatsakis recently, but only very superficially, so this shouldn't stop anyone from assigning it to themself to review and r+. N.B. The "WIP" commits represent imperfect attempts to solve the problem just for trait objects, but I've left them in for reference for the sake of whomever is reviewing this. CC @carllerche @theemathas @durka @mbrubeck
2 parents 6e9b842 + 90a1438 commit 0e912b2

28 files changed

+302
-199
lines changed

src/librustc/diagnostics.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2134,7 +2134,7 @@ static X: u32 = 42;
21342134

21352135

21362136
register_diagnostics! {
2137-
// E0006 // merged with E0005
2137+
// E0006, // merged with E0005
21382138
// E0101, // replaced with E0282
21392139
// E0102, // replaced with E0282
21402140
// E0134,
@@ -2183,9 +2183,7 @@ register_diagnostics! {
21832183
E0657, // `impl Trait` can only capture lifetimes bound at the fn level
21842184
E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax
21852185
E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders
2186-
21872186
E0697, // closures cannot be static
2188-
21892187
E0707, // multiple elided lifetimes used in arguments of `async fn`
21902188
E0708, // `async` non-`move` closures with arguments are not currently supported
21912189
E0709, // multiple different lifetimes used in arguments of `async fn`

src/librustc/hir/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -506,9 +506,9 @@ pub enum TraitBoundModifier {
506506
}
507507

508508
/// The AST represents all type param bounds as types.
509-
/// typeck::collect::compute_bounds matches these against
510-
/// the "special" built-in traits (see middle::lang_items) and
511-
/// detects Copy, Send and Sync.
509+
/// `typeck::collect::compute_bounds` matches these against
510+
/// the "special" built-in traits (see `middle::lang_items`) and
511+
/// detects `Copy`, `Send` and `Sync`.
512512
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
513513
pub enum GenericBound {
514514
Trait(PolyTraitRef, TraitBoundModifier),

src/librustc/lint/builtin.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -300,12 +300,6 @@ declare_lint! {
300300
"detects labels that are never used"
301301
}
302302

303-
declare_lint! {
304-
pub DUPLICATE_ASSOCIATED_TYPE_BINDINGS,
305-
Warn,
306-
"warns about duplicate associated type bindings in generics"
307-
}
308-
309303
declare_lint! {
310304
pub DUPLICATE_MACRO_EXPORTS,
311305
Deny,
@@ -418,7 +412,6 @@ impl LintPass for HardwiredLints {
418412
ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
419413
UNSTABLE_NAME_COLLISIONS,
420414
IRREFUTABLE_LET_PATTERNS,
421-
DUPLICATE_ASSOCIATED_TYPE_BINDINGS,
422415
DUPLICATE_MACRO_EXPORTS,
423416
INTRA_DOC_LINK_RESOLUTION_FAILURE,
424417
MISSING_DOC_CODE_EXAMPLES,

src/librustc/traits/mod.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,8 @@ pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError
5050
pub use self::specialize::{OverlapError, specialization_graph, translate_substs};
5151
pub use self::specialize::find_associated_item;
5252
pub use self::engine::{TraitEngine, TraitEngineExt};
53-
pub use self::util::elaborate_predicates;
54-
pub use self::util::supertraits;
55-
pub use self::util::Supertraits;
56-
pub use self::util::supertrait_def_ids;
57-
pub use self::util::SupertraitDefIds;
53+
pub use self::util::{elaborate_predicates, elaborate_trait_ref, elaborate_trait_refs};
54+
pub use self::util::{supertraits, supertrait_def_ids, Supertraits, SupertraitDefIds};
5855
pub use self::util::transitive_bounds;
5956

6057
#[allow(dead_code)]

src/librustc/traits/util.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ impl<I> FilterToTraits<I> {
333333
}
334334
}
335335

336-
impl<'tcx,I:Iterator<Item = ty::Predicate<'tcx>>> Iterator for FilterToTraits<I> {
336+
impl<'tcx, I: Iterator<Item = ty::Predicate<'tcx>>> Iterator for FilterToTraits<I> {
337337
type Item = ty::PolyTraitRef<'tcx>;
338338

339339
fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {

src/librustc/ty/mod.rs

Lines changed: 50 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ impl Visibility {
294294
}
295295
}
296296

297-
/// Returns true if an item with this visibility is accessible from the given block.
297+
/// Returns `true` if an item with this visibility is accessible from the given block.
298298
pub fn is_accessible_from<T: DefIdTree>(self, module: DefId, tree: T) -> bool {
299299
let restriction = match self {
300300
// Public items are visible everywhere.
@@ -309,7 +309,7 @@ impl Visibility {
309309
tree.is_descendant_of(module, restriction)
310310
}
311311

312-
/// Returns true if this visibility is at least as accessible as the given visibility
312+
/// Returns `true` if this visibility is at least as accessible as the given visibility
313313
pub fn is_at_least<T: DefIdTree>(self, vis: Visibility, tree: T) -> bool {
314314
let vis_restriction = match vis {
315315
Visibility::Public => return self == Visibility::Public,
@@ -320,7 +320,7 @@ impl Visibility {
320320
self.is_accessible_from(vis_restriction, tree)
321321
}
322322

323-
// Returns true if this item is visible anywhere in the local crate.
323+
// Returns `true` if this item is visible anywhere in the local crate.
324324
pub fn is_visible_locally(self) -> bool {
325325
match self {
326326
Visibility::Public => true,
@@ -451,7 +451,7 @@ bitflags! {
451451
// FIXME: Rename this to the actual property since it's used for generators too
452452
const HAS_TY_CLOSURE = 1 << 9;
453453

454-
// true if there are "names" of types and regions and so forth
454+
// `true` if there are "names" of types and regions and so forth
455455
// that are local to a particular fn
456456
const HAS_FREE_LOCAL_NAMES = 1 << 10;
457457

@@ -544,14 +544,14 @@ impl<'tcx> TyS<'tcx> {
544544
pub fn is_primitive_ty(&self) -> bool {
545545
match self.sty {
546546
TyKind::Bool |
547-
TyKind::Char |
548-
TyKind::Int(_) |
549-
TyKind::Uint(_) |
550-
TyKind::Float(_) |
551-
TyKind::Infer(InferTy::IntVar(_)) |
552-
TyKind::Infer(InferTy::FloatVar(_)) |
553-
TyKind::Infer(InferTy::FreshIntTy(_)) |
554-
TyKind::Infer(InferTy::FreshFloatTy(_)) => true,
547+
TyKind::Char |
548+
TyKind::Int(_) |
549+
TyKind::Uint(_) |
550+
TyKind::Float(_) |
551+
TyKind::Infer(InferTy::IntVar(_)) |
552+
TyKind::Infer(InferTy::FloatVar(_)) |
553+
TyKind::Infer(InferTy::FreshIntTy(_)) |
554+
TyKind::Infer(InferTy::FreshFloatTy(_)) => true,
555555
TyKind::Ref(_, x, _) => x.is_primitive_ty(),
556556
_ => false,
557557
}
@@ -953,7 +953,7 @@ impl<'a, 'gcx, 'tcx> Generics {
953953
_ => bug!("expected lifetime parameter, but found another generic parameter")
954954
}
955955
} else {
956-
tcx.generics_of(self.parent.expect("parent_count>0 but no parent?"))
956+
tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?"))
957957
.region_param(param, tcx)
958958
}
959959
}
@@ -970,7 +970,7 @@ impl<'a, 'gcx, 'tcx> Generics {
970970
_ => bug!("expected type parameter, but found another generic parameter")
971971
}
972972
} else {
973-
tcx.generics_of(self.parent.expect("parent_count>0 but no parent?"))
973+
tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?"))
974974
.type_param(param, tcx)
975975
}
976976
}
@@ -993,6 +993,7 @@ impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> {
993993
self.instantiate_into(tcx, &mut instantiated, substs);
994994
instantiated
995995
}
996+
996997
pub fn instantiate_own(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &Substs<'tcx>)
997998
-> InstantiatedPredicates<'tcx> {
998999
InstantiatedPredicates {
@@ -1041,15 +1042,15 @@ impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> {
10411042

10421043
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
10431044
pub enum Predicate<'tcx> {
1044-
/// Corresponds to `where Foo : Bar<A,B,C>`. `Foo` here would be
1045+
/// Corresponds to `where Foo: Bar<A,B,C>`. `Foo` here would be
10451046
/// the `Self` type of the trait reference and `A`, `B`, and `C`
10461047
/// would be the type parameters.
10471048
Trait(PolyTraitPredicate<'tcx>),
10481049

1049-
/// where `'a : 'b`
1050+
/// where `'a: 'b`
10501051
RegionOutlives(PolyRegionOutlivesPredicate<'tcx>),
10511052

1052-
/// where `T : 'a`
1053+
/// where `T: 'a`
10531054
TypeOutlives(PolyTypeOutlivesPredicate<'tcx>),
10541055

10551056
/// where `<T as TraitRef>::Name == X`, approximately.
@@ -1062,7 +1063,7 @@ pub enum Predicate<'tcx> {
10621063
/// trait must be object-safe
10631064
ObjectSafe(DefId),
10641065

1065-
/// No direct syntax. May be thought of as `where T : FnFoo<...>`
1066+
/// No direct syntax. May be thought of as `where T: FnFoo<...>`
10661067
/// for some substitutions `...` and `T` being a closure type.
10671068
/// Satisfied (or refuted) once we know the closure's kind.
10681069
ClosureKind(DefId, ClosureSubsts<'tcx>, ClosureKind),
@@ -1111,11 +1112,11 @@ impl<'a, 'gcx, 'tcx> Predicate<'tcx> {
11111112
//
11121113
// Let's start with an easy case. Consider two traits:
11131114
//
1114-
// trait Foo<'a> : Bar<'a,'a> { }
1115+
// trait Foo<'a>: Bar<'a,'a> { }
11151116
// trait Bar<'b,'c> { }
11161117
//
1117-
// Now, if we have a trait reference `for<'x> T : Foo<'x>`, then
1118-
// we can deduce that `for<'x> T : Bar<'x,'x>`. Basically, if we
1118+
// Now, if we have a trait reference `for<'x> T: Foo<'x>`, then
1119+
// we can deduce that `for<'x> T: Bar<'x,'x>`. Basically, if we
11191120
// knew that `Foo<'x>` (for any 'x) then we also know that
11201121
// `Bar<'x,'x>` (for any 'x). This more-or-less falls out from
11211122
// normal substitution.
@@ -1128,21 +1129,21 @@ impl<'a, 'gcx, 'tcx> Predicate<'tcx> {
11281129
//
11291130
// Another example to be careful of is this:
11301131
//
1131-
// trait Foo1<'a> : for<'b> Bar1<'a,'b> { }
1132+
// trait Foo1<'a>: for<'b> Bar1<'a,'b> { }
11321133
// trait Bar1<'b,'c> { }
11331134
//
1134-
// Here, if we have `for<'x> T : Foo1<'x>`, then what do we know?
1135-
// The answer is that we know `for<'x,'b> T : Bar1<'x,'b>`. The
1135+
// Here, if we have `for<'x> T: Foo1<'x>`, then what do we know?
1136+
// The answer is that we know `for<'x,'b> T: Bar1<'x,'b>`. The
11361137
// reason is similar to the previous example: any impl of
1137-
// `T:Foo1<'x>` must show that `for<'b> T : Bar1<'x, 'b>`. So
1138+
// `T:Foo1<'x>` must show that `for<'b> T: Bar1<'x, 'b>`. So
11381139
// basically we would want to collapse the bound lifetimes from
11391140
// the input (`trait_ref`) and the supertraits.
11401141
//
11411142
// To achieve this in practice is fairly straightforward. Let's
11421143
// consider the more complicated scenario:
11431144
//
1144-
// - We start out with `for<'x> T : Foo1<'x>`. In this case, `'x`
1145-
// has a De Bruijn index of 1. We want to produce `for<'x,'b> T : Bar1<'x,'b>`,
1145+
// - We start out with `for<'x> T: Foo1<'x>`. In this case, `'x`
1146+
// has a De Bruijn index of 1. We want to produce `for<'x,'b> T: Bar1<'x,'b>`,
11461147
// where both `'x` and `'b` would have a DB index of 1.
11471148
// The substitution from the input trait-ref is therefore going to be
11481149
// `'a => 'x` (where `'x` has a DB index of 1).
@@ -1194,6 +1195,7 @@ impl<'a, 'gcx, 'tcx> Predicate<'tcx> {
11941195
pub struct TraitPredicate<'tcx> {
11951196
pub trait_ref: TraitRef<'tcx>
11961197
}
1198+
11971199
pub type PolyTraitPredicate<'tcx> = ty::Binder<TraitPredicate<'tcx>>;
11981200

11991201
impl<'tcx> TraitPredicate<'tcx> {
@@ -1218,7 +1220,7 @@ impl<'tcx> PolyTraitPredicate<'tcx> {
12181220
}
12191221

12201222
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
1221-
pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A : B`
1223+
pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A: B`
12221224
pub type PolyOutlivesPredicate<A,B> = ty::Binder<OutlivesPredicate<A,B>>;
12231225
pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate<ty::Region<'tcx>,
12241226
ty::Region<'tcx>>;
@@ -1238,11 +1240,11 @@ pub type PolySubtypePredicate<'tcx> = ty::Binder<SubtypePredicate<'tcx>>;
12381240
/// This kind of predicate has no *direct* correspondent in the
12391241
/// syntax, but it roughly corresponds to the syntactic forms:
12401242
///
1241-
/// 1. `T : TraitRef<..., Item=Type>`
1243+
/// 1. `T: TraitRef<..., Item=Type>`
12421244
/// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
12431245
///
12441246
/// In particular, form #1 is "desugared" to the combination of a
1245-
/// normal trait predicate (`T : TraitRef<...>`) and one of these
1247+
/// normal trait predicate (`T: TraitRef<...>`) and one of these
12461248
/// predicates. Form #2 is a broader form in that it also permits
12471249
/// equality between arbitrary types. Processing an instance of
12481250
/// Form #2 eventually yields one of these `ProjectionPredicate`
@@ -1256,14 +1258,14 @@ pub struct ProjectionPredicate<'tcx> {
12561258
pub type PolyProjectionPredicate<'tcx> = Binder<ProjectionPredicate<'tcx>>;
12571259

12581260
impl<'tcx> PolyProjectionPredicate<'tcx> {
1259-
/// Returns the def-id of the associated item being projected.
1261+
/// Returns the `DefId` of the associated item being projected.
12601262
pub fn item_def_id(&self) -> DefId {
12611263
self.skip_binder().projection_ty.item_def_id
12621264
}
12631265

12641266
pub fn to_poly_trait_ref(&self, tcx: TyCtxt<'_, '_, '_>) -> PolyTraitRef<'tcx> {
1265-
// Note: unlike with TraitRef::to_poly_trait_ref(),
1266-
// self.0.trait_ref is permitted to have escaping regions.
1267+
// Note: unlike with `TraitRef::to_poly_trait_ref()`,
1268+
// `self.0.trait_ref` is permitted to have escaping regions.
12671269
// This is because here `self` has a `Binder` and so does our
12681270
// return value, so we are preserving the number of binding
12691271
// levels.
@@ -1274,12 +1276,12 @@ impl<'tcx> PolyProjectionPredicate<'tcx> {
12741276
self.map_bound(|predicate| predicate.ty)
12751277
}
12761278

1277-
/// The DefId of the TraitItem for the associated type.
1279+
/// The `DefId` of the `TraitItem` for the associated type.
12781280
///
1279-
/// Note that this is not the DefId of the TraitRef containing this
1280-
/// associated type, which is in tcx.associated_item(projection_def_id()).container.
1281+
/// Note that this is not the `DefId` of the `TraitRef` containing this
1282+
/// associated type, which is in `tcx.associated_item(projection_def_id()).container`.
12811283
pub fn projection_def_id(&self) -> DefId {
1282-
// ok to skip binder since trait def-id does not care about regions
1284+
// okay to skip binder since trait def-id does not care about regions
12831285
self.skip_binder().projection_ty.item_def_id
12841286
}
12851287
}
@@ -1515,14 +1517,14 @@ impl UniverseIndex {
15151517
UniverseIndex::from_u32(self.private.checked_add(1).unwrap())
15161518
}
15171519

1518-
/// True if `self` can name a name from `other` -- in other words,
1520+
/// Returns `true` if `self` can name a name from `other` -- in other words,
15191521
/// if the set of names in `self` is a superset of those in
15201522
/// `other` (`self >= other`).
15211523
pub fn can_name(self, other: UniverseIndex) -> bool {
15221524
self.private >= other.private
15231525
}
15241526

1525-
/// True if `self` cannot name some names from `other` -- in other
1527+
/// Returns `true` if `self` cannot name some names from `other` -- in other
15261528
/// words, if the set of names in `self` is a strict subset of
15271529
/// those in `other` (`self < other`).
15281530
pub fn cannot_name(self, other: UniverseIndex) -> bool {
@@ -1574,7 +1576,7 @@ impl<'tcx> ParamEnv<'tcx> {
15741576
/// are revealed. This is suitable for monomorphized, post-typeck
15751577
/// environments like codegen or doing optimizations.
15761578
///
1577-
/// NB. If you want to have predicates in scope, use `ParamEnv::new`,
1579+
/// N.B. If you want to have predicates in scope, use `ParamEnv::new`,
15781580
/// or invoke `param_env.with_reveal_all()`.
15791581
pub fn reveal_all() -> Self {
15801582
Self::new(List::empty(), Reveal::All)
@@ -1979,14 +1981,14 @@ impl ReprOptions {
19791981
self.int.unwrap_or(attr::SignedInt(ast::IntTy::Isize))
19801982
}
19811983

1982-
/// Returns true if this `#[repr()]` should inhabit "smart enum
1984+
/// Returns `true` if this `#[repr()]` should inhabit "smart enum
19831985
/// layout" optimizations, such as representing `Foo<&T>` as a
19841986
/// single pointer.
19851987
pub fn inhibit_enum_layout_opt(&self) -> bool {
19861988
self.c() || self.int.is_some()
19871989
}
19881990

1989-
/// Returns true if this `#[repr()]` should inhibit struct field reordering
1991+
/// Returns `true` if this `#[repr()]` should inhibit struct field reordering
19901992
/// optimizations, such as with repr(C) or repr(packed(1)).
19911993
pub fn inhibit_struct_field_reordering_opt(&self) -> bool {
19921994
!(self.flags & ReprFlags::IS_UNOPTIMISABLE).is_empty() || (self.pack == 1)
@@ -2089,7 +2091,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
20892091
self.flags.intersects(AdtFlags::IS_FUNDAMENTAL)
20902092
}
20912093

2092-
/// Returns true if this is PhantomData<T>.
2094+
/// Returns `true` if this is PhantomData<T>.
20932095
#[inline]
20942096
pub fn is_phantom_data(&self) -> bool {
20952097
self.flags.intersects(AdtFlags::IS_PHANTOM_DATA)
@@ -2105,7 +2107,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
21052107
self.flags.intersects(AdtFlags::IS_RC)
21062108
}
21072109

2108-
/// Returns true if this is Box<T>.
2110+
/// Returns `true` if this is Box<T>.
21092111
#[inline]
21102112
pub fn is_box(&self) -> bool {
21112113
self.flags.intersects(AdtFlags::IS_BOX)
@@ -2422,7 +2424,7 @@ impl<'a, 'tcx> ClosureKind {
24222424
}
24232425
}
24242426

2425-
/// True if this a type that impls this closure kind
2427+
/// Returns `true` if this a type that impls this closure kind
24262428
/// must also implement `other`.
24272429
pub fn extends(self, other: ty::ClosureKind) -> bool {
24282430
match (self, other) {
@@ -2475,7 +2477,7 @@ impl<'tcx> TyS<'tcx> {
24752477
///
24762478
/// Note: prefer `ty.walk()` where possible.
24772479
pub fn maybe_walk<F>(&'tcx self, mut f: F)
2478-
where F : FnMut(Ty<'tcx>) -> bool
2480+
where F: FnMut(Ty<'tcx>) -> bool
24792481
{
24802482
let mut walker = self.walk();
24812483
while let Some(ty) = walker.next() {
@@ -2678,7 +2680,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
26782680
as Box<dyn Iterator<Item = AssociatedItem> + 'a>
26792681
}
26802682

2681-
/// Returns true if the impls are the same polarity and the trait either
2683+
/// Returns `true` if the impls are the same polarity and the trait either
26822684
/// has no items or is annotated #[marker] and prevents item overrides.
26832685
pub fn impls_are_allowed_to_overlap(self, def_id1: DefId, def_id2: DefId) -> bool {
26842686
if self.features().overlapping_marker_traits {
@@ -2802,7 +2804,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
28022804
attr::contains_name(&self.get_attrs(did), attr)
28032805
}
28042806

2805-
/// Returns true if this is an `auto trait`.
2807+
/// Returns `true` if this is an `auto trait`.
28062808
pub fn trait_is_auto(self, trait_def_id: DefId) -> bool {
28072809
self.trait_def(trait_def_id).has_auto_impl
28082810
}

0 commit comments

Comments
 (0)