Skip to content

Commit d76e168

Browse files
Point at HIR types when impl trait ref doesn't normalize
1 parent 1bc3683 commit d76e168

File tree

4 files changed

+38
-22
lines changed

4 files changed

+38
-22
lines changed

compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1254,7 +1254,11 @@ fn check_impl<'tcx>(
12541254
// therefore don't need to be WF (the trait's `Self: Trait` predicate
12551255
// won't hold).
12561256
let trait_ref = tcx.impl_trait_ref(item.owner_id).unwrap();
1257-
let trait_ref = wfcx.normalize(ast_trait_ref.path.span, None, trait_ref);
1257+
let trait_ref = wfcx.normalize(
1258+
ast_trait_ref.path.span,
1259+
Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
1260+
trait_ref,
1261+
);
12581262
let trait_pred = ty::TraitPredicate {
12591263
trait_ref,
12601264
constness: match constness {

compiler/rustc_hir_analysis/src/hir_wf_check.rs

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -114,51 +114,63 @@ fn diagnostic_hir_wf_check<'tcx>(
114114
// Get the starting `hir::Ty` using our `WellFormedLoc`.
115115
// We will walk 'into' this type to try to find
116116
// a more precise span for our predicate.
117-
let ty = match loc {
117+
let tys = match loc {
118118
WellFormedLoc::Ty(_) => match hir.get(hir_id) {
119119
hir::Node::ImplItem(item) => match item.kind {
120-
hir::ImplItemKind::Type(ty) => Some(ty),
121-
hir::ImplItemKind::Const(ty, _) => Some(ty),
120+
hir::ImplItemKind::Type(ty) => vec![ty],
121+
hir::ImplItemKind::Const(ty, _) => vec![ty],
122122
ref item => bug!("Unexpected ImplItem {:?}", item),
123123
},
124124
hir::Node::TraitItem(item) => match item.kind {
125-
hir::TraitItemKind::Type(_, ty) => ty,
126-
hir::TraitItemKind::Const(ty, _) => Some(ty),
125+
hir::TraitItemKind::Type(_, ty) => ty.into_iter().collect(),
126+
hir::TraitItemKind::Const(ty, _) => vec![ty],
127127
ref item => bug!("Unexpected TraitItem {:?}", item),
128128
},
129129
hir::Node::Item(item) => match item.kind {
130-
hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _) => Some(ty),
131-
hir::ItemKind::Impl(ref impl_) => {
132-
assert!(impl_.of_trait.is_none(), "Unexpected trait impl: {:?}", impl_);
133-
Some(impl_.self_ty)
134-
}
130+
hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _) => vec![ty],
131+
hir::ItemKind::Impl(ref impl_) => match &impl_.of_trait {
132+
Some(t) => t
133+
.path
134+
.segments
135+
.last()
136+
.iter()
137+
.flat_map(|seg| seg.args().args)
138+
.filter_map(|arg| {
139+
if let hir::GenericArg::Type(ty) = arg { Some(*ty) } else { None }
140+
})
141+
.chain([impl_.self_ty])
142+
.collect(),
143+
None => {
144+
vec![impl_.self_ty]
145+
}
146+
},
135147
ref item => bug!("Unexpected item {:?}", item),
136148
},
137-
hir::Node::Field(field) => Some(field.ty),
149+
hir::Node::Field(field) => vec![field.ty],
138150
hir::Node::ForeignItem(ForeignItem {
139151
kind: ForeignItemKind::Static(ty, _), ..
140-
}) => Some(*ty),
152+
}) => vec![*ty],
141153
hir::Node::GenericParam(hir::GenericParam {
142154
kind: hir::GenericParamKind::Type { default: Some(ty), .. },
143155
..
144-
}) => Some(*ty),
156+
}) => vec![*ty],
145157
ref node => bug!("Unexpected node {:?}", node),
146158
},
147159
WellFormedLoc::Param { function: _, param_idx } => {
148160
let fn_decl = hir.fn_decl_by_hir_id(hir_id).unwrap();
149161
// Get return type
150162
if param_idx as usize == fn_decl.inputs.len() {
151163
match fn_decl.output {
152-
hir::FnRetTy::Return(ty) => Some(ty),
164+
hir::FnRetTy::Return(ty) => vec![ty],
153165
// The unit type `()` is always well-formed
154-
hir::FnRetTy::DefaultReturn(_span) => None,
166+
hir::FnRetTy::DefaultReturn(_span) => vec![],
155167
}
156168
} else {
157-
Some(&fn_decl.inputs[param_idx as usize])
169+
vec![&fn_decl.inputs[param_idx as usize]]
158170
}
159171
}
160172
};
161-
if let Some(ty) = ty {
173+
for ty in tys {
162174
visitor.visit_ty(ty);
163175
}
164176
visitor.cause

tests/ui/specialization/min_specialization/issue-79224.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the trait bound `B: Clone` is not satisfied
2-
--> $DIR/issue-79224.rs:18:17
2+
--> $DIR/issue-79224.rs:18:29
33
|
44
LL | impl<B: ?Sized> Display for Cow<'_, B> {
5-
| ^^^^^^^ the trait `Clone` is not implemented for `B`
5+
| ^^^^^^^^^^ the trait `Clone` is not implemented for `B`
66
|
77
= note: required for `B` to implement `ToOwned`
88
help: consider further restricting this bound

tests/ui/traits/issue-91594.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the trait bound `Foo: HasComponent<()>` is not satisfied
2-
--> $DIR/issue-91594.rs:10:6
2+
--> $DIR/issue-91594.rs:10:19
33
|
44
LL | impl HasComponent<<Foo as Component<Foo>>::Interface> for Foo {}
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasComponent<()>` is not implemented for `Foo`
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasComponent<()>` is not implemented for `Foo`
66
|
77
= help: the trait `HasComponent<<Foo as Component<Foo>>::Interface>` is implemented for `Foo`
88
note: required for `Foo` to implement `Component<Foo>`

0 commit comments

Comments
 (0)