From 476ea9ef1c0ba7250e369a2ec7205506b09474b7 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 13 May 2019 01:37:04 -0400 Subject: Always try to project predicates when finding auto traits in rustdoc Fixes #60726 Previous, AutoTraitFinder would only try to project predicates when the predicate type contained an inference variable. When finding auto traits, we only project to try to unify inference variables - we don't otherwise learn any new information about the required bounds. However, this lead to failing to properly generate a negative auto trait impl (indicating that a type never implements a certain auto trait) in the following unusual scenario: In almost all cases, a type has an (implicit) negative impl of an auto trait due some other type having an explicit *negative* impl of that auto trait. For example: struct MyType { field: *const T } has an implicit 'impl !Send for MyType', due to the explicit negative impl (in libcore) 'impl !Send for *const T'. However, as exposed by the 'abi_stable' crate, this isn't always the case. This minimzed example shows how a type can never implement 'Send', due to a projection error: ``` pub struct True; pub struct False; pub trait MyTrait { type Project; } pub struct MyStruct { field: T } impl MyTrait for u8 { type Project = False; } unsafe impl Send for MyStruct where T: MyTrait {} pub struct Wrapper { inner: MyStruct } ``` In this example, `::Project == True' must hold for 'MyStruct: Send' to hold. However, '::Project == False' holds instead To properly account for this unusual case, we need to call 'poly_project_and_unify' on *all* predicates, not just those with inference variables. This ensures that we catch the projection error that occurs above, and don't incorrectly determine that 'Wrapper: Send' holds. --- src/test/rustdoc/issue-60726.rs | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/test/rustdoc/issue-60726.rs (limited to 'src/test/rustdoc') diff --git a/src/test/rustdoc/issue-60726.rs b/src/test/rustdoc/issue-60726.rs new file mode 100644 index 00000000000..6acc8627738 --- /dev/null +++ b/src/test/rustdoc/issue-60726.rs @@ -0,0 +1,35 @@ +use std::marker::PhantomData; + +pub struct True; +pub struct False; + +pub trait InterfaceType{ + type Send; +} + + +pub struct FooInterface(PhantomDataT>); + +impl InterfaceType for FooInterface { + type Send=False; +} + + +pub struct DynTrait{ + _interface:PhantomDataI>, + _unsync_unsend:PhantomData<::std::rc::Rc<()>>, +} + +unsafe impl Send for DynTrait +where + I:InterfaceType +{} + +// @has issue_60726/struct.IntoIter.html +// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl !Send for \ +// IntoIter" +// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl !Sync for \ +// IntoIter" +pub struct IntoIter{ + hello:DynTrait>, +} -- cgit 1.4.1-3-g733a5