Skip to content

Commit 6bc55c7

Browse files
committed
Remove AssocTypeBound and propagate bound Spans
1 parent ad1c23c commit 6bc55c7

17 files changed

+106
-287
lines changed

src/librustc_middle/traits/mod.rs

-9
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,6 @@ pub enum ObligationCauseCode<'tcx> {
257257

258258
/// #[feature(trivial_bounds)] is not enabled
259259
TrivialBound,
260-
261-
AssocTypeBound(Box<AssocTypeBoundData>),
262260
}
263261

264262
impl ObligationCauseCode<'_> {
@@ -272,13 +270,6 @@ impl ObligationCauseCode<'_> {
272270
}
273271
}
274272

275-
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
276-
pub struct AssocTypeBoundData {
277-
pub impl_span: Option<Span>,
278-
pub original: Span,
279-
pub bounds: Vec<Span>,
280-
}
281-
282273
// `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger.
283274
#[cfg(target_arch = "x86_64")]
284275
static_assert_size!(ObligationCauseCode<'_>, 32);

src/librustc_middle/traits/structural_impls.rs

-1
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,6 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
501501
super::MethodReceiver => Some(super::MethodReceiver),
502502
super::BlockTailExpression(id) => Some(super::BlockTailExpression(id)),
503503
super::TrivialBound => Some(super::TrivialBound),
504-
super::AssocTypeBound(ref data) => Some(super::AssocTypeBound(data.clone())),
505504
}
506505
}
507506
}

src/librustc_trait_selection/traits/error_reporting/suggestions.rs

-9
Original file line numberDiff line numberDiff line change
@@ -1684,15 +1684,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
16841684
err.help("add `#![feature(trivial_bounds)]` to the crate attributes to enable");
16851685
}
16861686
}
1687-
ObligationCauseCode::AssocTypeBound(ref data) => {
1688-
err.span_label(data.original, "associated type defined here");
1689-
if let Some(sp) = data.impl_span {
1690-
err.span_label(sp, "in this `impl` item");
1691-
}
1692-
for sp in &data.bounds {
1693-
err.span_label(*sp, "restricted in this bound");
1694-
}
1695-
}
16961687
}
16971688
}
16981689

src/librustc_trait_selection/traits/wf.rs

+50-179
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
use crate::infer::InferCtxt;
22
use crate::opaque_types::required_region_bounds;
3-
use crate::traits::{self, AssocTypeBoundData};
3+
use crate::traits;
44
use rustc_hir as hir;
55
use rustc_hir::def_id::DefId;
66
use rustc_hir::lang_items;
77
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
88
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
9-
use rustc_span::symbol::{kw, Ident};
109
use rustc_span::Span;
1110
use std::rc::Rc;
1211

@@ -143,137 +142,57 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
143142
pred: &ty::Predicate<'_>,
144143
mut trait_assoc_items: impl Iterator<Item = ty::AssocItem>,
145144
) {
146-
let trait_item =
147-
tcx.hir().as_local_hir_id(trait_ref.def_id).and_then(|trait_id| tcx.hir().find(trait_id));
148-
let (trait_name, trait_generics) = match trait_item {
149-
Some(hir::Node::Item(hir::Item {
150-
ident,
151-
kind: hir::ItemKind::Trait(.., generics, _, _),
152-
..
153-
}))
154-
| Some(hir::Node::Item(hir::Item {
155-
ident,
156-
kind: hir::ItemKind::TraitAlias(generics, _),
157-
..
158-
})) => (Some(ident), Some(generics)),
159-
_ => (None, None),
145+
debug!(
146+
"extended_cause_with_original_assoc_item_obligation {:?} {:?} {:?} {:?}",
147+
trait_ref, item, cause, pred
148+
);
149+
let items = match item {
150+
Some(hir::Item { kind: hir::ItemKind::Impl { items, .. }, .. }) => items,
151+
_ => return,
160152
};
161-
162-
let item_span = item.map(|i| tcx.sess.source_map().guess_head_span(i.span));
153+
let fix_span =
154+
|impl_item_ref: &hir::ImplItemRef<'_>| match tcx.hir().impl_item(impl_item_ref.id).kind {
155+
hir::ImplItemKind::Const(ty, _) | hir::ImplItemKind::TyAlias(ty) => ty.span,
156+
_ => impl_item_ref.span,
157+
};
163158
match pred {
164159
ty::Predicate::Projection(proj) => {
165160
// The obligation comes not from the current `impl` nor the `trait` being
166161
// implemented, but rather from a "second order" obligation, like in
167-
// `src/test/ui/associated-types/point-at-type-on-obligation-failure.rs`:
168-
//
169-
// error[E0271]: type mismatch resolving `<Foo2 as Bar2>::Ok == ()`
170-
// --> $DIR/point-at-type-on-obligation-failure.rs:13:5
171-
// |
172-
// LL | type Ok;
173-
// | -- associated type defined here
174-
// ...
175-
// LL | impl Bar for Foo {
176-
// | ---------------- in this `impl` item
177-
// LL | type Ok = ();
178-
// | ^^^^^^^^^^^^^ expected `u32`, found `()`
179-
// |
180-
// = note: expected type `u32`
181-
// found type `()`
182-
//
183-
// FIXME: we would want to point a span to all places that contributed to this
184-
// obligation. In the case above, it should be closer to:
185-
//
186-
// error[E0271]: type mismatch resolving `<Foo2 as Bar2>::Ok == ()`
187-
// --> $DIR/point-at-type-on-obligation-failure.rs:13:5
188-
// |
189-
// LL | type Ok;
190-
// | -- associated type defined here
191-
// LL | type Sibling: Bar2<Ok=Self::Ok>;
192-
// | -------------------------------- obligation set here
193-
// ...
194-
// LL | impl Bar for Foo {
195-
// | ---------------- in this `impl` item
196-
// LL | type Ok = ();
197-
// | ^^^^^^^^^^^^^ expected `u32`, found `()`
198-
// ...
199-
// LL | impl Bar2 for Foo2 {
200-
// | ---------------- in this `impl` item
201-
// LL | type Ok = u32;
202-
// | -------------- obligation set here
203-
// |
204-
// = note: expected type `u32`
205-
// found type `()`
206-
if let Some(hir::ItemKind::Impl { items, .. }) = item.map(|i| &i.kind) {
207-
let trait_assoc_item = tcx.associated_item(proj.projection_def_id());
208-
if let Some(impl_item) =
209-
items.iter().find(|item| item.ident == trait_assoc_item.ident)
210-
{
211-
cause.span = impl_item.span;
212-
cause.code = traits::AssocTypeBound(Box::new(AssocTypeBoundData {
213-
impl_span: item_span,
214-
original: trait_assoc_item.ident.span,
215-
bounds: vec![],
216-
}));
162+
// `src/test/ui/associated-types/point-at-type-on-obligation-failure.rs`.
163+
let trait_assoc_item = tcx.associated_item(proj.projection_def_id());
164+
if let Some(impl_item_span) =
165+
items.iter().find(|item| item.ident == trait_assoc_item.ident).map(fix_span)
166+
{
167+
cause.span = impl_item_span;
168+
} else {
169+
let kind = &proj.ty().skip_binder().kind;
170+
if let ty::Projection(projection_ty) = kind {
171+
// This happens when an associated type has a projection coming from another
172+
// associated type. See `traits-assoc-type-in-supertrait-bad.rs`.
173+
let trait_assoc_item = tcx.associated_item(projection_ty.item_def_id);
174+
if let Some(impl_item_span) =
175+
items.iter().find(|item| item.ident == trait_assoc_item.ident).map(fix_span)
176+
{
177+
cause.span = impl_item_span;
178+
}
217179
}
218180
}
219181
}
220-
ty::Predicate::Trait(proj, _) => {
221-
// An associated item obligation born out of the `trait` failed to be met.
222-
// Point at the `impl` that failed the obligation, the associated item that
223-
// needed to meet the obligation, and the definition of that associated item,
224-
// which should hold the obligation in most cases. An example can be seen in
225-
// `src/test/ui/associated-types/point-at-type-on-obligation-failure-2.rs`:
226-
//
227-
// error[E0277]: the trait bound `bool: Bar` is not satisfied
228-
// --> $DIR/point-at-type-on-obligation-failure-2.rs:8:5
229-
// |
230-
// LL | type Assoc: Bar;
231-
// | ----- associated type defined here
232-
// ...
233-
// LL | impl Foo for () {
234-
// | --------------- in this `impl` item
235-
// LL | type Assoc = bool;
236-
// | ^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `bool`
237-
//
238-
// If the obligation comes from the where clause in the `trait`, we point at it:
239-
//
240-
// error[E0277]: the trait bound `bool: Bar` is not satisfied
241-
// --> $DIR/point-at-type-on-obligation-failure-2.rs:8:5
242-
// |
243-
// | trait Foo where <Self as Foo>>::Assoc: Bar {
244-
// | -------------------------- restricted in this bound
245-
// LL | type Assoc;
246-
// | ----- associated type defined here
247-
// ...
248-
// LL | impl Foo for () {
249-
// | --------------- in this `impl` item
250-
// LL | type Assoc = bool;
251-
// | ^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `bool`
252-
if let (
253-
ty::Projection(ty::ProjectionTy { item_def_id, .. }),
254-
Some(hir::ItemKind::Impl { items, .. }),
255-
) = (&proj.skip_binder().self_ty().kind, item.map(|i| &i.kind))
182+
ty::Predicate::Trait(pred, _) => {
183+
// An associated item obligation born out of the `trait` failed to be met. An example
184+
// can be seen in `ui/associated-types/point-at-type-on-obligation-failure-2.rs`.
185+
debug!("extended_cause_with_original_assoc_item_obligation trait proj {:?}", pred);
186+
if let ty::Projection(ty::ProjectionTy { item_def_id, .. }) =
187+
&pred.skip_binder().self_ty().kind
256188
{
257-
if let Some((impl_item, trait_assoc_item)) = trait_assoc_items
189+
if let Some(impl_item_span) = trait_assoc_items
258190
.find(|i| i.def_id == *item_def_id)
259191
.and_then(|trait_assoc_item| {
260-
items
261-
.iter()
262-
.find(|i| i.ident == trait_assoc_item.ident)
263-
.map(|impl_item| (impl_item, trait_assoc_item))
192+
items.iter().find(|i| i.ident == trait_assoc_item.ident).map(fix_span)
264193
})
265194
{
266-
let bounds = trait_generics
267-
.map(|generics| {
268-
get_generic_bound_spans(&generics, trait_name, trait_assoc_item.ident)
269-
})
270-
.unwrap_or_else(Vec::new);
271-
cause.span = impl_item.span;
272-
cause.code = traits::AssocTypeBound(Box::new(AssocTypeBoundData {
273-
impl_span: item_span,
274-
original: trait_assoc_item.ident.span,
275-
bounds,
276-
}));
195+
cause.span = impl_item_span;
277196
}
278197
}
279198
}
@@ -307,6 +226,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
307226
let tcx = self.infcx.tcx;
308227
let obligations = self.nominal_obligations(trait_ref.def_id, trait_ref.substs);
309228

229+
debug!("compute_trait_ref obligations {:?}", obligations);
310230
let cause = self.cause(traits::MiscObligation);
311231
let param_env = self.param_env;
312232

@@ -315,16 +235,16 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
315235
if let Elaborate::All = elaborate {
316236
let implied_obligations = traits::util::elaborate_obligations(tcx, obligations.clone());
317237
let implied_obligations = implied_obligations.map(|obligation| {
238+
debug!("compute_trait_ref implied_obligation {:?}", obligation);
239+
debug!("compute_trait_ref implied_obligation cause {:?}", obligation.cause);
318240
let mut cause = cause.clone();
319-
let parent_trait_ref = obligation
320-
.predicate
321-
.to_opt_poly_trait_ref()
322-
.unwrap_or_else(|| ty::Binder::dummy(*trait_ref));
323-
let derived_cause = traits::DerivedObligationCause {
324-
parent_trait_ref,
325-
parent_code: Rc::new(obligation.cause.code.clone()),
326-
};
327-
cause.code = traits::ObligationCauseCode::ImplDerivedObligation(derived_cause);
241+
if let Some(parent_trait_ref) = obligation.predicate.to_opt_poly_trait_ref() {
242+
let derived_cause = traits::DerivedObligationCause {
243+
parent_trait_ref,
244+
parent_code: Rc::new(obligation.cause.code.clone()),
245+
};
246+
cause.code = traits::ObligationCauseCode::ImplDerivedObligation(derived_cause);
247+
}
328248
extend_cause_with_original_assoc_item_obligation(
329249
tcx,
330250
trait_ref,
@@ -333,6 +253,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
333253
&obligation.predicate,
334254
tcx.associated_items(trait_ref.def_id).in_definition_order().copied(),
335255
);
256+
debug!("compute_trait_ref new cause {:?}", cause);
336257
traits::Obligation::new(cause, param_env, obligation.predicate)
337258
});
338259
self.out.extend(implied_obligations);
@@ -719,53 +640,3 @@ pub fn object_region_bounds<'tcx>(
719640

720641
required_region_bounds(tcx, open_ty, predicates)
721642
}
722-
723-
/// Find the span of a generic bound affecting an associated type.
724-
fn get_generic_bound_spans(
725-
generics: &hir::Generics<'_>,
726-
trait_name: Option<&Ident>,
727-
assoc_item_name: Ident,
728-
) -> Vec<Span> {
729-
let mut bounds = vec![];
730-
for clause in generics.where_clause.predicates.iter() {
731-
if let hir::WherePredicate::BoundPredicate(pred) = clause {
732-
match &pred.bounded_ty.kind {
733-
hir::TyKind::Path(hir::QPath::Resolved(Some(ty), path)) => {
734-
let mut s = path.segments.iter();
735-
if let (a, Some(b), None) = (s.next(), s.next(), s.next()) {
736-
if a.map(|s| &s.ident) == trait_name
737-
&& b.ident == assoc_item_name
738-
&& is_self_path(&ty.kind)
739-
{
740-
// `<Self as Foo>::Bar`
741-
bounds.push(pred.span);
742-
}
743-
}
744-
}
745-
hir::TyKind::Path(hir::QPath::TypeRelative(ty, segment)) => {
746-
if segment.ident == assoc_item_name {
747-
if is_self_path(&ty.kind) {
748-
// `Self::Bar`
749-
bounds.push(pred.span);
750-
}
751-
}
752-
}
753-
_ => {}
754-
}
755-
}
756-
}
757-
bounds
758-
}
759-
760-
fn is_self_path(kind: &hir::TyKind<'_>) -> bool {
761-
if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = kind {
762-
let mut s = path.segments.iter();
763-
if let (Some(segment), None) = (s.next(), s.next()) {
764-
if segment.ident.name == kw::SelfUpper {
765-
// `type(Self)`
766-
return true;
767-
}
768-
}
769-
}
770-
false
771-
}

src/librustc_typeck/astconv.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1045,7 +1045,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
10451045
bounds,
10461046
speculative,
10471047
&mut dup_bindings,
1048-
span,
1048+
binding.span,
10491049
);
10501050
// Okay to ignore `Err` because of `ErrorReported` (see above).
10511051
}

src/test/ui/associated-type/associated-type-projection-from-multiple-supertraits.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ LL | fn dent<C:BoxCar>(c: C, color: <C as Vehicle>::Color) {
2828
| ^^^^^^^^^^^^^^^^^^^^^
2929

3030
error[E0222]: ambiguous associated type `Color` in bounds of `BoxCar`
31-
--> $DIR/associated-type-projection-from-multiple-supertraits.rs:23:30
31+
--> $DIR/associated-type-projection-from-multiple-supertraits.rs:23:37
3232
|
3333
LL | type Color;
3434
| ----------- ambiguous `Color` from `Vehicle`
@@ -37,7 +37,7 @@ LL | type Color;
3737
| ----------- ambiguous `Color` from `Box`
3838
...
3939
LL | fn dent_object<COLOR>(c: dyn BoxCar<Color=COLOR>) {
40-
| ^^^^^^^^^^^^^^^^^^^ ambiguous associated type `Color`
40+
| ^^^^^^^^^^^ ambiguous associated type `Color`
4141
|
4242
= help: consider introducing a new type parameter `T` and adding `where` constraints:
4343
where

0 commit comments

Comments
 (0)