File tree 3 files changed +44
-1
lines changed
compiler/rustc_trait_selection/src/traits
3 files changed +44
-1
lines changed Original file line number Diff line number Diff line change @@ -734,7 +734,21 @@ impl<'tcx> TypeVisitor<'tcx> for OrphanChecker<'tcx> {
734
734
result
735
735
}
736
736
737
- // FIXME: Constants should participate in orphan checking.
737
+ /// All possible values for a constant parameter already exist
738
+ /// in the crate defining the trait, so they are always non-local[^1].
739
+ ///
740
+ /// Because there's no way to have an impl where the first local
741
+ /// generic argument is a constant, we also don't have to fail
742
+ /// the orphan check when encountering a parameter or a generic constant.
743
+ ///
744
+ /// This means that we can completely ignore constants during the orphan check.
745
+ ///
746
+ /// See `src/test/ui/coherence/const-generics-orphan-check-ok.rs` for examples.
747
+ ///
748
+ /// [^1]: This might not hold for function pointers or trait objects in the future.
749
+ /// As these should be quite rare as const arguments and especially rare as impl
750
+ /// parameters, allowing uncovered const parameters in impls seems more useful
751
+ /// than allowing `impl<T> Trait<local_fn_ptr, T> for i32` to compile.
738
752
fn visit_const ( & mut self , _c : ty:: Const < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
739
753
ControlFlow :: CONTINUE
740
754
}
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