1
Fork 0

Put lazy normalization behind a feature gate

This commit is contained in:
Ben Lewis 2020-01-04 18:54:19 +13:00 committed by Bastian Kauschke
parent 3ef831069a
commit 93d15b9480
26 changed files with 207 additions and 67 deletions

View file

@ -558,6 +558,9 @@ declare_features! (
/// Allow negative trait implementations. /// Allow negative trait implementations.
(active, negative_impls, "1.44.0", Some(68318), None), (active, negative_impls, "1.44.0", Some(68318), None),
/// Lazily evaluate constants. Which allows constants to depend on type parameters.
(active, lazy_normalization_consts, "1.44.0", Some(60471), None),
/// Allows the use of `#[target_feature]` on safe functions. /// Allows the use of `#[target_feature]` on safe functions.
(active, target_feature_11, "1.45.0", Some(69098), None), (active, target_feature_11, "1.45.0", Some(69098), None),
@ -581,4 +584,5 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[
sym::raw_dylib, sym::raw_dylib,
sym::const_trait_impl, sym::const_trait_impl,
sym::const_trait_bound_opt_out, sym::const_trait_bound_opt_out,
sym::lazy_normalization_consts,
]; ];

View file

@ -164,11 +164,15 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> {
(_, ty::ConstKind::Infer(InferConst::Var(vid))) => { (_, ty::ConstKind::Infer(InferConst::Var(vid))) => {
return self.unify_const_variable(!a_is_expected, vid, a); return self.unify_const_variable(!a_is_expected, vid, a);
} }
(ty::ConstKind::Unevaluated(..), _) => { (ty::ConstKind::Unevaluated(..), _)
if self.tcx.features().lazy_normalization_consts =>
{
relation.const_equate_obligation(a, b); relation.const_equate_obligation(a, b);
return Ok(b); return Ok(b);
} }
(_, ty::ConstKind::Unevaluated(..)) => { (_, ty::ConstKind::Unevaluated(..))
if self.tcx.features().lazy_normalization_consts =>
{
relation.const_equate_obligation(a, b); relation.const_equate_obligation(a, b);
return Ok(a); return Ok(a);
} }
@ -658,14 +662,16 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
} }
} }
} }
ty::ConstKind::Unevaluated(..) => Ok(c), ty::ConstKind::Unevaluated(..) if self.tcx().features().lazy_normalization_consts => {
Ok(c)
}
_ => relate::super_relate_consts(self, c, c), _ => relate::super_relate_consts(self, c, c),
} }
} }
} }
pub trait ConstEquateRelation<'tcx>: TypeRelation<'tcx> { pub trait ConstEquateRelation<'tcx>: TypeRelation<'tcx> {
/// Register am obligation that both constants must be equal to each other. /// Register an obligation that both constants must be equal to each other.
/// ///
/// If they aren't equal then the relation doesn't hold. /// If they aren't equal then the relation doesn't hold.
fn const_equate_obligation(&mut self, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>); fn const_equate_obligation(&mut self, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>);

View file

@ -1,4 +1,4 @@
use super::combine::{CombineFields, RelationDir, ConstEquateRelation}; use super::combine::{CombineFields, ConstEquateRelation, RelationDir};
use super::Subtype; use super::Subtype;
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};

View file

@ -988,7 +988,9 @@ where
} }
} }
} }
ty::ConstKind::Unevaluated(..) => Ok(a), ty::ConstKind::Unevaluated(..) if self.tcx().features().lazy_normalization_consts => {
Ok(a)
}
_ => relate::super_relate_consts(self, a, a), _ => relate::super_relate_consts(self, a, a),
} }
} }

View file

@ -431,18 +431,20 @@ pub fn super_relate_tys<R: TypeRelation<'tcx>>(
let t = relation.relate(&a_t, &b_t)?; let t = relation.relate(&a_t, &b_t)?;
match relation.relate(&sz_a, &sz_b) { match relation.relate(&sz_a, &sz_b) {
Ok(sz) => Ok(tcx.mk_ty(ty::Array(t, sz))), Ok(sz) => Ok(tcx.mk_ty(ty::Array(t, sz))),
// FIXME(lazy_normalization_consts) Implement improved diagnostics for mismatched array
// length?
Err(err) if relation.tcx().features().lazy_normalization_consts => Err(err),
Err(err) => { Err(err) => {
// // Check whether the lengths are both concrete/known values, // Check whether the lengths are both concrete/known values,
// // but are unequal, for better diagnostics. // but are unequal, for better diagnostics.
// let sz_a = sz_a.try_eval_usize(tcx, relation.param_env()); let sz_a = sz_a.try_eval_usize(tcx, relation.param_env());
// let sz_b = sz_b.try_eval_usize(tcx, relation.param_env()); let sz_b = sz_b.try_eval_usize(tcx, relation.param_env());
// match (sz_a, sz_b) { match (sz_a, sz_b) {
// (Some(sz_a_val), Some(sz_b_val)) => Err(TypeError::FixedArraySize( (Some(sz_a_val), Some(sz_b_val)) => Err(TypeError::FixedArraySize(
// expected_found(relation, &sz_a_val, &sz_b_val), expected_found(relation, &sz_a_val, &sz_b_val),
// )), )),
// _ => Err(err), _ => Err(err),
// } }
Err(err)
} }
} }
} }
@ -605,14 +607,14 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
} }
// FIXME(const_generics): this is wrong, as it is a projection // FIXME(const_generics): this is wrong, as it is a projection
// ( (
// ty::ConstKind::Unevaluated(a_def_id, a_substs, a_promoted), ty::ConstKind::Unevaluated(a_def_id, a_substs, a_promoted),
// ty::ConstKind::Unevaluated(b_def_id, b_substs, b_promoted), ty::ConstKind::Unevaluated(b_def_id, b_substs, b_promoted),
// ) if a_def_id == b_def_id && a_promoted == b_promoted => { ) if a_def_id == b_def_id && a_promoted == b_promoted => {
// let substs = let substs =
// relation.relate_with_variance(ty::Variance::Invariant, &a_substs, &b_substs)?; relation.relate_with_variance(ty::Variance::Invariant, &a_substs, &b_substs)?;
// Ok(ty::ConstKind::Unevaluated(a_def_id, &substs, a_promoted)) Ok(ty::ConstKind::Unevaluated(a_def_id, &substs, a_promoted))
// } }
_ => Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))), _ => Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))),
}; };
new_const_val.map(|val| tcx.mk_const(ty::Const { val, ty: a.ty })) new_const_val.map(|val| tcx.mk_const(ty::Const { val, ty: a.ty }))

View file

@ -870,7 +870,7 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
instrument_mcount: bool = (false, parse_bool, [TRACKED], instrument_mcount: bool = (false, parse_bool, [TRACKED],
"insert function instrument code for mcount-based tracing (default: no)"), "insert function instrument code for mcount-based tracing (default: no)"),
keep_hygiene_data: bool = (false, parse_bool, [UNTRACKED], keep_hygiene_data: bool = (false, parse_bool, [UNTRACKED],
"keep hygiene data after analysis (default: no)"), "lazily evaluate constants (experimental)"),
link_native_libraries: bool = (true, parse_bool, [UNTRACKED], link_native_libraries: bool = (true, parse_bool, [UNTRACKED],
"link native libraries in the linker invocation (default: yes)"), "link native libraries in the linker invocation (default: yes)"),
link_only: bool = (false, parse_bool, [TRACKED], link_only: bool = (false, parse_bool, [TRACKED],

View file

@ -411,6 +411,7 @@ symbols! {
label_break_value, label_break_value,
lang, lang,
lang_items, lang_items,
lazy_normalization_consts,
let_chains, let_chains,
lhs, lhs,
lib, lib,

View file

@ -386,6 +386,15 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
_ => ty, _ => ty,
} }
} }
fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
if self.selcx.tcx().features().lazy_normalization_consts {
constant
} else {
let constant = constant.super_fold_with(self);
constant.eval(self.selcx.tcx(), self.param_env)
}
}
} }
/// The guts of `normalize`: normalize a specific projection like `<T /// The guts of `normalize`: normalize a specific projection like `<T

View file

@ -201,4 +201,9 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
_ => ty, _ => ty,
} }
} }
fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
let constant = constant.super_fold_with(self);
constant.eval(self.infcx.tcx, self.param_env)
}
} }

View file

@ -1156,8 +1156,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
let node = tcx.hir().get(hir_id); let node = tcx.hir().get(hir_id);
let parent_def_id = match node { let parent_def_id = match node {
Node::AnonConst(_) Node::ImplItem(_)
| Node::ImplItem(_)
| Node::TraitItem(_) | Node::TraitItem(_)
| Node::Variant(_) | Node::Variant(_)
| Node::Ctor(..) | Node::Ctor(..)
@ -1166,6 +1165,15 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
Some(tcx.hir().local_def_id(parent_id).to_def_id()) Some(tcx.hir().local_def_id(parent_id).to_def_id())
} }
Node::AnonConst(_) => {
if tcx.features().lazy_normalization_consts {
let parent_id = tcx.hir().get_parent_item(hir_id);
Some(tcx.hir().local_def_id(parent_id))
} else {
None
}
}
Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(..), .. }) => { Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(..), .. }) => {
Some(tcx.closure_base_def_id(def_id)) Some(tcx.closure_base_def_id(def_id))
} }

View file

@ -1,5 +1,6 @@
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete //~^ WARN the feature `const_generics` is incomplete
#![feature(lazy_normalization_consts)]
//~^ WARN the feature `lazy_normalization_consts` is incomplete
#[allow(dead_code)] #[allow(dead_code)]
struct ArithArrayLen<const N: usize>([u32; 0 + N]); struct ArithArrayLen<const N: usize>([u32; 0 + N]);

View file

@ -7,8 +7,14 @@ LL | #![feature(const_generics)]
= note: `#[warn(incomplete_features)]` on by default = note: `#[warn(incomplete_features)]` on by default
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
warning: the feature `lazy_normalization_consts` is incomplete and may cause the compiler to crash
--> $DIR/array-size-in-generic-struct-param.rs:3:12
|
LL | #![feature(lazy_normalization_consts)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: constant expression depends on a generic parameter error: constant expression depends on a generic parameter
--> $DIR/array-size-in-generic-struct-param.rs:5:38 --> $DIR/array-size-in-generic-struct-param.rs:7:38
| |
LL | struct ArithArrayLen<const N: usize>([u32; 0 + N]); LL | struct ArithArrayLen<const N: usize>([u32; 0 + N]);
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
@ -16,7 +22,7 @@ LL | struct ArithArrayLen<const N: usize>([u32; 0 + N]);
= note: this may fail depending on what value the parameter takes = note: this may fail depending on what value the parameter takes
error: constant expression depends on a generic parameter error: constant expression depends on a generic parameter
--> $DIR/array-size-in-generic-struct-param.rs:14:5 --> $DIR/array-size-in-generic-struct-param.rs:16:5
| |
LL | arr: [u8; CFG.arr_size], LL | arr: [u8; CFG.arr_size],
| ^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -1,5 +1,6 @@
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete //~^ WARN the feature `const_generics` is incomplete
#![feature(lazy_normalization_consts)]
//~^ WARN the feature `lazy_normalization_consts` is incomplete
// build-pass // build-pass

View file

@ -1,5 +1,6 @@
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete //~^ WARN the feature `const_generics` is incomplete
#![feature(lazy_normalization_consts)]
//~^ WARN the feature `lazy_normalization_consts` is incomplete
fn f<T: Copy, const N: usize>(x: T) -> [T; N] { fn f<T: Copy, const N: usize>(x: T) -> [T; N] {
[x; { N }] [x; { N }]

View file

@ -7,6 +7,12 @@ LL | #![feature(const_generics)]
= note: `#[warn(incomplete_features)]` on by default = note: `#[warn(incomplete_features)]` on by default
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
warning: the feature `lazy_normalization_consts` is incomplete and may cause the compiler to crash
--> $DIR/issue-61336-2.rs:3:12
|
LL | #![feature(lazy_normalization_consts)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
--> $DIR/issue-61336-2.rs:9:5 --> $DIR/issue-61336-2.rs:9:5
| |

View file

@ -1,5 +1,7 @@
#![feature(const_generics)] #![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete //~^ WARN the feature `const_generics` is incomplete
#![feature(lazy_normalization_consts)]
//~^ WARN the feature `lazy_normalization_consts` is incomplete
fn f<T: Copy, const N: usize>(x: T) -> [T; N] { fn f<T: Copy, const N: usize>(x: T) -> [T; N] {
[x; N] [x; N]

View file

@ -7,6 +7,12 @@ LL | #![feature(const_generics)]
= note: `#[warn(incomplete_features)]` on by default = note: `#[warn(incomplete_features)]` on by default
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
warning: the feature `lazy_normalization_consts` is incomplete and may cause the compiler to crash
--> $DIR/issue-61336.rs:3:12
|
LL | #![feature(lazy_normalization_consts)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
--> $DIR/issue-61336.rs:9:5 --> $DIR/issue-61336.rs:9:5
| |

View file

@ -2,6 +2,8 @@
#![feature(const_generics)] #![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete //~^ WARN the feature `const_generics` is incomplete
#![feature(lazy_normalization_consts)]
//~^ WARN the feature `lazy_normalization_consts` is incomplete
struct Const<const N: usize>; struct Const<const N: usize>;

View file

@ -7,5 +7,13 @@ LL | #![feature(const_generics)]
= note: `#[warn(incomplete_features)]` on by default = note: `#[warn(incomplete_features)]` on by default
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
<<<<<<< HEAD
warning: 1 warning emitted warning: 1 warning emitted
=======
warning: the feature `lazy_normalization_consts` is incomplete and may cause the compiler to crash
--> $DIR/issue-61747.rs:5:12
|
LL | #![feature(lazy_normalization_consts)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
>>>>>>> Added `lazy_normalization_consts` feature, and removed the -Z flag.

View file

@ -2,6 +2,8 @@
#![feature(const_generics)] #![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
#![feature(lazy_normalization_consts)]
//~^ WARN the feature `lazy_normalization_consts` is incomplete and may cause the compiler to crash
trait Foo {} trait Foo {}

View file

@ -6,3 +6,9 @@ LL | #![feature(const_generics)]
= note: `#[warn(incomplete_features)]` on by default = note: `#[warn(incomplete_features)]` on by default
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
warning: the feature `lazy_normalization_consts` is incomplete and may cause the compiler to crash
--> $DIR/issue-61935.rs:5:12
|
LL | #![feature(lazy_normalization_consts)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -1,5 +1,6 @@
#![allow(incomplete_features, dead_code, unconditional_recursion)] #![allow(incomplete_features, dead_code, unconditional_recursion)]
#![feature(const_generics)] #![feature(const_generics)]
#![feature(lazy_normalization_consts)]
fn fact<const N: usize>() { fn fact<const N: usize>() {
fact::<{ N - 1 }>(); fact::<{ N - 1 }>();

View file

@ -2,6 +2,8 @@
#![feature(const_generics)] #![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
#![feature(lazy_normalization_consts)]
//~^ WARN the feature `lazy_normalization_consts` is incomplete and may cause the compiler to crash
trait Baz { trait Baz {
type Quaks; type Quaks;

View file

@ -6,3 +6,9 @@ LL | #![feature(const_generics)]
| |
= note: `#[warn(incomplete_features)]` on by default = note: `#[warn(incomplete_features)]` on by default
warning: the feature `lazy_normalization_consts` is incomplete and may cause the compiler to crash
--> $DIR/issue-67185-1.rs:5:12
|
LL | #![feature(lazy_normalization_consts)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -1,5 +1,7 @@
#![feature(const_generics)] #![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
#![feature(lazy_normalization_consts)]
//~^ WARN the feature `lazy_normalization_consts` is incomplete and may cause the compiler to crash
trait Baz { trait Baz {
type Quaks; type Quaks;
@ -12,7 +14,8 @@ trait Bar {}
impl Bar for [u16; 4] {} impl Bar for [u16; 4] {}
impl Bar for [[u16; 3]; 3] {} impl Bar for [[u16; 3]; 3] {}
trait Foo //~ ERROR mismatched types trait Foo //~ ERROR the trait bound `[u16; 3]: Bar` is not satisfied [E0277]
//~^ ERROR the trait bound `[[u16; 3]; 2]: Bar` is not satisfied [E0277]
where where
[<u8 as Baz>::Quaks; 2]: Bar, [<u8 as Baz>::Quaks; 2]: Bar,
<u8 as Baz>::Quaks: Bar, <u8 as Baz>::Quaks: Bar,
@ -22,12 +25,12 @@ trait Foo //~ ERROR mismatched types
struct FooImpl; struct FooImpl;
impl Foo for FooImpl {} impl Foo for FooImpl {}
//~^ ERROR mismatched types //~^ ERROR the trait bound `[u16; 3]: Bar` is not satisfied [E0277]
//~^^ ERROR mismatched types //~^^ ERROR the trait bound `[[u16; 3]; 2]: Bar` is not satisfied [E0277]
fn f(_: impl Foo) {} fn f(_: impl Foo) {}
//~^ ERROR mismatched types //~^ ERROR the trait bound `[u16; 3]: Bar` is not satisfied [E0277]
//~^^ ERROR mismatched types //~^^ ERROR the trait bound `[[u16; 3]; 2]: Bar` is not satisfied [E0277]
fn main() { fn main() {
f(FooImpl) f(FooImpl)

View file

@ -6,56 +6,106 @@ LL | #![feature(const_generics)]
| |
= note: `#[warn(incomplete_features)]` on by default = note: `#[warn(incomplete_features)]` on by default
error[E0308]: mismatched types warning: the feature `lazy_normalization_consts` is incomplete and may cause the compiler to crash
--> $DIR/issue-67185-2.rs:15:1 --> $DIR/issue-67185-2.rs:3:12
|
LL | #![feature(lazy_normalization_consts)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
--> $DIR/issue-67185-2.rs:17:1
| |
LL | / trait Foo LL | / trait Foo
LL | |
LL | | where LL | | where
LL | | [<u8 as Baz>::Quaks; 2]: Bar, LL | | [<u8 as Baz>::Quaks; 2]: Bar,
LL | | <u8 as Baz>::Quaks: Bar, LL | | <u8 as Baz>::Quaks: Bar,
LL | | { LL | | {
LL | | } LL | | }
| |_^ expected `3usize`, found `4usize` | |_^ the trait `Bar` is not implemented for `[u16; 3]`
| |
= note: expected type `3usize` = help: the following implementations were found:
found type `4usize` <[[u16; 3]; 3] as Bar>
<[u16; 4] as Bar>
= help: see issue #48214
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
error[E0308]: mismatched types error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
--> $DIR/issue-67185-2.rs:24:6 --> $DIR/issue-67185-2.rs:17:1
|
LL | / trait Foo
LL | |
LL | | where
LL | | [<u8 as Baz>::Quaks; 2]: Bar,
LL | | <u8 as Baz>::Quaks: Bar,
LL | | {
LL | | }
| |_^ the trait `Bar` is not implemented for `[[u16; 3]; 2]`
|
= help: the following implementations were found:
<[[u16; 3]; 3] as Bar>
<[u16; 4] as Bar>
= help: see issue #48214
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
--> $DIR/issue-67185-2.rs:27:6
| |
LL | impl Foo for FooImpl {} LL | impl Foo for FooImpl {}
| ^^^ expected `3usize`, found `4usize` | ^^^ the trait `Bar` is not implemented for `[u16; 3]`
| |
= note: expected type `3usize` = help: the following implementations were found:
found type `4usize` <[[u16; 3]; 3] as Bar>
<[u16; 4] as Bar>
error[E0308]: mismatched types error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
--> $DIR/issue-67185-2.rs:24:6 --> $DIR/issue-67185-2.rs:27:6
| |
LL | impl Foo for FooImpl {} LL | impl Foo for FooImpl {}
| ^^^ expected `2usize`, found `3usize` | ^^^ the trait `Bar` is not implemented for `[[u16; 3]; 2]`
| |
= note: expected type `2usize` = help: the following implementations were found:
found type `3usize` <[[u16; 3]; 3] as Bar>
<[u16; 4] as Bar>
error[E0308]: mismatched types error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
--> $DIR/issue-67185-2.rs:28:1 --> $DIR/issue-67185-2.rs:31:14
| |
LL | fn f(_: impl Foo) {} LL | / trait Foo
| ^^^^^^^^^^^^^^^^^^^^ expected `2usize`, found `3usize` LL | |
LL | | where
LL | | [<u8 as Baz>::Quaks; 2]: Bar,
LL | | <u8 as Baz>::Quaks: Bar,
LL | | {
LL | | }
| |_- required by `Foo`
...
LL | fn f(_: impl Foo) {}
| ^^^ the trait `Bar` is not implemented for `[[u16; 3]; 2]`
| |
= note: expected type `2usize` = help: the following implementations were found:
found type `3usize` <[[u16; 3]; 3] as Bar>
<[u16; 4] as Bar>
error[E0308]: mismatched types error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
--> $DIR/issue-67185-2.rs:28:1 --> $DIR/issue-67185-2.rs:31:14
| |
LL | fn f(_: impl Foo) {} LL | / trait Foo
| ^^^^^^^^^^^^^^^^^^^^ expected `3usize`, found `4usize` LL | |
LL | | where
LL | | [<u8 as Baz>::Quaks; 2]: Bar,
LL | | <u8 as Baz>::Quaks: Bar,
LL | | {
LL | | }
| |_- required by `Foo`
...
LL | fn f(_: impl Foo) {}
| ^^^ the trait `Bar` is not implemented for `[u16; 3]`
| |
= note: expected type `3usize` = help: the following implementations were found:
found type `4usize` <[[u16; 3]; 3] as Bar>
<[u16; 4] as Bar>
error: aborting due to 5 previous errors error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0308`. For more information about this error, try `rustc --explain E0277`.