Skip to content

Commit

Permalink
Fix infinite obligation loop for Send/Sync
Browse files Browse the repository at this point in the history
  • Loading branch information
HMPerson1 committed Oct 29, 2018
1 parent ca7408b commit babfbde
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 4 deletions.
11 changes: 8 additions & 3 deletions clippy_lints/src/any_coerce.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,15 @@ fn check_unsize_coercion<'tcx>(
// redo the typechecking for this coercion to see if it required unsizing something to `dyn Any`
// see https://github.com/rust-lang/rust/blob/cae6efc37d70ab7d353e6ab9ce229d59a65ed643/src/librustc_typeck/check/coercion.rs#L454-L611
let tcx = infcx.tcx;
let coerce_unsized_trait_did = tcx.lang_items().coerce_unsized_trait().unwrap();
let unsize_trait_did = tcx.lang_items().unsize_trait().unwrap();

// don't report overflow errors
let mut selcx = traits::SelectionContext::with_query_mode(&infcx, traits::TraitQueryMode::Canonical);
let mut queue = VecDeque::new();
queue.push_back(
ty::TraitRef::new(
tcx.lang_items().coerce_unsized_trait().unwrap(),
coerce_unsized_trait_did,
tcx.mk_substs_trait(src_ty, &[tgt_ty.into()]),
)
.to_poly_trait_ref(),
Expand All @@ -120,12 +123,14 @@ fn check_unsize_coercion<'tcx>(
trait_ref.to_poly_trait_predicate(),
));
if let Ok(Some(vtable)) = select_result {
// we only care about trait predicates
// we only care about trait predicates for these traits
let traits = [coerce_unsized_trait_did, unsize_trait_did];
queue.extend(
vtable
.nested_obligations()
.into_iter()
.filter_map(|oblig| oblig.predicate.to_opt_poly_trait_ref()),
.filter_map(|oblig| oblig.predicate.to_opt_poly_trait_ref())
.filter(|tr| traits.contains(&tr.def_id())),
);
}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/any_coerce.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ struct Unsizeable<T: ?Sized, U: ?Sized, V: ?Sized> {
}

fn main() {
let mut box_any: Box<dyn Any> = Box::new(Foo);
let mut box_any: Box<dyn Any + Send> = Box::new(Foo);
let _: *mut dyn Any = &mut box_any; // LINT
let _: *mut dyn Any = &mut *box_any; // ok

Expand Down

0 comments on commit babfbde

Please sign in to comment.