Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
}
}

pub(crate) fn visit_with<V: ProofTreeVisitor<'tcx>>(&self, visitor: &mut V) -> V::Result {
pub fn visit_with<V: ProofTreeVisitor<'tcx>>(&self, visitor: &mut V) -> V::Result {
if self.depth < visitor.config().max_depth {
try_visit!(visitor.visit_goal(self));
}
Expand Down
822 changes: 0 additions & 822 deletions compiler/rustc_trait_selection/src/traits/auto_trait.rs

This file was deleted.

2 changes: 0 additions & 2 deletions compiler/rustc_trait_selection/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
//!
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/resolution.html

pub mod auto_trait;
pub(crate) mod coherence;
pub mod const_evaluatable;
mod dyn_compatibility;
Expand Down Expand Up @@ -71,7 +70,6 @@ pub use self::util::{
upcast_choices, with_replaced_escaping_bound_vars,
};
use crate::error_reporting::InferCtxtErrorExt;
use crate::infer::outlives::env::OutlivesEnvironment;
use crate::infer::{InferCtxt, TyCtxtInferExt};
use crate::regions::InferCtxtRegionExt;
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
Expand Down
547 changes: 468 additions & 79 deletions src/librustdoc/clean/auto_trait.rs

Large diffs are not rendered by default.

42 changes: 26 additions & 16 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,14 +271,11 @@ fn clean_poly_trait_ref_with_constraints<'tcx>(
cx: &mut DocContext<'tcx>,
poly_trait_ref: ty::PolyTraitRef<'tcx>,
constraints: ThinVec<AssocItemConstraint>,
) -> GenericBound {
GenericBound::TraitBound(
PolyTrait {
trait_: clean_trait_ref_with_constraints(cx, poly_trait_ref, constraints),
generic_params: clean_bound_vars(poly_trait_ref.bound_vars(), cx),
},
hir::TraitBoundModifiers::NONE,
)
) -> PolyTrait {
PolyTrait {
trait_: clean_trait_ref_with_constraints(cx, poly_trait_ref, constraints),
generic_params: clean_bound_vars(poly_trait_ref.bound_vars(), cx),
}
}

fn clean_lifetime(lifetime: &hir::Lifetime, cx: &DocContext<'_>) -> Lifetime {
Expand Down Expand Up @@ -403,16 +400,28 @@ fn clean_poly_trait_predicate<'tcx>(
) -> Option<WherePredicate> {
// `T: [const] Destruct` is hidden because `T: Destruct` is a no-op.
// FIXME(const_trait_impl) check constness
if Some(pred.skip_binder().def_id()) == cx.tcx.lang_items().destruct_trait() {
if Some(pred.def_id()) == cx.tcx.lang_items().destruct_trait() {
return None;
}

let poly_trait_ref = pred.map_bound(|pred| pred.trait_ref);
Some(WherePredicate::BoundPredicate {
ty: clean_middle_ty(poly_trait_ref.self_ty(), cx, None, None),
bounds: vec![clean_poly_trait_ref_with_constraints(cx, poly_trait_ref, ThinVec::new())],
bound_params: Vec::new(),
})
let trait_ref = pred.map_bound(|pred| pred.trait_ref);

let ty = clean_middle_ty(trait_ref.self_ty(), cx, None, None);

let bound = GenericBound::TraitBound(
clean_poly_trait_ref_with_constraints(cx, trait_ref, ThinVec::new()),
hir::TraitBoundModifiers {
polarity: match pred.polarity() {
ty::PredicatePolarity::Positive => hir::BoundPolarity::Positive,
ty::PredicatePolarity::Negative => {
rustc_ast::BoundPolarity::Negative(rustc_span::DUMMY_SP)
}
},
constness: hir::BoundConstness::Never,
},
);

Some(WherePredicate::BoundPredicate { ty, bounds: vec![bound], bound_params: Vec::new() })
}

fn clean_region_outlives_predicate<'tcx>(
Expand Down Expand Up @@ -2316,7 +2325,8 @@ fn clean_middle_opaque_bounds<'tcx>(
})
.collect();

Some(clean_poly_trait_ref_with_constraints(cx, trait_ref, bindings))
let trait_ref = clean_poly_trait_ref_with_constraints(cx, trait_ref, bindings);
Some(GenericBound::TraitBound(trait_ref, hir::TraitBoundModifiers::NONE))
})
.collect::<Vec<_>>();

Expand Down
162 changes: 162 additions & 0 deletions t.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
#![feature(auto_traits, negative_impls)]

pub auto trait Marker {}

// pub struct Outer<T>(Inner<T>);
// struct Inner<T>(T);

// pub struct Compound {
// f0: i32,
// f1: u32,
// }

// pub struct Compound<T> {
// f0: i32,
// f1: Wrap<T>,
// // f1: T,
// }

// pub struct Wrap<T>(T);

// impl<T: Copy> Marker for Wrap<T> {}

// [[next]] no explicit impl found
// [[next]] (G) Err(NoSolution) Misc #C=1 for[] TraitPredicate(<Compound<T> as Marker>, polarity:Positive)
// [[next]] (C#0) Err(NoSolution) TraitCandidate/BuiltinImpl(Misc)
// [[next]] (G) Ok(Yes) ImplWhereBound #C=1 for[] TraitPredicate(<i32 as Marker>, polarity:Positive)
// [[next]] (C#0) Ok(Yes) TraitCandidate/BuiltinImpl(Misc)
// [[next]] (G) Err(NoSolution) ImplWhereBound #C=1 for[] TraitPredicate(<Wrap<T> as Marker>, polarity:Positive)
// [[next]] (C#0) Err(NoSolution) TraitCandidate/Impl(DefId(0:12 ~ t[6e8d]::{impl#0}))
// [[next]] (G) Ok(Yes) ImplWhereBound #C=1 for[] TraitPredicate(<T as std::marker::Sized>, polarity:Positive)
// [[next]] (C#0) Ok(Yes) TraitCandidate/ParamEnv(NonGlobal)
// [[next]] (G) Err(NoSolution) ImplWhereBound #C=0 for[] TraitPredicate(<T as std::marker::Copy>, polarity:Positive)

// pub struct Compound {
// f0: NonMarker,
// }

// struct NonMarker;
// impl !Marker for NonMarker {}

//////////7

// pub struct Outer<T>(Inner<T>);
// struct Inner<T>(T);

// impl<T, U> Marker for Inner<T>
// where
// T: Iterator<Item = U>,
// U: Copy,
// {}

// FIXME: Negative
// impl<T> Marker for Inner<T>
// where
// // // NOTE: Can be arbitrarily deeply nested
// // T: Iterator<Item: Copy>,
// T: Iterator<Item: Iterator<Item = ()>>
// T: Iterator<Item = ()>,
// {}

//
// impl<T, X> Marker for Inner<T>
// where
// T: Iterator<Item = X>,
// (X,): Copy, // FIXME: dropped
// {}

// impl<'a, T, const N: usize> Marker for Inner<T>
// where
// T: Iterator<Item = [&'a (); N]>,
// {}

// impl<T: !Copy> Marker for Inner<T> {}

// impl<T> Marker for Inner<T>
// where
// T: const std::default::Default,
// {}

// impl<T> const Marker for Inner<T>
// where
// T: [const] std::default::Default,
// {}

// impl<T> !Marker for Inner<T> {}
// impl<T> Marker for Inner<T>
// where
// // T: Copy
// [T; 1 + 2]:
// {}

// pub trait Bound {}

// impl<T> Bound for T {}

// impl<X, Y> Marker for Inner<(X, Y)> {}

// impl<T: Iterator<Item = String>> Marker for Inner<T> {}
// impl<T: Iterator<Item: Copy>> Marker for Inner<T> {}

// pub trait Bound {}
// impl<T: Copy + std::fmt::Debug + Bound> Marker for Inner<T> {}
// impl Marker for Inner<&'static str> {}

///////////// for<>fnptr-ICE //////////////

// pub struct Outer<'a>(Local<fn(&'a ())>);

// struct Local<T>(T);

// impl Marker for Local<for<'a> fn(&'a ())> {}

///////////

// pub struct Outer<'a>(Inner<'a>);
// struct Inner<'a>(&'a ());

// impl Marker for Inner<'static> {}

///////////////// ConstEvaluatable

// pub struct Hold<const N: u8>;

// pub struct Outer<const N: u8>(Inner<N>);
// struct Inner<const N: u8>;

// impl<const N: u8> Marker for Inner<N>
// where
// Hold<{ N + 1 }>:
// {}

// pub struct Type<T>(Opaque<T>);

// type Opaque<T> = impl Sized;

// #[define_opaque(Opaque)] fn define<T>(x: T) -> Opaque<T> { Wrap(x) }

// pub struct Wrap<T>(T);

// impl<T: Copy> Marker for Wrap<T> {}

// impl !Marker for () {}
//

//////// XXX outlives-preds (BUG!)

// pub struct Outer<'a, T: 'a>(Inner<'a, T>);
// struct Inner<'a, T: 'a>(&'a T);

// impl<'a, T> Marker for Inner<'a, T>
// where
// 'a: 'static,
// // T: Bound<'a>, // [!]
// {}

// pub trait Bound<'a> {}

///////////

pub struct Outer<T>(Inner<T>);
type Inner<T> = impl Sized; #[define_opaque(Inner)] fn define<T>() -> Inner<T> {}

125 changes: 125 additions & 0 deletions tests/rustdoc/synthetic-auto/projections.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
// FIXME(fmease): Early mock-up. Expectations are temporary.
#![crate_name = "it"]

pub struct Outer<T>(Inner<T>);
struct Inner<T>(T);

//@ has it/struct.Outer.html \
// '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//*[@class="code-header"]' \
// "impl<T> Unpin for Outer<T>where T: Iterator<Item = ()>"

impl<T> Unpin for Inner<T>
where
T: Iterator<Item = ()>
{}

// FIXME: Nicer name for the synthetic param.
//@ has it/struct.Outer.html \
// '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//*[@class="code-header"]' \
// "impl<T, X0> UnwindSafe for Outer<T>where T: Iterator<Item = X0>"

impl<T, U> std::panic::UnwindSafe for Inner<T>
where
T: Iterator<Item = U>
{}

// FIXME: Nicer name for the synthetic param.
//@ has it/struct.Outer.html \
// '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//*[@class="code-header"]' \
// "impl<T, X0> Send for Outer<T>\
// where \
// T: Iterator<Item = X0>, \
// X0: Copy"

unsafe impl<T, U> Send for Inner<T>
where
T: Iterator<Item = U>,
U: Copy,
{}

// FIXME: Nicer name for the synthetic param.
// FIXME: Ugly + superfluous `?Sized` bound.
//@ has it/struct.Outer.html \
// '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//*[@class="code-header"]' \
// "impl<T, X0> Sync for Outer<T>\
// where \
// T: Iterator<Item = X0>, \
// X0: Copy + ?Sized"

unsafe impl<T> Sync for Inner<T>
where
T: Iterator<Item: Copy>
{}

// FIXME: Utter downfall, bound vomit
//@ has it/struct.Outer.html \
// '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//*[@class="code-header"]' \
// "impl<T, X0, X1, X2> RefUnwindSafe for Outer<T>\
// where \
// T: Iterator<Item = X0, Item = X2>, \
// X2: Iterator + ?Sized, \
// X0: ?Sized, \
// <X0 as Iterator>::Item == X1"

impl<T, U> std::panic::RefUnwindSafe for Inner<T>
where
T: Iterator<Item: Iterator<Item = U>>
{}

/* TREE:
(G) Err(NoSolution) Misc for[] TraitPredicate(<Outer<T> as std::panic::RefUnwindSafe>, polarity:Positive)
(C) Err(NoSolution) TraitCandidate/BuiltinImpl(Misc)
(G) Err(NoSolution) ImplWhereBound for[] TraitPredicate(<Inner<T> as std::panic::RefUnwindSafe>, polarity:Positive)
(C) Err(NoSolution) TraitCandidate/Impl(DefId(0:21 ~ it[c9cb]::{impl#4}))
(G) Err(NoSolution) NormalizeGoal(Coinductive) for[] AliasRelate(Term::Ty(Alias(Projection, AliasTy { args: [T/#0], def_id: DefId(2:9696 ~ core[efc6]::iter::traits::iterator::Iterator::Item), .. })), Equate, Term::Ty(?2t))
(C) Err(NoSolution) Root { result: Err(NoSolution) }
(G) Err(NoSolution) TypeRelating for[] NormalizesTo(AliasTerm { args: [T/#0], def_id: DefId(2:9696 ~ core[efc6]::iter::traits::iterator::Iterator::Item), .. }, Term::Ty(?31t))
(G) Ok(Maybe { cause: Ambiguity, opaque_types_jank: AllGood }) ImplWhereBound for[] ProjectionPredicate(AliasTerm { args: [?2t], def_id: DefId(2:9696 ~ core[efc6]::iter::traits::iterator::Iterator::Item), .. }, Term::Ty(?1t))
(C) Ok(Maybe { cause: Ambiguity, opaque_types_jank: AllGood }) Root { result: Ok(Canonical { value: Response { certainty: Maybe { cause: Ambiguity, opaque_types_jank: AllGood }, var_values: CanonicalVarValues { var_values: [^c_0, ^c_1, ^c_2] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: [], opaque_types: [], normalization_nested_goals: NestedNormalizationGoals([]) }) }, max_universe: U0, variables: [PlaceholderTy(!0), Ty { ui: U0, sub_root: 1 }, Ty { ui: U0, sub_root: 2 }] }) }
(G) Ok(Maybe { cause: Ambiguity, opaque_types_jank: AllGood }) TypeRelating for[] AliasRelate(Term::Ty(Alias(Projection, AliasTy { args: [?2t], def_id: DefId(2:9696 ~ core[efc6]::iter::traits::iterator::Iterator::Item), .. })), Equate, Term::Ty(?1t))
(C) Ok(Maybe { cause: Ambiguity, opaque_types_jank: AllGood }) Root { result: Ok(Canonical { value: Response { certainty: Maybe { cause: Ambiguity, opaque_types_jank: AllGood }, var_values: CanonicalVarValues { var_values: [^c_0, ^c_1, ^c_2] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: [], opaque_types: [], normalization_nested_goals: NestedNormalizationGoals([]) }) }, max_universe: U0, variables: [PlaceholderTy(!0), Ty { ui: U0, sub_root: 1 }, Ty { ui: U0, sub_root: 2 }] }) }
(G) Ok(Maybe { cause: Ambiguity, opaque_types_jank: AllGood }) TypeRelating for[] NormalizesTo(AliasTerm { args: [?2t], def_id: DefId(2:9696 ~ core[efc6]::iter::traits::iterator::Iterator::Item), .. }, Term::Ty(?36t))
(C) Ok(Maybe { cause: Ambiguity, opaque_types_jank: AllGood }) TraitCandidate/BuiltinImpl(Misc)
(G) Ok(Maybe { cause: Ambiguity, opaque_types_jank: AllGood }) ImplWhereBound for[] TraitPredicate(<_ as std::marker::Sized>, polarity:Positive)
(C) Ok(Maybe { cause: Ambiguity, opaque_types_jank: AllGood }) TraitCandidate/BuiltinImpl(Misc)
(G) Err(NoSolution) ImplWhereBound for[] TraitPredicate(<T as std::iter::Iterator>, polarity:Positive)
(G) Err(NoSolution) NormalizeGoal(Coinductive) for[] AliasRelate(Term::Ty(Alias(Projection, AliasTy { args: [T/#0], def_id: DefId(2:9696 ~ core[efc6]::iter::traits::iterator::Iterator::Item), .. })), Equate, Term::Ty(?11t))
(C) Err(NoSolution) Root { result: Err(NoSolution) }
(G) Err(NoSolution) TypeRelating for[] NormalizesTo(AliasTerm { args: [T/#0], def_id: DefId(2:9696 ~ core[efc6]::iter::traits::iterator::Iterator::Item), .. }, Term::Ty(?31t))
(G) Ok(Maybe { cause: Ambiguity, opaque_types_jank: AllGood }) ImplWhereBound for[] TraitPredicate(<_ as std::iter::Iterator>, polarity:Positive)
(C) Ok(Maybe { cause: Ambiguity, opaque_types_jank: AllGood }) TraitCandidate/BuiltinImpl(Misc)
(G) Ok(Yes) ImplWhereBound for[] TraitPredicate(<T as std::marker::Sized>, polarity:Positive)
(C) Ok(Yes) TraitCandidate/ParamEnv(NonGlobal)
*/
/* RESULT:
Binder { value: ProjectionPredicate(AliasTerm { args: [T/#0], def_id: DefId(2:9696 ~ core[efc6]::iter::traits::iterator::Iterator::Item), .. }, Term::Ty(?2t)), bound_vars: [] },
Binder { value: ProjectionPredicate(AliasTerm { args: [?2t], def_id: DefId(2:9696 ~ core[efc6]::iter::traits::iterator::Iterator::Item), .. }, Term::Ty(?1t)), bound_vars: [] },
Binder { value: TraitPredicate(<_ as std::marker::Sized>, polarity:Positive), bound_vars: [] },
Binder { value: TraitPredicate(<T as std::iter::Iterator>, polarity:Positive), bound_vars: [] },
Binder { value: ProjectionPredicate(AliasTerm { args: [T/#0], def_id: DefId(2:9696 ~ core[efc6]::iter::traits::iterator::Iterator::Item), .. }, Term::Ty(?11t)), bound_vars: [] },
Binder { value: TraitPredicate(<_ as std::iter::Iterator>, polarity:Positive), bound_vars: [] },
Binder { value: TraitPredicate(<T as std::marker::Sized>, polarity:Positive), bound_vars: [] },
*/

//////////////////////////////////////////////////////////////

pub struct Extern<T>(Intern<T>);
struct Intern<T>(T);

// FIXME: Well, some improvmenets can&should be done in clean/mod, resugaring more eq preds.

//@ has it/struct.Extern.html \
// '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//*[@class="code-header"]' \
// "impl<T, X0> Unpin for Extern<T>\
// where \
// T: Trait, \
// X0: Copy + ?Sized, \
// <<T as Trait>::Assoc as Trait>::Assoc == X0,"

impl<T> Unpin for Intern<T>
where
T: Trait,
<T::Assoc as Trait>::Assoc: Copy,
{}

trait Trait { type Assoc: Trait; }
19 changes: 19 additions & 0 deletions tests/rustdoc/synthetic-auto/region-universe-mismatch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// issue: <https://github.com/rust-lang/rust/issues/123298>
#![crate_name = "it"]

// Constituent type `<'a> Inner<fn(&'a ())>` doesn't impl `Unpin` since user impl
// candidate `Inner<for<'a> fn(&'a ())>` is less general (the universes don't match).
//
//@ has it/struct.Outer.html \
// '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//*[@class="code-header"]' \
// "impl<'a> !Unpin for Outer<'a>"
pub struct Outer<'a>(Inner<fn(&'a ())>);

struct Inner<T>(T);
impl Unpin for Inner<for<'a> fn(&'a ())> {}

// Trivial counterexample: Here, everything matches perfectly.
//@ has it/struct.Wrap.html \
// '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//*[@class="code-header"]' \
// "impl Unpin for Wrap"
pub struct Wrap(Inner<for<'a> fn(&'a ())>);
Loading
Loading