Auto merge of #125671 - BoxyUwU:remove_const_ty_eq, r=compiler-errors
Do not equate `Const`'s ty in `super_combine_const` Fixes #114456 In #125451 we started relating the `Const`'s tys outside of a probe so it was no longer simply an assertion to catch bugs. This was done so that when we _do_ provide a wrongly typed const argument to an item if we wind up relating it with some other instantiation we'll have a `TypeError` we can bubble up and taint the resulting mir allowing const eval to skip evaluation. In this PR I instead change `ConstArgHasType` to correctly handle checking the types of const inference variables. Previously if we had something like `impl<const N: u32> Trait for [(); N]`, when using the impl we would instantiate it with infer vars and then check that `?x: u32` is of type `u32` and succeed. Then later we would infer `?x` to some `Const` of type `usize`. We now stall on `?x` in `ConstArgHasType` until it has a concrete value that we can determine the type of. This allows us to fail using the erroneous implementation of `Trait` which allows us to taint the mir. Long term we intend to remove the `ty` field on `Const` so we would have no way of accessing the `ty` of a const inference variable anyway and would have to do this. I did not fully update `ConstArgHasType` to avoid using the `ty` field as it's not entirely possible right now- we would need to lookup `ConstArgHasType` candidates in the env. --- As for _why_ I think we should do this, relating the types of const's is not necessary for soundness of the type system. Originally this check started off as a plain `==` in `super_relate_consts` and gradually has been growing in complexity as we support more complicated types. It was never actually required to ensure that const arguments are correctly typed for their parameters however. The way we currently check that a const argument has the correct type is a little convoluted and confusing (and will hopefully be less weird as time goes on). Every const argument has an anon const with its return type set to type of the const parameter it is an argument to. When type checking the anon const regular type checking rules require that the expression is the same type as the return type. This effectively ensure that no matter what every const argument _always_ has the correct type. An extra bit of complexity is that during `hir_ty_lowering` we do not represent everything as a `ConstKind::Unevaluated` corresponding to the anon const. For generic parameters i.e. `[(); N]` we simply represent them as `ConstKind::Param` as we do not want `ConstKind::Unevaluated` with generic substs on stable under min const generics. The anon const still gets type checked resulting in errors about type mismatches. Eventually we intend to not create anon consts for all const arguments (for example for `ConstKind::Param`) and instead check that the argument type is correct via `ConstArgHasType` obligations (these effectively also act as a check that the anon consts have the correctly set return type). What this all means is that the the only time we should ever have mismatched types when relating two `Const`s is if we have messed up our logic for ensuring that const arguments are of the correct type. Having this not be an assert is: - Confusing as it may incorrectly lead people to believe this is an important check that is actually required - Opens the possibility for bugs or behaviour reliant on this (unnecessary) check existing --- This PR makes two tests go from pass->ICE (`generic_const_exprs/ice-125520-layout-mismatch-mulwithoverflow.rs` and `tests/crashes/121858.rs`). This is caused by the fact that we evaluate anon consts even if their where clauses do not hold and is a pre-existing issue and only affects `generic_const_exprs`. I am comfortable exposing the brokenness of `generic_const_exprs` more with this PR This PR makes a test go from ICE->pass (`const-generics/issues/issue-105821.rs`). I have no idea why this PR affects that but I believe that ICE is an unrelated issue to do with the fact that under `generic_const_exprs`/`adt_const_params` we do not handle lifetimes in const parameter types correctly. This PR is likely just masking this bug. Note: this PR doesn't re-introduce the assertion that the two consts' tys are equal. I'm not really sure how I feel about this but tbh it has caused more ICEs than its found lately so 🤷♀️ r? `@oli-obk` `@compiler-errors`
This commit is contained in:
commit
32a3ed229c
30 changed files with 206 additions and 327 deletions
|
@ -22,11 +22,10 @@ use super::glb::Glb;
|
||||||
use super::lub::Lub;
|
use super::lub::Lub;
|
||||||
use super::type_relating::TypeRelating;
|
use super::type_relating::TypeRelating;
|
||||||
use super::StructurallyRelateAliases;
|
use super::StructurallyRelateAliases;
|
||||||
use crate::infer::{DefineOpaqueTypes, InferCtxt, InferOk, TypeTrace};
|
use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace};
|
||||||
use crate::traits::{Obligation, PredicateObligations};
|
use crate::traits::{Obligation, PredicateObligations};
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::infer::unify_key::EffectVarValue;
|
use rustc_middle::infer::unify_key::EffectVarValue;
|
||||||
use rustc_middle::traits::ObligationCause;
|
|
||||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||||
use rustc_middle::ty::relate::{RelateResult, TypeRelation};
|
use rustc_middle::ty::relate::{RelateResult, TypeRelation};
|
||||||
use rustc_middle::ty::{self, InferConst, Ty, TyCtxt, TypeVisitableExt, Upcast};
|
use rustc_middle::ty::{self, InferConst, Ty, TyCtxt, TypeVisitableExt, Upcast};
|
||||||
|
@ -170,12 +169,6 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
let a = self.shallow_resolve_const(a);
|
let a = self.shallow_resolve_const(a);
|
||||||
let b = self.shallow_resolve_const(b);
|
let b = self.shallow_resolve_const(b);
|
||||||
|
|
||||||
// It is always an error if the types of two constants that are related are not equal.
|
|
||||||
let InferOk { value: (), obligations } = self
|
|
||||||
.at(&ObligationCause::dummy_with_span(relation.span()), relation.param_env())
|
|
||||||
.eq(DefineOpaqueTypes::No, a.ty(), b.ty())?;
|
|
||||||
relation.register_obligations(obligations);
|
|
||||||
|
|
||||||
match (a.kind(), b.kind()) {
|
match (a.kind(), b.kind()) {
|
||||||
(
|
(
|
||||||
ty::ConstKind::Infer(InferConst::Var(a_vid)),
|
ty::ConstKind::Infer(InferConst::Var(a_vid)),
|
||||||
|
|
|
@ -197,9 +197,31 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
|
||||||
goal: Goal<'tcx, (ty::Const<'tcx>, Ty<'tcx>)>,
|
goal: Goal<'tcx, (ty::Const<'tcx>, Ty<'tcx>)>,
|
||||||
) -> QueryResult<'tcx> {
|
) -> QueryResult<'tcx> {
|
||||||
let (ct, ty) = goal.predicate;
|
let (ct, ty) = goal.predicate;
|
||||||
|
|
||||||
|
// FIXME(BoxyUwU): Really we should not be calling `ct.ty()` for any variant
|
||||||
|
// other than `ConstKind::Value`. Unfortunately this would require looking in the
|
||||||
|
// env for any `ConstArgHasType` assumptions for parameters and placeholders. I
|
||||||
|
// have not yet gotten around to implementing this though.
|
||||||
|
//
|
||||||
|
// We do still stall on infer vars though as otherwise a goal like:
|
||||||
|
// `ConstArgHasType(?x: usize, usize)` can succeed even though it might later
|
||||||
|
// get unified with some const that is not of type `usize`.
|
||||||
|
match ct.kind() {
|
||||||
|
// FIXME: Ignore effect vars because canonicalization doesn't handle them correctly
|
||||||
|
// and if we stall on the var then we wind up creating ambiguity errors in a probe
|
||||||
|
// for this goal which contains an effect var. Which then ends up ICEing.
|
||||||
|
ty::ConstKind::Infer(ty::InferConst::Var(_)) => {
|
||||||
|
self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
|
||||||
|
}
|
||||||
|
ty::ConstKind::Error(_) => {
|
||||||
|
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
self.eq(goal.param_env, ct.ty(), ty)?;
|
self.eq(goal.param_env, ct.ty(), ty)?;
|
||||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||||
|
|
|
@ -2685,6 +2685,22 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
.with_span_label(span, format!("cannot satisfy `{predicate}`"))
|
.with_span_label(span, format!("cannot satisfy `{predicate}`"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Given some `ConstArgHasType(?x, usize)`, we should not emit an error such as
|
||||||
|
// "type annotations needed: cannot satisfy the constant `_` has type `usize`"
|
||||||
|
// Instead we should emit a normal error suggesting the user to turbofish the
|
||||||
|
// const parameter that is currently being inferred. Unfortunately we cannot
|
||||||
|
// nicely emit such an error so we delay an ICE incase nobody else reports it
|
||||||
|
// for us.
|
||||||
|
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
|
||||||
|
return self.tcx.sess.dcx().span_delayed_bug(
|
||||||
|
span,
|
||||||
|
format!(
|
||||||
|
"`ambiguous ConstArgHasType({:?}, {:?}) unaccompanied by inference error`",
|
||||||
|
ct, ty
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if let Some(e) = self.tainted_by_errors() {
|
if let Some(e) = self.tainted_by_errors() {
|
||||||
return e;
|
return e;
|
||||||
|
|
|
@ -429,18 +429,39 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
||||||
// This is because this is not ever a useful obligation to report
|
// This is because this is not ever a useful obligation to report
|
||||||
// as the cause of an overflow.
|
// as the cause of an overflow.
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
|
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
|
||||||
|
// FIXME(BoxyUwU): Really we should not be calling `ct.ty()` for any variant
|
||||||
|
// other than `ConstKind::Value`. Unfortunately this would require looking in the
|
||||||
|
// env for any `ConstArgHasType` assumptions for parameters and placeholders. I
|
||||||
|
// don't really want to implement this in the old solver so I haven't.
|
||||||
|
//
|
||||||
|
// We do still stall on infer vars though as otherwise a goal like:
|
||||||
|
// `ConstArgHasType(?x: usize, usize)` can succeed even though it might later
|
||||||
|
// get unified with some const that is not of type `usize`.
|
||||||
|
let ct = self.selcx.infcx.shallow_resolve_const(ct);
|
||||||
|
match ct.kind() {
|
||||||
|
ty::ConstKind::Infer(ty::InferConst::Var(vid)) => {
|
||||||
|
pending_obligation.stalled_on.clear();
|
||||||
|
pending_obligation.stalled_on.extend([TyOrConstInferVar::Const(vid)]);
|
||||||
|
ProcessResult::Unchanged
|
||||||
|
}
|
||||||
|
ty::ConstKind::Error(_) => return ProcessResult::Changed(vec![]),
|
||||||
|
_ => {
|
||||||
match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq(
|
match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq(
|
||||||
// Only really excercised by generic_const_exprs
|
// Only really excercised by generic_const_exprs
|
||||||
DefineOpaqueTypes::Yes,
|
DefineOpaqueTypes::Yes,
|
||||||
ct.ty(),
|
ct.ty(),
|
||||||
ty,
|
ty,
|
||||||
) {
|
) {
|
||||||
Ok(inf_ok) => ProcessResult::Changed(mk_pending(inf_ok.into_obligations())),
|
Ok(inf_ok) => {
|
||||||
|
ProcessResult::Changed(mk_pending(inf_ok.into_obligations()))
|
||||||
|
}
|
||||||
Err(_) => ProcessResult::Error(FulfillmentErrorCode::Select(
|
Err(_) => ProcessResult::Error(FulfillmentErrorCode::Select(
|
||||||
SelectionError::Unimplemented,
|
SelectionError::Unimplemented,
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// General case overflow check. Allow `process_trait_obligation`
|
// General case overflow check. Allow `process_trait_obligation`
|
||||||
// and `process_projection_obligation` to handle checking for
|
// and `process_projection_obligation` to handle checking for
|
||||||
|
|
|
@ -995,10 +995,27 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Ambiguous => Ok(EvaluatedToAmbig),
|
ty::PredicateKind::Ambiguous => Ok(EvaluatedToAmbig),
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
|
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
|
||||||
|
// FIXME(BoxyUwU): Really we should not be calling `ct.ty()` for any variant
|
||||||
|
// other than `ConstKind::Value`. Unfortunately this would require looking in the
|
||||||
|
// env for any `ConstArgHasType` assumptions for parameters and placeholders. I
|
||||||
|
// don't really want to implement this in the old solver so I haven't.
|
||||||
|
//
|
||||||
|
// We do still stall on infer vars though as otherwise a goal like:
|
||||||
|
// `ConstArgHasType(?x: usize, usize)` can succeed even though it might later
|
||||||
|
// get unified with some const that is not of type `usize`.
|
||||||
|
let ct = self.infcx.shallow_resolve_const(ct);
|
||||||
|
let ct_ty = match ct.kind() {
|
||||||
|
ty::ConstKind::Infer(ty::InferConst::Var(_)) => {
|
||||||
|
return Ok(EvaluatedToAmbig);
|
||||||
|
}
|
||||||
|
ty::ConstKind::Error(_) => return Ok(EvaluatedToOk),
|
||||||
|
_ => ct.ty(),
|
||||||
|
};
|
||||||
|
|
||||||
match self.infcx.at(&obligation.cause, obligation.param_env).eq(
|
match self.infcx.at(&obligation.cause, obligation.param_env).eq(
|
||||||
// Only really excercised by generic_const_exprs
|
// Only really excercised by generic_const_exprs
|
||||||
DefineOpaqueTypes::Yes,
|
DefineOpaqueTypes::Yes,
|
||||||
ct.ty(),
|
ct_ty,
|
||||||
ty,
|
ty,
|
||||||
) {
|
) {
|
||||||
Ok(inf_ok) => self.evaluate_predicates_recursively(
|
Ok(inf_ok) => self.evaluate_predicates_recursively(
|
||||||
|
|
|
@ -1,17 +1,14 @@
|
||||||
|
//@ known-bug: #121858
|
||||||
#![feature(generic_const_exprs)]
|
#![feature(generic_const_exprs)]
|
||||||
#![allow(incomplete_features)]
|
|
||||||
|
|
||||||
struct Outer<const A: i64, const B: usize>();
|
struct Outer<const A: i64, const B: usize>();
|
||||||
impl<const A: usize, const B: usize> Outer<A, B>
|
impl<const A: usize, const B: usize> Outer<A, B>
|
||||||
//~^ ERROR: `A` is not of type `i64`
|
|
||||||
//~| ERROR: mismatched types
|
|
||||||
where
|
where
|
||||||
[(); A + (B * 2)]:,
|
[(); A + (B * 2)]:,
|
||||||
{
|
{
|
||||||
fn o() {}
|
fn o() -> Union {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
Outer::<1, 1>::o();
|
Outer::<1, 1>::o();
|
||||||
//~^ ERROR: no function or associated item named `o` found
|
|
||||||
}
|
}
|
|
@ -1,12 +0,0 @@
|
||||||
//@ known-bug: #122638
|
|
||||||
#![feature(min_specialization)]
|
|
||||||
|
|
||||||
impl<'a, T: std::fmt::Debug, const N: usize> Iterator for ConstChunksExact<'a, T, { N }> {
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ConstChunksExact<'a, T: '_, const assert: usize> {}
|
|
||||||
|
|
||||||
impl<'a, T: std::fmt::Debug, const N: usize> Iterator for ConstChunksExact<'a, T, {}> {
|
|
||||||
type Item = &'a [T; N];
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
//@ known-bug: #123141
|
|
||||||
|
|
||||||
trait ConstChunksExactTrait<T> {
|
|
||||||
fn const_chunks_exact<const N: usize>(&self) -> ConstChunksExact<'_, T, {N}>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl <T> ConstChunksExactTrait<T> for [T] {}
|
|
||||||
|
|
||||||
struct ConstChunksExact<'a, T: 'a, const N: usize> {}
|
|
||||||
|
|
||||||
impl <'a, T: , const N: usize> Iterator for ConstChunksExact<'a, T, {rem}> {
|
|
||||||
type Item = &'a [T; N];
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let slice = &[1i32, 2, 3, 4, 5, 6, 7, 7, 9, 1i32];
|
|
||||||
|
|
||||||
let mut iter = [[1, 2, 3], [4, 5, 6], [7, 8 ,9]].iter();
|
|
||||||
|
|
||||||
for a in slice.const_chunks_exact::<3>() {
|
|
||||||
assert_eq!(a, iter.next().unwrap());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +1,23 @@
|
||||||
//@ known-bug: #123141
|
//@ known-bug: #123141
|
||||||
trait ConstChunksExactTrait<T> {
|
|
||||||
fn const_chunks_exact<const N: usize>(&self) -> ConstChunksExact<'_, T, { N }>;
|
trait Trait {
|
||||||
|
fn next(self) -> Self::Item;
|
||||||
|
type Item;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> ConstChunksExactTrait<T> for [T] {}
|
struct Foo<T: ?Sized>(T);
|
||||||
|
|
||||||
struct ConstChunksExact<'a, T: 'a, const N: usize> {}
|
impl<T: ?Sized, U> Trait for Foo<U> {
|
||||||
|
type Item = Foo<T>;
|
||||||
|
fn next(self) -> Self::Item {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, T, const N: usize> Iterator for ConstChunksExact<'a, T, { rem }> {
|
fn opaque() -> impl Trait {
|
||||||
type Item = &'a [T; N];
|
Foo::<_>(10_u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let slice = &[1i32, 2, 3, 4, 5, 6, 7, 7, 9, 1i32];
|
opaque().next();
|
||||||
|
|
||||||
let mut iter = [[1, 2, 3], [4, 5, 6], [7, 8, 9]].iter();
|
|
||||||
|
|
||||||
for a in slice.const_chunks_exact::<3>() {
|
|
||||||
assert_eq!(a, iter.next().unwrap());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,5 +8,6 @@ impl<const N: u8> Trait for [(); N] {}
|
||||||
//~^ ERROR: mismatched types
|
//~^ ERROR: mismatched types
|
||||||
impl<const N: i8> Trait for [(); N] {}
|
impl<const N: i8> Trait for [(); N] {}
|
||||||
//~^ ERROR: mismatched types
|
//~^ ERROR: mismatched types
|
||||||
|
//~| ERROR: conflicting implementations of trait `Trait`
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,3 +1,12 @@
|
||||||
|
error[E0119]: conflicting implementations of trait `Trait` for type `[(); _]`
|
||||||
|
--> $DIR/generic_const_type_mismatch.rs:9:1
|
||||||
|
|
|
||||||
|
LL | impl<const N: u8> Trait for [(); N] {}
|
||||||
|
| ----------------------------------- first implementation here
|
||||||
|
LL |
|
||||||
|
LL | impl<const N: i8> Trait for [(); N] {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[(); _]`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/generic_const_type_mismatch.rs:7:34
|
--> $DIR/generic_const_type_mismatch.rs:7:34
|
||||||
|
|
|
|
||||||
|
@ -10,6 +19,7 @@ error[E0308]: mismatched types
|
||||||
LL | impl<const N: i8> Trait for [(); N] {}
|
LL | impl<const N: i8> Trait for [(); N] {}
|
||||||
| ^ expected `usize`, found `i8`
|
| ^ expected `usize`, found `i8`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0308`.
|
Some errors have detailed explanations: E0119, E0308.
|
||||||
|
For more information about an error, try `rustc --explain E0119`.
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
//@ known-bug: #114456
|
//@ check-pass
|
||||||
#![feature(adt_const_params, lazy_type_alias)]
|
#![feature(adt_const_params, lazy_type_alias)]
|
||||||
|
//~^ WARN: the feature `adt_const_params` is incomplete
|
||||||
|
//~| WARN: the feature `lazy_type_alias` is incomplete
|
||||||
|
|
||||||
pub type Matrix = [usize; 1];
|
pub type Matrix = [usize; 1];
|
||||||
const EMPTY_MATRIX: Matrix = [0; 1];
|
const EMPTY_MATRIX: Matrix = [0; 1];
|
|
@ -0,0 +1,19 @@
|
||||||
|
warning: the feature `adt_const_params` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
--> $DIR/alias_const_param_ty-1.rs:2:12
|
||||||
|
|
|
||||||
|
LL | #![feature(adt_const_params, lazy_type_alias)]
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
|
warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
--> $DIR/alias_const_param_ty-1.rs:2:30
|
||||||
|
|
|
||||||
|
LL | #![feature(adt_const_params, lazy_type_alias)]
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
|
||||||
|
|
||||||
|
warning: 2 warnings emitted
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
//@ known-bug: #114456
|
//@ check-pass
|
||||||
#![feature(adt_const_params)]
|
#![feature(adt_const_params)]
|
||||||
|
//~^ WARN: the feature `adt_const_params` is incomplete
|
||||||
|
|
||||||
const EMPTY_MATRIX: <Type as Trait>::Matrix = [0; 1];
|
const EMPTY_MATRIX: <Type as Trait>::Matrix = [0; 1];
|
||||||
|
|
||||||
|
@ -12,8 +13,12 @@ impl Walk<EMPTY_MATRIX> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Type {}
|
pub enum Type {}
|
||||||
pub trait Trait { type Matrix; }
|
pub trait Trait {
|
||||||
impl Trait for Type { type Matrix = [usize; 1]; }
|
type Matrix;
|
||||||
|
}
|
||||||
|
impl Trait for Type {
|
||||||
|
type Matrix = [usize; 1];
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _ = Walk::new();
|
let _ = Walk::new();
|
|
@ -0,0 +1,11 @@
|
||||||
|
warning: the feature `adt_const_params` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
--> $DIR/alias_const_param_ty-2.rs:2:12
|
||||||
|
|
|
||||||
|
LL | #![feature(adt_const_params)]
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
|
warning: 1 warning emitted
|
||||||
|
|
|
@ -10,5 +10,7 @@ impl<const N: u64> Q for [u8; N] {
|
||||||
const ASSOC: usize = 1;
|
const ASSOC: usize = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] { todo!() }
|
pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] {
|
||||||
//~^ ERROR: `[u8; 13]: Q` is not satisfied
|
//~^ ERROR: the constant `13` is not of type `u64`
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
error[E0277]: the trait bound `[u8; 13]: Q` is not satisfied
|
error: the constant `13` is not of type `u64`
|
||||||
--> $DIR/bad-subst-const-kind.rs:13:24
|
--> $DIR/bad-subst-const-kind.rs:13:24
|
||||||
|
|
|
|
||||||
LL | pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] { todo!() }
|
LL | pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] {
|
||||||
| ^^^^^^^^ the trait `Q` is not implemented for `[u8; 13]`
|
| ^^^^^^^^ expected `u64`, found `usize`
|
||||||
|
|
|
|
||||||
= help: the trait `Q` is implemented for `[u8; N]`
|
note: required for `[u8; 13]` to implement `Q`
|
||||||
|
--> $DIR/bad-subst-const-kind.rs:8:20
|
||||||
|
|
|
||||||
|
LL | impl<const N: u64> Q for [u8; N] {
|
||||||
|
| ------------ ^ ^^^^^^^
|
||||||
|
| |
|
||||||
|
| unsatisfied trait bound introduced here
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/bad-subst-const-kind.rs:8:31
|
--> $DIR/bad-subst-const-kind.rs:8:31
|
||||||
|
@ -14,5 +20,4 @@ LL | impl<const N: u64> Q for [u8; N] {
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0308.
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
|
||||||
|
|
|
@ -3,7 +3,9 @@
|
||||||
struct Foo<const N: u32 = 2>;
|
struct Foo<const N: u32 = 2>;
|
||||||
|
|
||||||
impl<const N: u32> Foo<N> {
|
impl<const N: u32> Foo<N> {
|
||||||
fn foo() -> Self { loop {} }
|
fn foo() -> Self {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0282]: type annotations needed for `Foo<_>`
|
error[E0282]: type annotations needed for `Foo<_>`
|
||||||
--> $DIR/doesnt_infer.rs:11:9
|
--> $DIR/doesnt_infer.rs:13:9
|
||||||
|
|
|
|
||||||
LL | let foo = Foo::foo();
|
LL | let foo = Foo::foo();
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
|
@ -4,5 +4,5 @@ use std::simd::Mask;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let y = Mask::<_, _>::splat(false);
|
let y = Mask::<_, _>::splat(false);
|
||||||
//~^ ERROR: type annotations needed for
|
//~^ ERROR: type annotations needed
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
// issue: rust-lang/rust#125520
|
|
||||||
#![feature(generic_const_exprs)]
|
|
||||||
//~^ WARN the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
|
|
||||||
|
|
||||||
struct Outer<const A: i64, const B: i64>();
|
|
||||||
impl<const A: usize, const B: usize> Outer<A, B>
|
|
||||||
//~^ ERROR the constant `A` is not of type `i64`
|
|
||||||
//~| ERROR the constant `B` is not of type `i64`
|
|
||||||
//~| ERROR mismatched types
|
|
||||||
//~| ERROR mismatched types
|
|
||||||
where
|
|
||||||
[(); A + (B * 2)]:,
|
|
||||||
{
|
|
||||||
fn i() -> Self {
|
|
||||||
//~^ ERROR the constant `A` is not of type `i64`
|
|
||||||
//~| ERROR the constant `B` is not of type `i64`
|
|
||||||
Self
|
|
||||||
//~^ ERROR mismatched types
|
|
||||||
//~| ERROR the constant `A` is not of type `i64`
|
|
||||||
//~| ERROR the constant `B` is not of type `i64`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
Outer::<1, 1>::o();
|
|
||||||
//~^ ERROR no function or associated item named `o` found for struct `Outer` in the current scope
|
|
||||||
}
|
|
|
@ -1,125 +0,0 @@
|
||||||
warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
|
|
||||||
--> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:2:12
|
|
||||||
|
|
|
||||||
LL | #![feature(generic_const_exprs)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
|
||||||
|
|
||||||
error: the constant `A` is not of type `i64`
|
|
||||||
--> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:6:38
|
|
||||||
|
|
|
||||||
LL | impl<const A: usize, const B: usize> Outer<A, B>
|
|
||||||
| ^^^^^^^^^^^ expected `i64`, found `usize`
|
|
||||||
|
|
|
||||||
note: required by a bound in `Outer`
|
|
||||||
--> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:5:14
|
|
||||||
|
|
|
||||||
LL | struct Outer<const A: i64, const B: i64>();
|
|
||||||
| ^^^^^^^^^^^^ required by this bound in `Outer`
|
|
||||||
|
|
||||||
error: the constant `B` is not of type `i64`
|
|
||||||
--> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:6:38
|
|
||||||
|
|
|
||||||
LL | impl<const A: usize, const B: usize> Outer<A, B>
|
|
||||||
| ^^^^^^^^^^^ expected `i64`, found `usize`
|
|
||||||
|
|
|
||||||
note: required by a bound in `Outer`
|
|
||||||
--> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:5:28
|
|
||||||
|
|
|
||||||
LL | struct Outer<const A: i64, const B: i64>();
|
|
||||||
| ^^^^^^^^^^^^ required by this bound in `Outer`
|
|
||||||
|
|
||||||
error: the constant `A` is not of type `i64`
|
|
||||||
--> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:14:15
|
|
||||||
|
|
|
||||||
LL | fn i() -> Self {
|
|
||||||
| ^^^^ expected `i64`, found `usize`
|
|
||||||
|
|
|
||||||
note: required by a bound in `Outer`
|
|
||||||
--> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:5:14
|
|
||||||
|
|
|
||||||
LL | struct Outer<const A: i64, const B: i64>();
|
|
||||||
| ^^^^^^^^^^^^ required by this bound in `Outer`
|
|
||||||
|
|
||||||
error: the constant `B` is not of type `i64`
|
|
||||||
--> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:14:15
|
|
||||||
|
|
|
||||||
LL | fn i() -> Self {
|
|
||||||
| ^^^^ expected `i64`, found `usize`
|
|
||||||
|
|
|
||||||
note: required by a bound in `Outer`
|
|
||||||
--> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:5:28
|
|
||||||
|
|
|
||||||
LL | struct Outer<const A: i64, const B: i64>();
|
|
||||||
| ^^^^^^^^^^^^ required by this bound in `Outer`
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:17:9
|
|
||||||
|
|
|
||||||
LL | struct Outer<const A: i64, const B: i64>();
|
|
||||||
| ---------------------------------------- `Outer` defines a struct constructor here, which should be called
|
|
||||||
...
|
|
||||||
LL | fn i() -> Self {
|
|
||||||
| ---- expected `Outer<A, B>` because of return type
|
|
||||||
...
|
|
||||||
LL | Self
|
|
||||||
| ^^^^ expected `Outer<A, B>`, found struct constructor
|
|
||||||
|
|
|
||||||
= note: expected struct `Outer<A, B>`
|
|
||||||
found struct constructor `fn() -> Outer<A, B> {Outer::<A, B>}`
|
|
||||||
help: use parentheses to construct this tuple struct
|
|
||||||
|
|
|
||||||
LL | Self()
|
|
||||||
| ++
|
|
||||||
|
|
||||||
error: the constant `A` is not of type `i64`
|
|
||||||
--> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:17:9
|
|
||||||
|
|
|
||||||
LL | Self
|
|
||||||
| ^^^^ expected `i64`, found `usize`
|
|
||||||
|
|
|
||||||
note: required by a bound in `Outer`
|
|
||||||
--> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:5:14
|
|
||||||
|
|
|
||||||
LL | struct Outer<const A: i64, const B: i64>();
|
|
||||||
| ^^^^^^^^^^^^ required by this bound in `Outer`
|
|
||||||
|
|
||||||
error: the constant `B` is not of type `i64`
|
|
||||||
--> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:17:9
|
|
||||||
|
|
|
||||||
LL | Self
|
|
||||||
| ^^^^ expected `i64`, found `usize`
|
|
||||||
|
|
|
||||||
note: required by a bound in `Outer`
|
|
||||||
--> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:5:28
|
|
||||||
|
|
|
||||||
LL | struct Outer<const A: i64, const B: i64>();
|
|
||||||
| ^^^^^^^^^^^^ required by this bound in `Outer`
|
|
||||||
|
|
||||||
error[E0599]: no function or associated item named `o` found for struct `Outer` in the current scope
|
|
||||||
--> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:25:20
|
|
||||||
|
|
|
||||||
LL | struct Outer<const A: i64, const B: i64>();
|
|
||||||
| ---------------------------------------- function or associated item `o` not found for this struct
|
|
||||||
...
|
|
||||||
LL | Outer::<1, 1>::o();
|
|
||||||
| ^ function or associated item not found in `Outer<1, 1>`
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:6:44
|
|
||||||
|
|
|
||||||
LL | impl<const A: usize, const B: usize> Outer<A, B>
|
|
||||||
| ^ expected `i64`, found `usize`
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:6:47
|
|
||||||
|
|
|
||||||
LL | impl<const A: usize, const B: usize> Outer<A, B>
|
|
||||||
| ^ expected `i64`, found `usize`
|
|
||||||
|
|
||||||
error: aborting due to 10 previous errors; 1 warning emitted
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0308, E0599.
|
|
||||||
For more information about an error, try `rustc --explain E0308`.
|
|
|
@ -10,7 +10,7 @@ impl<const N: u64> Q for [u8; N] {}
|
||||||
//~| ERROR mismatched types
|
//~| ERROR mismatched types
|
||||||
|
|
||||||
pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {}
|
pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {}
|
||||||
//~^ ERROR `[u8; 13]: Q` is not satisfied
|
//~^ ERROR the constant `13` is not of type `u64`
|
||||||
//~| ERROR mismatched types
|
//~| ERROR mismatched types
|
||||||
|
|
||||||
pub fn main() {}
|
pub fn main() {}
|
||||||
|
|
|
@ -7,13 +7,19 @@ LL | const ASSOC: usize;
|
||||||
LL | impl<const N: u64> Q for [u8; N] {}
|
LL | impl<const N: u64> Q for [u8; N] {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `ASSOC` in implementation
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `ASSOC` in implementation
|
||||||
|
|
||||||
error[E0277]: the trait bound `[u8; 13]: Q` is not satisfied
|
error: the constant `13` is not of type `u64`
|
||||||
--> $DIR/type_mismatch.rs:12:26
|
--> $DIR/type_mismatch.rs:12:26
|
||||||
|
|
|
|
||||||
LL | pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {}
|
LL | pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {}
|
||||||
| ^^^^^^^^ the trait `Q` is not implemented for `[u8; 13]`
|
| ^^^^^^^^ expected `u64`, found `usize`
|
||||||
|
|
|
|
||||||
= help: the trait `Q` is implemented for `[u8; N]`
|
note: required for `[u8; 13]` to implement `Q`
|
||||||
|
--> $DIR/type_mismatch.rs:8:20
|
||||||
|
|
|
||||||
|
LL | impl<const N: u64> Q for [u8; N] {}
|
||||||
|
| ------------ ^ ^^^^^^^
|
||||||
|
| |
|
||||||
|
| unsatisfied trait bound introduced here
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/type_mismatch.rs:12:20
|
--> $DIR/type_mismatch.rs:12:20
|
||||||
|
@ -31,5 +37,5 @@ LL | impl<const N: u64> Q for [u8; N] {}
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0046, E0277, E0308.
|
Some errors have detailed explanations: E0046, E0308.
|
||||||
For more information about an error, try `rustc --explain E0046`.
|
For more information about an error, try `rustc --explain E0046`.
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
//@ failure-status: 101
|
//@ check-pass
|
||||||
//@ known-bug: rust-lang/rust#125451
|
// If this test starts failing because it ICEs due to not being able to convert a `ReErased` to
|
||||||
//@ normalize-stderr-test "note: .*\n\n" -> ""
|
// something then feel free to just convert this to a known-bug. I'm pretty sure this is still
|
||||||
//@ normalize-stderr-test "thread 'rustc' panicked.*\n.*\n" -> ""
|
// a failing test, we just started masking the bug.
|
||||||
//@ normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
|
|
||||||
//@ normalize-stderr-test "delayed at .*" -> ""
|
|
||||||
//@ rustc-env:RUST_BACKTRACE=0
|
|
||||||
|
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
#![feature(adt_const_params, generic_const_exprs)]
|
#![feature(adt_const_params, generic_const_exprs)]
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
error: internal compiler error: compiler/rustc_borrowck/src/universal_regions.rs:LL:CC: cannot convert `'{erased}` to a region vid
|
|
||||||
|
|
||||||
query stack during panic:
|
|
||||||
#0 [mir_borrowck] borrow-checking `<impl at $DIR/issue-105821.rs:21:1: 23:24>::R`
|
|
||||||
#1 [analysis] running analysis passes on this crate
|
|
||||||
end of query stack
|
|
||||||
error: aborting due to 1 previous error
|
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
error: the constant `A` is not of type `i64`
|
|
||||||
--> $DIR/eval_type_mismatch.rs:5:38
|
|
||||||
|
|
|
||||||
LL | impl<const A: usize, const B: usize> Outer<A, B>
|
|
||||||
| ^^^^^^^^^^^ expected `i64`, found `usize`
|
|
||||||
|
|
|
||||||
note: required by a bound in `Outer`
|
|
||||||
--> $DIR/eval_type_mismatch.rs:4:14
|
|
||||||
|
|
|
||||||
LL | struct Outer<const A: i64, const B: usize>();
|
|
||||||
| ^^^^^^^^^^^^ required by this bound in `Outer`
|
|
||||||
|
|
||||||
error[E0599]: no function or associated item named `o` found for struct `Outer<1, 1>` in the current scope
|
|
||||||
--> $DIR/eval_type_mismatch.rs:15:20
|
|
||||||
|
|
|
||||||
LL | struct Outer<const A: i64, const B: usize>();
|
|
||||||
| ------------------------------------------ function or associated item `o` not found for this struct
|
|
||||||
...
|
|
||||||
LL | Outer::<1, 1>::o();
|
|
||||||
| ^ function or associated item not found in `Outer<1, 1>`
|
|
||||||
|
|
|
||||||
= note: the function or associated item was found for
|
|
||||||
- `Outer<A, B>`
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/eval_type_mismatch.rs:5:44
|
|
||||||
|
|
|
||||||
LL | impl<const A: usize, const B: usize> Outer<A, B>
|
|
||||||
| ^ expected `i64`, found `usize`
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0308, E0599.
|
|
||||||
For more information about an error, try `rustc --explain E0308`.
|
|
|
@ -6,5 +6,5 @@ fn foo<const N: usize>(_: impl std::fmt::Display) -> [usize; N] {
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _ = foo("foo");
|
let _ = foo("foo");
|
||||||
//~^ ERROR type annotations needed for `[usize; _]`
|
//~^ ERROR type annotations needed
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,7 @@ struct S<const L: usize>;
|
||||||
|
|
||||||
impl<const N: i32> Copy for S<N> {}
|
impl<const N: i32> Copy for S<N> {}
|
||||||
//~^ ERROR: mismatched types
|
//~^ ERROR: mismatched types
|
||||||
//~| ERROR: the trait bound `S<N>: Clone` is not satisfied
|
|
||||||
//~| ERROR: the constant `N` is not of type `usize`
|
|
||||||
impl<const M: usize> Copy for S<M> {}
|
impl<const M: usize> Copy for S<M> {}
|
||||||
|
//~^ ERROR: conflicting implementations of trait `Copy` for type `S<_>`
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,29 +1,11 @@
|
||||||
error[E0277]: the trait bound `S<N>: Clone` is not satisfied
|
error[E0119]: conflicting implementations of trait `Copy` for type `S<_>`
|
||||||
--> $DIR/bad-const-wf-doesnt-specialize.rs:8:29
|
--> $DIR/bad-const-wf-doesnt-specialize.rs:10:1
|
||||||
|
|
|
|
||||||
LL | impl<const N: i32> Copy for S<N> {}
|
LL | impl<const N: i32> Copy for S<N> {}
|
||||||
| ^^^^ the trait `Clone` is not implemented for `S<N>`
|
| -------------------------------- first implementation here
|
||||||
|
|
LL |
|
||||||
= help: the trait `Clone` is implemented for `S<L>`
|
LL | impl<const M: usize> Copy for S<M> {}
|
||||||
note: required by a bound in `Copy`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `S<_>`
|
||||||
--> $SRC_DIR/core/src/marker.rs:LL:COL
|
|
||||||
help: consider annotating `S<N>` with `#[derive(Clone)]`
|
|
||||||
|
|
|
||||||
LL + #[derive(Clone)]
|
|
||||||
LL | struct S<const L: usize>;
|
|
||||||
|
|
|
||||||
|
|
||||||
error: the constant `N` is not of type `usize`
|
|
||||||
--> $DIR/bad-const-wf-doesnt-specialize.rs:8:29
|
|
||||||
|
|
|
||||||
LL | impl<const N: i32> Copy for S<N> {}
|
|
||||||
| ^^^^ expected `usize`, found `i32`
|
|
||||||
|
|
|
||||||
note: required by a bound in `S`
|
|
||||||
--> $DIR/bad-const-wf-doesnt-specialize.rs:6:10
|
|
||||||
|
|
|
||||||
LL | struct S<const L: usize>;
|
|
||||||
| ^^^^^^^^^^^^^^ required by this bound in `S`
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/bad-const-wf-doesnt-specialize.rs:8:31
|
--> $DIR/bad-const-wf-doesnt-specialize.rs:8:31
|
||||||
|
@ -31,7 +13,7 @@ error[E0308]: mismatched types
|
||||||
LL | impl<const N: i32> Copy for S<N> {}
|
LL | impl<const N: i32> Copy for S<N> {}
|
||||||
| ^ expected `usize`, found `i32`
|
| ^ expected `usize`, found `i32`
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0308.
|
Some errors have detailed explanations: E0119, E0308.
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
For more information about an error, try `rustc --explain E0119`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue