orphan check: remove const generics fixme

This commit is contained in:
lcnr 2022-07-28 17:30:39 +02:00
parent 05e678ccca
commit c9b21b0ea2
3 changed files with 39 additions and 1 deletions

View File

@ -746,8 +746,17 @@ impl<'tcx> TypeVisitor<'tcx> for OrphanChecker<'tcx> {
result
}
// FIXME: Constants should participate in orphan checking.
fn visit_const(&mut self, _c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
// All possible values for a constant parameter already exist
// in the crate defining the trait, so they are always non-local.
//
// Because there's no way to have an impl where the first local
// generic argument is a constant, we also don't have to fail
// the orphan check when encountering a parameter or a generic constant.
//
// This means that we can completely ignore constants during the orphan check.
//
// See `src/test/ui/coherence/const-generics-orphan-check-ok.rs` for examples.
ControlFlow::CONTINUE
}
}

View File

@ -0,0 +1 @@
pub trait Trait<const N: usize, T> {}

View File

@ -0,0 +1,28 @@
// check-pass
// aux-build:trait-with-const-param.rs
extern crate trait_with_const_param;
use trait_with_const_param::*;
// Trivial case, const param after local type.
struct Local1;
impl<const N: usize, T> Trait<N, T> for Local1 {}
// Concrete consts behave the same as foreign types,
// so this also trivially works.
impl Trait<3, Local1> for i32 {}
// This case isn't as trivial as we would forbid type
// parameters here, we do allow const parameters though.
//
// The reason that type parameters are forbidden for
// `impl<T> Trait<T, LocalInA> for i32 {}` is that another
// downstream crate can add `impl<T> Trait<LocalInB, T> for i32`.
// As these two impls would overlap we forbid any impls which
// have a type parameter in front of a local type.
//
// With const parameters this issue does not exist as there are no
// constants local to another downstream crate.
struct Local2;
impl<const N: usize> Trait<N, Local2> for i32 {}
fn main() {}