File tree Expand file tree Collapse file tree 3 files changed +39
-1
lines changed
compiler/rustc_trait_selection/src/traits Expand file tree Collapse file tree 3 files changed +39
-1
lines changed Original file line number Diff line number Diff line change @@ -746,8 +746,17 @@ impl<'tcx> TypeVisitor<'tcx> for OrphanChecker<'tcx> {
746746 result
747747 }
748748
749- // FIXME: Constants should participate in orphan checking.
750749 fn visit_const ( & mut self , _c : ty:: Const < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
750+ // All possible values for a constant parameter already exist
751+ // in the crate defining the trait, so they are always non-local.
752+ //
753+ // Because there's no way to have an impl where the first local
754+ // generic argument is a constant, we also don't have to fail
755+ // the orphan check when encountering a parameter or a generic constant.
756+ //
757+ // This means that we can completely ignore constants during the orphan check.
758+ //
759+ // See `src/test/ui/coherence/const-generics-orphan-check-ok.rs` for examples.
751760 ControlFlow :: CONTINUE
752761 }
753762}
Original file line number Diff line number Diff line change 1+ pub trait Trait < const N : usize , T > { }
Original file line number Diff line number Diff line change 1+ // check-pass
2+ // aux-build:trait-with-const-param.rs
3+ extern crate trait_with_const_param;
4+ use trait_with_const_param:: * ;
5+
6+ // Trivial case, const param after local type.
7+ struct Local1 ;
8+ impl < const N : usize , T > Trait < N , T > for Local1 { }
9+
10+ // Concrete consts behave the same as foreign types,
11+ // so this also trivially works.
12+ impl Trait < 3 , Local1 > for i32 { }
13+
14+ // This case isn't as trivial as we would forbid type
15+ // parameters here, we do allow const parameters though.
16+ //
17+ // The reason that type parameters are forbidden for
18+ // `impl<T> Trait<T, LocalInA> for i32 {}` is that another
19+ // downstream crate can add `impl<T> Trait<LocalInB, T> for i32`.
20+ // As these two impls would overlap we forbid any impls which
21+ // have a type parameter in front of a local type.
22+ //
23+ // With const parameters this issue does not exist as there are no
24+ // constants local to another downstream crate.
25+ struct Local2 ;
26+ impl < const N : usize > Trait < N , Local2 > for i32 { }
27+
28+ fn main ( ) { }
You can’t perform that action at this time.
0 commit comments