Point at HIR types when impl trait ref doesn't normalize
This commit is contained in:
parent
1bc3683b32
commit
d76e168f01
@ -1254,7 +1254,11 @@ fn check_impl<'tcx>(
|
|||||||
// therefore don't need to be WF (the trait's `Self: Trait` predicate
|
// therefore don't need to be WF (the trait's `Self: Trait` predicate
|
||||||
// won't hold).
|
// won't hold).
|
||||||
let trait_ref = tcx.impl_trait_ref(item.owner_id).unwrap();
|
let trait_ref = tcx.impl_trait_ref(item.owner_id).unwrap();
|
||||||
let trait_ref = wfcx.normalize(ast_trait_ref.path.span, None, trait_ref);
|
let trait_ref = wfcx.normalize(
|
||||||
|
ast_trait_ref.path.span,
|
||||||
|
Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
|
||||||
|
trait_ref,
|
||||||
|
);
|
||||||
let trait_pred = ty::TraitPredicate {
|
let trait_pred = ty::TraitPredicate {
|
||||||
trait_ref,
|
trait_ref,
|
||||||
constness: match constness {
|
constness: match constness {
|
||||||
|
@ -114,34 +114,46 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
|
|||||||
// Get the starting `hir::Ty` using our `WellFormedLoc`.
|
// Get the starting `hir::Ty` using our `WellFormedLoc`.
|
||||||
// We will walk 'into' this type to try to find
|
// We will walk 'into' this type to try to find
|
||||||
// a more precise span for our predicate.
|
// a more precise span for our predicate.
|
||||||
let ty = match loc {
|
let tys = match loc {
|
||||||
WellFormedLoc::Ty(_) => match hir.get(hir_id) {
|
WellFormedLoc::Ty(_) => match hir.get(hir_id) {
|
||||||
hir::Node::ImplItem(item) => match item.kind {
|
hir::Node::ImplItem(item) => match item.kind {
|
||||||
hir::ImplItemKind::Type(ty) => Some(ty),
|
hir::ImplItemKind::Type(ty) => vec![ty],
|
||||||
hir::ImplItemKind::Const(ty, _) => Some(ty),
|
hir::ImplItemKind::Const(ty, _) => vec![ty],
|
||||||
ref item => bug!("Unexpected ImplItem {:?}", item),
|
ref item => bug!("Unexpected ImplItem {:?}", item),
|
||||||
},
|
},
|
||||||
hir::Node::TraitItem(item) => match item.kind {
|
hir::Node::TraitItem(item) => match item.kind {
|
||||||
hir::TraitItemKind::Type(_, ty) => ty,
|
hir::TraitItemKind::Type(_, ty) => ty.into_iter().collect(),
|
||||||
hir::TraitItemKind::Const(ty, _) => Some(ty),
|
hir::TraitItemKind::Const(ty, _) => vec![ty],
|
||||||
ref item => bug!("Unexpected TraitItem {:?}", item),
|
ref item => bug!("Unexpected TraitItem {:?}", item),
|
||||||
},
|
},
|
||||||
hir::Node::Item(item) => match item.kind {
|
hir::Node::Item(item) => match item.kind {
|
||||||
hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _) => Some(ty),
|
hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _) => vec![ty],
|
||||||
hir::ItemKind::Impl(ref impl_) => {
|
hir::ItemKind::Impl(ref impl_) => match &impl_.of_trait {
|
||||||
assert!(impl_.of_trait.is_none(), "Unexpected trait impl: {:?}", impl_);
|
Some(t) => t
|
||||||
Some(impl_.self_ty)
|
.path
|
||||||
}
|
.segments
|
||||||
|
.last()
|
||||||
|
.iter()
|
||||||
|
.flat_map(|seg| seg.args().args)
|
||||||
|
.filter_map(|arg| {
|
||||||
|
if let hir::GenericArg::Type(ty) = arg { Some(*ty) } else { None }
|
||||||
|
})
|
||||||
|
.chain([impl_.self_ty])
|
||||||
|
.collect(),
|
||||||
|
None => {
|
||||||
|
vec![impl_.self_ty]
|
||||||
|
}
|
||||||
|
},
|
||||||
ref item => bug!("Unexpected item {:?}", item),
|
ref item => bug!("Unexpected item {:?}", item),
|
||||||
},
|
},
|
||||||
hir::Node::Field(field) => Some(field.ty),
|
hir::Node::Field(field) => vec![field.ty],
|
||||||
hir::Node::ForeignItem(ForeignItem {
|
hir::Node::ForeignItem(ForeignItem {
|
||||||
kind: ForeignItemKind::Static(ty, _), ..
|
kind: ForeignItemKind::Static(ty, _), ..
|
||||||
}) => Some(*ty),
|
}) => vec![*ty],
|
||||||
hir::Node::GenericParam(hir::GenericParam {
|
hir::Node::GenericParam(hir::GenericParam {
|
||||||
kind: hir::GenericParamKind::Type { default: Some(ty), .. },
|
kind: hir::GenericParamKind::Type { default: Some(ty), .. },
|
||||||
..
|
..
|
||||||
}) => Some(*ty),
|
}) => vec![*ty],
|
||||||
ref node => bug!("Unexpected node {:?}", node),
|
ref node => bug!("Unexpected node {:?}", node),
|
||||||
},
|
},
|
||||||
WellFormedLoc::Param { function: _, param_idx } => {
|
WellFormedLoc::Param { function: _, param_idx } => {
|
||||||
@ -149,16 +161,16 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
|
|||||||
// Get return type
|
// Get return type
|
||||||
if param_idx as usize == fn_decl.inputs.len() {
|
if param_idx as usize == fn_decl.inputs.len() {
|
||||||
match fn_decl.output {
|
match fn_decl.output {
|
||||||
hir::FnRetTy::Return(ty) => Some(ty),
|
hir::FnRetTy::Return(ty) => vec![ty],
|
||||||
// The unit type `()` is always well-formed
|
// The unit type `()` is always well-formed
|
||||||
hir::FnRetTy::DefaultReturn(_span) => None,
|
hir::FnRetTy::DefaultReturn(_span) => vec![],
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Some(&fn_decl.inputs[param_idx as usize])
|
vec![&fn_decl.inputs[param_idx as usize]]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if let Some(ty) = ty {
|
for ty in tys {
|
||||||
visitor.visit_ty(ty);
|
visitor.visit_ty(ty);
|
||||||
}
|
}
|
||||||
visitor.cause
|
visitor.cause
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error[E0277]: the trait bound `B: Clone` is not satisfied
|
error[E0277]: the trait bound `B: Clone` is not satisfied
|
||||||
--> $DIR/issue-79224.rs:18:17
|
--> $DIR/issue-79224.rs:18:29
|
||||||
|
|
|
|
||||||
LL | impl<B: ?Sized> Display for Cow<'_, B> {
|
LL | impl<B: ?Sized> Display for Cow<'_, B> {
|
||||||
| ^^^^^^^ the trait `Clone` is not implemented for `B`
|
| ^^^^^^^^^^ the trait `Clone` is not implemented for `B`
|
||||||
|
|
|
|
||||||
= note: required for `B` to implement `ToOwned`
|
= note: required for `B` to implement `ToOwned`
|
||||||
help: consider further restricting this bound
|
help: consider further restricting this bound
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error[E0277]: the trait bound `Foo: HasComponent<()>` is not satisfied
|
error[E0277]: the trait bound `Foo: HasComponent<()>` is not satisfied
|
||||||
--> $DIR/issue-91594.rs:10:6
|
--> $DIR/issue-91594.rs:10:19
|
||||||
|
|
|
|
||||||
LL | impl HasComponent<<Foo as Component<Foo>>::Interface> for Foo {}
|
LL | impl HasComponent<<Foo as Component<Foo>>::Interface> for Foo {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasComponent<()>` is not implemented for `Foo`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasComponent<()>` is not implemented for `Foo`
|
||||||
|
|
|
|
||||||
= help: the trait `HasComponent<<Foo as Component<Foo>>::Interface>` is implemented for `Foo`
|
= help: the trait `HasComponent<<Foo as Component<Foo>>::Interface>` is implemented for `Foo`
|
||||||
note: required for `Foo` to implement `Component<Foo>`
|
note: required for `Foo` to implement `Component<Foo>`
|
||||||
|
Loading…
Reference in New Issue
Block a user