Auto merge of #61812 - jonas-schievink:assoc-ty-defaults, r=nikomatsakis
Implement RFC 2532 – Associated Type Defaults This is a partial implementation that is still missing the changes to object types, since I ran into some trouble while implementing that. I'm opening this part already to get feedback on the implementation and the unexpected test fallout (see my comments below). The remaining changes can be done in a later PR. Blockers before this can land: * [x] Resolve unsoundness around interaction with specialization (https://github.com/rust-lang/rust/pull/61812#discussion_r300504010) - #64564 cc https://github.com/rust-lang/rust/issues/29661 Fixes #53907 Fixes #54182 Fixes #62211 Fixes #41868 Fixes #63593 Fixes #47385 Fixes #43924 Fixes #32350 Fixes #26681 Fixes https://github.com/rust-lang/rust/issues/67187
This commit is contained in:
commit
3a0d106109
53 changed files with 2048 additions and 154 deletions
|
@ -1,9 +1,11 @@
|
||||||
|
#### Note: this error code is no longer emitted by the compiler
|
||||||
|
|
||||||
You implemented a trait, overriding one or more of its associated types but did
|
You implemented a trait, overriding one or more of its associated types but did
|
||||||
not reimplement its default methods.
|
not reimplement its default methods.
|
||||||
|
|
||||||
Example of erroneous code:
|
Example of erroneous code:
|
||||||
|
|
||||||
```compile_fail,E0399
|
```
|
||||||
#![feature(associated_type_defaults)]
|
#![feature(associated_type_defaults)]
|
||||||
|
|
||||||
pub trait Foo {
|
pub trait Foo {
|
||||||
|
|
|
@ -1054,25 +1054,40 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
||||||
// an error when we confirm the candidate
|
// an error when we confirm the candidate
|
||||||
// (which will ultimately lead to `normalize_to_error`
|
// (which will ultimately lead to `normalize_to_error`
|
||||||
// being invoked).
|
// being invoked).
|
||||||
node_item.item.defaultness.has_value()
|
false
|
||||||
} else {
|
} else {
|
||||||
|
// If we're looking at a trait *impl*, the item is
|
||||||
|
// specializable if the impl or the item are marked
|
||||||
|
// `default`.
|
||||||
node_item.item.defaultness.is_default()
|
node_item.item.defaultness.is_default()
|
||||||
|| super::util::impl_is_default(selcx.tcx(), node_item.node.def_id())
|
|| super::util::impl_is_default(selcx.tcx(), node_item.node.def_id())
|
||||||
};
|
};
|
||||||
|
|
||||||
// Only reveal a specializable default if we're past type-checking
|
match is_default {
|
||||||
// and the obligations is monomorphic, otherwise passes such as
|
// Non-specializable items are always projectable
|
||||||
// transmute checking and polymorphic MIR optimizations could
|
false => true,
|
||||||
// get a result which isn't correct for all monomorphizations.
|
|
||||||
if !is_default {
|
// Only reveal a specializable default if we're past type-checking
|
||||||
true
|
// and the obligation is monomorphic, otherwise passes such as
|
||||||
} else if obligation.param_env.reveal == Reveal::All {
|
// transmute checking and polymorphic MIR optimizations could
|
||||||
// NOTE(eddyb) inference variables can resolve to parameters, so
|
// get a result which isn't correct for all monomorphizations.
|
||||||
// assume `poly_trait_ref` isn't monomorphic, if it contains any.
|
true if obligation.param_env.reveal == Reveal::All => {
|
||||||
let poly_trait_ref = selcx.infcx().resolve_vars_if_possible(&poly_trait_ref);
|
// NOTE(eddyb) inference variables can resolve to parameters, so
|
||||||
!poly_trait_ref.needs_infer() && !poly_trait_ref.needs_subst()
|
// assume `poly_trait_ref` isn't monomorphic, if it contains any.
|
||||||
} else {
|
let poly_trait_ref =
|
||||||
false
|
selcx.infcx().resolve_vars_if_possible(&poly_trait_ref);
|
||||||
|
!poly_trait_ref.needs_infer() && !poly_trait_ref.needs_subst()
|
||||||
|
}
|
||||||
|
|
||||||
|
true => {
|
||||||
|
debug!(
|
||||||
|
"assemble_candidates_from_impls: not eligible due to default: \
|
||||||
|
assoc_ty={} predicate={}",
|
||||||
|
selcx.tcx().def_path_str(node_item.item.def_id),
|
||||||
|
obligation.predicate,
|
||||||
|
);
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super::VtableParam(..) => {
|
super::VtableParam(..) => {
|
||||||
|
|
|
@ -1964,7 +1964,6 @@ fn check_impl_items_against_trait<'tcx>(
|
||||||
|
|
||||||
// Locate trait definition and items
|
// Locate trait definition and items
|
||||||
let trait_def = tcx.trait_def(impl_trait_ref.def_id);
|
let trait_def = tcx.trait_def(impl_trait_ref.def_id);
|
||||||
let mut overridden_associated_type = None;
|
|
||||||
|
|
||||||
let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id));
|
let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id));
|
||||||
|
|
||||||
|
@ -2046,9 +2045,6 @@ fn check_impl_items_against_trait<'tcx>(
|
||||||
hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(_) => {
|
hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(_) => {
|
||||||
let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
|
let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
|
||||||
if ty_trait_item.kind == ty::AssocKind::Type {
|
if ty_trait_item.kind == ty::AssocKind::Type {
|
||||||
if ty_trait_item.defaultness.has_value() {
|
|
||||||
overridden_associated_type = Some(impl_item);
|
|
||||||
}
|
|
||||||
compare_ty_impl(
|
compare_ty_impl(
|
||||||
tcx,
|
tcx,
|
||||||
&ty_impl_item,
|
&ty_impl_item,
|
||||||
|
@ -2082,8 +2078,6 @@ fn check_impl_items_against_trait<'tcx>(
|
||||||
|
|
||||||
// Check for missing items from trait
|
// Check for missing items from trait
|
||||||
let mut missing_items = Vec::new();
|
let mut missing_items = Vec::new();
|
||||||
let mut invalidated_items = Vec::new();
|
|
||||||
let associated_type_overridden = overridden_associated_type.is_some();
|
|
||||||
for trait_item in tcx.associated_items(impl_trait_ref.def_id).in_definition_order() {
|
for trait_item in tcx.associated_items(impl_trait_ref.def_id).in_definition_order() {
|
||||||
let is_implemented = trait_def
|
let is_implemented = trait_def
|
||||||
.ancestors(tcx, impl_id)
|
.ancestors(tcx, impl_id)
|
||||||
|
@ -2094,8 +2088,6 @@ fn check_impl_items_against_trait<'tcx>(
|
||||||
if !is_implemented && !traits::impl_is_default(tcx, impl_id) {
|
if !is_implemented && !traits::impl_is_default(tcx, impl_id) {
|
||||||
if !trait_item.defaultness.has_value() {
|
if !trait_item.defaultness.has_value() {
|
||||||
missing_items.push(*trait_item);
|
missing_items.push(*trait_item);
|
||||||
} else if associated_type_overridden {
|
|
||||||
invalidated_items.push(trait_item.ident);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2103,19 +2095,6 @@ fn check_impl_items_against_trait<'tcx>(
|
||||||
if !missing_items.is_empty() {
|
if !missing_items.is_empty() {
|
||||||
missing_items_err(tcx, impl_span, &missing_items, full_impl_span);
|
missing_items_err(tcx, impl_span, &missing_items, full_impl_span);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !invalidated_items.is_empty() {
|
|
||||||
let invalidator = overridden_associated_type.unwrap();
|
|
||||||
struct_span_err!(
|
|
||||||
tcx.sess,
|
|
||||||
invalidator.span,
|
|
||||||
E0399,
|
|
||||||
"the following trait items need to be reimplemented as `{}` was overridden: `{}`",
|
|
||||||
invalidator.ident,
|
|
||||||
invalidated_items.iter().map(|name| name.to_string()).collect::<Vec<_>>().join("`, `")
|
|
||||||
)
|
|
||||||
.emit();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn missing_items_err(
|
fn missing_items_err(
|
||||||
|
|
|
@ -425,10 +425,109 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) {
|
||||||
|
|
||||||
for_item(tcx, item).with_fcx(|fcx, _| {
|
for_item(tcx, item).with_fcx(|fcx, _| {
|
||||||
check_where_clauses(tcx, fcx, item.span, trait_def_id, None);
|
check_where_clauses(tcx, fcx, item.span, trait_def_id, None);
|
||||||
|
check_associated_type_defaults(fcx, trait_def_id);
|
||||||
|
|
||||||
vec![]
|
vec![]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Checks all associated type defaults of trait `trait_def_id`.
|
||||||
|
///
|
||||||
|
/// Assuming the defaults are used, check that all predicates (bounds on the
|
||||||
|
/// assoc type and where clauses on the trait) hold.
|
||||||
|
fn check_associated_type_defaults(fcx: &FnCtxt<'_, '_>, trait_def_id: DefId) {
|
||||||
|
let tcx = fcx.tcx;
|
||||||
|
let substs = InternalSubsts::identity_for_item(tcx, trait_def_id);
|
||||||
|
|
||||||
|
// For all assoc. types with defaults, build a map from
|
||||||
|
// `<Self as Trait<...>>::Assoc` to the default type.
|
||||||
|
let map = tcx
|
||||||
|
.associated_items(trait_def_id)
|
||||||
|
.in_definition_order()
|
||||||
|
.filter_map(|item| {
|
||||||
|
if item.kind == ty::AssocKind::Type && item.defaultness.has_value() {
|
||||||
|
// `<Self as Trait<...>>::Assoc`
|
||||||
|
let proj = ty::ProjectionTy { substs, item_def_id: item.def_id };
|
||||||
|
let default_ty = tcx.type_of(item.def_id);
|
||||||
|
debug!("assoc. type default mapping: {} -> {}", proj, default_ty);
|
||||||
|
Some((proj, default_ty))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<FxHashMap<_, _>>();
|
||||||
|
|
||||||
|
/// Replaces projections of associated types with their default types.
|
||||||
|
///
|
||||||
|
/// This does a "shallow substitution", meaning that defaults that refer to
|
||||||
|
/// other defaulted assoc. types will still refer to the projection
|
||||||
|
/// afterwards, not to the other default. For example:
|
||||||
|
///
|
||||||
|
/// ```compile_fail
|
||||||
|
/// trait Tr {
|
||||||
|
/// type A: Clone = Vec<Self::B>;
|
||||||
|
/// type B = u8;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// This will end up replacing the bound `Self::A: Clone` with
|
||||||
|
/// `Vec<Self::B>: Clone`, not with `Vec<u8>: Clone`. If we did a deep
|
||||||
|
/// substitution and ended up with the latter, the trait would be accepted.
|
||||||
|
/// If an `impl` then replaced `B` with something that isn't `Clone`,
|
||||||
|
/// suddenly the default for `A` is no longer valid. The shallow
|
||||||
|
/// substitution forces the trait to add a `B: Clone` bound to be accepted,
|
||||||
|
/// which means that an `impl` can replace any default without breaking
|
||||||
|
/// others.
|
||||||
|
///
|
||||||
|
/// Note that this isn't needed for soundness: The defaults would still be
|
||||||
|
/// checked in any impl that doesn't override them.
|
||||||
|
struct DefaultNormalizer<'tcx> {
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
map: FxHashMap<ty::ProjectionTy<'tcx>, Ty<'tcx>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> ty::fold::TypeFolder<'tcx> for DefaultNormalizer<'tcx> {
|
||||||
|
fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
|
||||||
|
self.tcx
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
|
match t.kind {
|
||||||
|
ty::Projection(proj_ty) => {
|
||||||
|
if let Some(default) = self.map.get(&proj_ty) {
|
||||||
|
default
|
||||||
|
} else {
|
||||||
|
t.super_fold_with(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => t.super_fold_with(self),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now take all predicates defined on the trait, replace any mention of
|
||||||
|
// the assoc. types with their default, and prove them.
|
||||||
|
// We only consider predicates that directly mention the assoc. type.
|
||||||
|
let mut norm = DefaultNormalizer { tcx, map };
|
||||||
|
let predicates = fcx.tcx.predicates_of(trait_def_id);
|
||||||
|
for &(orig_pred, span) in predicates.predicates.iter() {
|
||||||
|
let pred = orig_pred.fold_with(&mut norm);
|
||||||
|
if pred != orig_pred {
|
||||||
|
// Mentions one of the defaulted assoc. types
|
||||||
|
debug!("default suitability check: proving predicate: {} -> {}", orig_pred, pred);
|
||||||
|
let pred = fcx.normalize_associated_types_in(span, &pred);
|
||||||
|
let cause = traits::ObligationCause::new(
|
||||||
|
span,
|
||||||
|
fcx.body_id,
|
||||||
|
traits::ItemObligation(trait_def_id),
|
||||||
|
);
|
||||||
|
let obligation = traits::Obligation::new(cause, fcx.param_env, pred);
|
||||||
|
|
||||||
|
fcx.register_predicate(obligation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn check_item_fn(tcx: TyCtxt<'_>, item: &hir::Item<'_>) {
|
fn check_item_fn(tcx: TyCtxt<'_>, item: &hir::Item<'_>) {
|
||||||
for_item(tcx, item).with_fcx(|fcx, tcx| {
|
for_item(tcx, item).with_fcx(|fcx, tcx| {
|
||||||
let def_id = fcx.tcx.hir().local_def_id(item.hir_id);
|
let def_id = fcx.tcx.hir().local_def_id(item.hir_id);
|
||||||
|
|
17
src/test/ui/associated-const/defaults-cyclic-fail.rs
Normal file
17
src/test/ui/associated-const/defaults-cyclic-fail.rs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// build-fail
|
||||||
|
|
||||||
|
// Cyclic assoc. const defaults don't error unless *used*
|
||||||
|
trait Tr {
|
||||||
|
const A: u8 = Self::B;
|
||||||
|
//~^ ERROR cycle detected when const-evaluating + checking `Tr::A`
|
||||||
|
|
||||||
|
const B: u8 = Self::A;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This impl is *allowed* unless its assoc. consts are used
|
||||||
|
impl Tr for () {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// This triggers the cycle error
|
||||||
|
assert_eq!(<() as Tr>::A, 0);
|
||||||
|
}
|
31
src/test/ui/associated-const/defaults-cyclic-fail.stderr
Normal file
31
src/test/ui/associated-const/defaults-cyclic-fail.stderr
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
error[E0391]: cycle detected when const-evaluating + checking `Tr::A`
|
||||||
|
--> $DIR/defaults-cyclic-fail.rs:5:5
|
||||||
|
|
|
||||||
|
LL | const A: u8 = Self::B;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: ...which requires const-evaluating `Tr::A`...
|
||||||
|
--> $DIR/defaults-cyclic-fail.rs:5:19
|
||||||
|
|
|
||||||
|
LL | const A: u8 = Self::B;
|
||||||
|
| ^^^^^^^
|
||||||
|
note: ...which requires const-evaluating + checking `Tr::B`...
|
||||||
|
--> $DIR/defaults-cyclic-fail.rs:8:5
|
||||||
|
|
|
||||||
|
LL | const B: u8 = Self::A;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
note: ...which requires const-evaluating `Tr::B`...
|
||||||
|
--> $DIR/defaults-cyclic-fail.rs:8:19
|
||||||
|
|
|
||||||
|
LL | const B: u8 = Self::A;
|
||||||
|
| ^^^^^^^
|
||||||
|
= note: ...which again requires const-evaluating + checking `Tr::A`, completing the cycle
|
||||||
|
note: cycle used when const-evaluating `main`
|
||||||
|
--> $DIR/defaults-cyclic-fail.rs:16:16
|
||||||
|
|
|
||||||
|
LL | assert_eq!(<() as Tr>::A, 0);
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0391`.
|
36
src/test/ui/associated-const/defaults-cyclic-pass.rs
Normal file
36
src/test/ui/associated-const/defaults-cyclic-pass.rs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// run-pass
|
||||||
|
|
||||||
|
// Cyclic assoc. const defaults don't error unless *used*
|
||||||
|
trait Tr {
|
||||||
|
const A: u8 = Self::B;
|
||||||
|
const B: u8 = Self::A;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This impl is *allowed* unless its assoc. consts are used, matching the
|
||||||
|
// behavior without defaults.
|
||||||
|
impl Tr for () {}
|
||||||
|
|
||||||
|
// Overriding either constant breaks the cycle
|
||||||
|
impl Tr for u8 {
|
||||||
|
const A: u8 = 42;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tr for u16 {
|
||||||
|
const B: u8 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tr for u32 {
|
||||||
|
const A: u8 = 100;
|
||||||
|
const B: u8 = 123;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert_eq!(<u8 as Tr>::A, 42);
|
||||||
|
assert_eq!(<u8 as Tr>::B, 42);
|
||||||
|
|
||||||
|
assert_eq!(<u16 as Tr>::A, 0);
|
||||||
|
assert_eq!(<u16 as Tr>::B, 0);
|
||||||
|
|
||||||
|
assert_eq!(<u32 as Tr>::A, 100);
|
||||||
|
assert_eq!(<u32 as Tr>::B, 123);
|
||||||
|
}
|
45
src/test/ui/associated-const/defaults-not-assumed-fail.rs
Normal file
45
src/test/ui/associated-const/defaults-not-assumed-fail.rs
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
// build-fail
|
||||||
|
|
||||||
|
trait Tr {
|
||||||
|
const A: u8 = 255;
|
||||||
|
|
||||||
|
// This should not be a constant evaluation error (overflow). The value of
|
||||||
|
// `Self::A` must not be assumed to hold inside the trait.
|
||||||
|
const B: u8 = Self::A + 1;
|
||||||
|
//~^ ERROR any use of this value will cause an error
|
||||||
|
}
|
||||||
|
|
||||||
|
// An impl that doesn't override any constant will NOT cause a const eval error
|
||||||
|
// just because it's defined, but only if the bad constant is used anywhere.
|
||||||
|
// This matches the behavior without defaults.
|
||||||
|
impl Tr for () {}
|
||||||
|
|
||||||
|
// An impl that overrides either constant with a suitable value will be fine.
|
||||||
|
impl Tr for u8 {
|
||||||
|
const A: u8 = 254;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tr for u16 {
|
||||||
|
const B: u8 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tr for u32 {
|
||||||
|
const A: u8 = 254;
|
||||||
|
const B: u8 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert_eq!(<() as Tr>::A, 255);
|
||||||
|
assert_eq!(<() as Tr>::B, 0); // causes the error above
|
||||||
|
//~^ ERROR evaluation of constant expression failed
|
||||||
|
//~| ERROR erroneous constant used
|
||||||
|
|
||||||
|
assert_eq!(<u8 as Tr>::A, 254);
|
||||||
|
assert_eq!(<u8 as Tr>::B, 255);
|
||||||
|
|
||||||
|
assert_eq!(<u16 as Tr>::A, 255);
|
||||||
|
assert_eq!(<u16 as Tr>::B, 0);
|
||||||
|
|
||||||
|
assert_eq!(<u32 as Tr>::A, 254);
|
||||||
|
assert_eq!(<u32 as Tr>::B, 0);
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
error: any use of this value will cause an error
|
||||||
|
--> $DIR/defaults-not-assumed-fail.rs:8:19
|
||||||
|
|
|
||||||
|
LL | const B: u8 = Self::A + 1;
|
||||||
|
| --------------^^^^^^^^^^^-
|
||||||
|
| |
|
||||||
|
| attempt to add with overflow
|
||||||
|
|
|
||||||
|
= note: `#[deny(const_err)]` on by default
|
||||||
|
|
||||||
|
error[E0080]: evaluation of constant expression failed
|
||||||
|
--> $DIR/defaults-not-assumed-fail.rs:33:5
|
||||||
|
|
|
||||||
|
LL | assert_eq!(<() as Tr>::B, 0); // causes the error above
|
||||||
|
| ^^^^^^^^^^^-------------^^^^^
|
||||||
|
| |
|
||||||
|
| referenced constant has errors
|
||||||
|
|
|
||||||
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: erroneous constant used
|
||||||
|
--> $DIR/defaults-not-assumed-fail.rs:33:5
|
||||||
|
|
|
||||||
|
LL | assert_eq!(<() as Tr>::B, 0); // causes the error above
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
|
||||||
|
|
|
||||||
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0080`.
|
42
src/test/ui/associated-const/defaults-not-assumed-pass.rs
Normal file
42
src/test/ui/associated-const/defaults-not-assumed-pass.rs
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
// run-pass
|
||||||
|
|
||||||
|
trait Tr {
|
||||||
|
const A: u8 = 255;
|
||||||
|
|
||||||
|
// This should not be a constant evaluation error (overflow). The value of
|
||||||
|
// `Self::A` must not be assumed to hold inside the trait.
|
||||||
|
const B: u8 = Self::A + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// An impl that doesn't override any constant will NOT cause a const eval error
|
||||||
|
// just because it's defined, but only if the bad constant is used anywhere.
|
||||||
|
// This matches the behavior without defaults.
|
||||||
|
impl Tr for () {}
|
||||||
|
|
||||||
|
// An impl that overrides either constant with a suitable value will be fine.
|
||||||
|
impl Tr for u8 {
|
||||||
|
const A: u8 = 254;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tr for u16 {
|
||||||
|
const B: u8 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tr for u32 {
|
||||||
|
const A: u8 = 254;
|
||||||
|
const B: u8 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert_eq!(<() as Tr>::A, 255);
|
||||||
|
//assert_eq!(<() as Tr>::B, 0); // using this is an error
|
||||||
|
|
||||||
|
assert_eq!(<u8 as Tr>::A, 254);
|
||||||
|
assert_eq!(<u8 as Tr>::B, 255);
|
||||||
|
|
||||||
|
assert_eq!(<u16 as Tr>::A, 255);
|
||||||
|
assert_eq!(<u16 as Tr>::B, 0);
|
||||||
|
|
||||||
|
assert_eq!(<u32 as Tr>::A, 254);
|
||||||
|
assert_eq!(<u32 as Tr>::B, 0);
|
||||||
|
}
|
|
@ -1,3 +1,8 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
// Before RFC 2532, overriding one assoc. type default required overriding all
|
||||||
|
// provided defaults.
|
||||||
|
|
||||||
#![feature(associated_type_defaults)]
|
#![feature(associated_type_defaults)]
|
||||||
|
|
||||||
pub trait Tr {
|
pub trait Tr {
|
||||||
|
@ -9,7 +14,9 @@ pub trait Tr {
|
||||||
|
|
||||||
impl Tr for () {
|
impl Tr for () {
|
||||||
type Assoc = ();
|
type Assoc = ();
|
||||||
//~^ ERROR need to be reimplemented as `Assoc` was overridden: `Assoc2`, `C`, `foo`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {
|
||||||
|
let _: <() as Tr>::Assoc = ();
|
||||||
|
let _: <() as Tr>::Assoc2 = ();
|
||||||
|
}
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
error[E0399]: the following trait items need to be reimplemented as `Assoc` was overridden: `Assoc2`, `C`, `foo`
|
|
||||||
--> $DIR/associated-types-overridden-default.rs:11:5
|
|
||||||
|
|
|
||||||
LL | type Assoc = ();
|
|
||||||
| ^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0399`.
|
|
45
src/test/ui/associated-types/defaults-cyclic-fail-1.rs
Normal file
45
src/test/ui/associated-types/defaults-cyclic-fail-1.rs
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#![feature(associated_type_defaults)]
|
||||||
|
|
||||||
|
// Having a cycle in assoc. type defaults is okay...
|
||||||
|
trait Tr {
|
||||||
|
type A = Self::B;
|
||||||
|
type B = Self::A;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...but is an error in any impl that doesn't override at least one of the defaults
|
||||||
|
impl Tr for () {}
|
||||||
|
//~^ ERROR overflow evaluating the requirement
|
||||||
|
|
||||||
|
// As soon as at least one is redefined, it works:
|
||||||
|
impl Tr for u8 {
|
||||||
|
type A = u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tr for u16 {
|
||||||
|
type B = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tr for u32 {
|
||||||
|
type A = ();
|
||||||
|
type B = u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...but only if this actually breaks the cycle
|
||||||
|
impl Tr for bool {
|
||||||
|
//~^ ERROR overflow evaluating the requirement
|
||||||
|
type A = Box<Self::B>;
|
||||||
|
//~^ ERROR overflow evaluating the requirement
|
||||||
|
}
|
||||||
|
// (the error is shown twice for some reason)
|
||||||
|
|
||||||
|
impl Tr for usize {
|
||||||
|
//~^ ERROR overflow evaluating the requirement
|
||||||
|
type B = &'static Self::A;
|
||||||
|
//~^ ERROR overflow evaluating the requirement
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// We don't check that the types project correctly because the cycle errors stop compilation
|
||||||
|
// before `main` is type-checked.
|
||||||
|
// `defaults-cyclic-pass-1.rs` does this.
|
||||||
|
}
|
33
src/test/ui/associated-types/defaults-cyclic-fail-1.stderr
Normal file
33
src/test/ui/associated-types/defaults-cyclic-fail-1.stderr
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
error[E0275]: overflow evaluating the requirement `<() as Tr>::B`
|
||||||
|
--> $DIR/defaults-cyclic-fail-1.rs:10:6
|
||||||
|
|
|
||||||
|
LL | impl Tr for () {}
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error[E0275]: overflow evaluating the requirement `<bool as Tr>::B`
|
||||||
|
--> $DIR/defaults-cyclic-fail-1.rs:28:6
|
||||||
|
|
|
||||||
|
LL | impl Tr for bool {
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error[E0275]: overflow evaluating the requirement `<usize as Tr>::B`
|
||||||
|
--> $DIR/defaults-cyclic-fail-1.rs:35:6
|
||||||
|
|
|
||||||
|
LL | impl Tr for usize {
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error[E0275]: overflow evaluating the requirement `<bool as Tr>::B`
|
||||||
|
--> $DIR/defaults-cyclic-fail-1.rs:30:5
|
||||||
|
|
|
||||||
|
LL | type A = Box<Self::B>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0275]: overflow evaluating the requirement `<usize as Tr>::A`
|
||||||
|
--> $DIR/defaults-cyclic-fail-1.rs:37:5
|
||||||
|
|
|
||||||
|
LL | type B = &'static Self::A;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0275`.
|
47
src/test/ui/associated-types/defaults-cyclic-fail-2.rs
Normal file
47
src/test/ui/associated-types/defaults-cyclic-fail-2.rs
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
#![feature(associated_type_defaults)]
|
||||||
|
|
||||||
|
// A more complex version of `defaults-cyclic-fail-1.rs`, with non-trivial defaults.
|
||||||
|
|
||||||
|
// Having a cycle in assoc. type defaults is okay...
|
||||||
|
trait Tr {
|
||||||
|
type A = Vec<Self::B>;
|
||||||
|
type B = Box<Self::A>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...but is an error in any impl that doesn't override at least one of the defaults
|
||||||
|
impl Tr for () {}
|
||||||
|
//~^ ERROR overflow evaluating the requirement
|
||||||
|
|
||||||
|
// As soon as at least one is redefined, it works:
|
||||||
|
impl Tr for u8 {
|
||||||
|
type A = u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tr for u16 {
|
||||||
|
type B = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tr for u32 {
|
||||||
|
type A = ();
|
||||||
|
type B = u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...but only if this actually breaks the cycle
|
||||||
|
impl Tr for bool {
|
||||||
|
//~^ ERROR overflow evaluating the requirement
|
||||||
|
type A = Box<Self::B>;
|
||||||
|
//~^ ERROR overflow evaluating the requirement
|
||||||
|
}
|
||||||
|
// (the error is shown twice for some reason)
|
||||||
|
|
||||||
|
impl Tr for usize {
|
||||||
|
//~^ ERROR overflow evaluating the requirement
|
||||||
|
type B = &'static Self::A;
|
||||||
|
//~^ ERROR overflow evaluating the requirement
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// We don't check that the types project correctly because the cycle errors stop compilation
|
||||||
|
// before `main` is type-checked.
|
||||||
|
// `defaults-cyclic-pass-2.rs` does this.
|
||||||
|
}
|
33
src/test/ui/associated-types/defaults-cyclic-fail-2.stderr
Normal file
33
src/test/ui/associated-types/defaults-cyclic-fail-2.stderr
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
error[E0275]: overflow evaluating the requirement `<() as Tr>::B`
|
||||||
|
--> $DIR/defaults-cyclic-fail-2.rs:12:6
|
||||||
|
|
|
||||||
|
LL | impl Tr for () {}
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error[E0275]: overflow evaluating the requirement `<bool as Tr>::B`
|
||||||
|
--> $DIR/defaults-cyclic-fail-2.rs:30:6
|
||||||
|
|
|
||||||
|
LL | impl Tr for bool {
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error[E0275]: overflow evaluating the requirement `<usize as Tr>::B`
|
||||||
|
--> $DIR/defaults-cyclic-fail-2.rs:37:6
|
||||||
|
|
|
||||||
|
LL | impl Tr for usize {
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error[E0275]: overflow evaluating the requirement `<bool as Tr>::B`
|
||||||
|
--> $DIR/defaults-cyclic-fail-2.rs:32:5
|
||||||
|
|
|
||||||
|
LL | type A = Box<Self::B>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0275]: overflow evaluating the requirement `<usize as Tr>::A`
|
||||||
|
--> $DIR/defaults-cyclic-fail-2.rs:39:5
|
||||||
|
|
|
||||||
|
LL | type B = &'static Self::A;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0275`.
|
56
src/test/ui/associated-types/defaults-cyclic-pass-1.rs
Normal file
56
src/test/ui/associated-types/defaults-cyclic-pass-1.rs
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(associated_type_defaults)]
|
||||||
|
|
||||||
|
// Having a cycle in assoc. type defaults is okay, as long as there's no impl
|
||||||
|
// that retains it.
|
||||||
|
trait Tr {
|
||||||
|
type A = Self::B;
|
||||||
|
type B = Self::A;
|
||||||
|
|
||||||
|
fn f();
|
||||||
|
}
|
||||||
|
|
||||||
|
// An impl has to break the cycle to be accepted.
|
||||||
|
impl Tr for u8 {
|
||||||
|
type A = u8;
|
||||||
|
|
||||||
|
fn f() {
|
||||||
|
// Check that the type propagates as expected (seen from inside the impl)
|
||||||
|
let _: Self::A = 0u8;
|
||||||
|
let _: Self::B = 0u8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tr for String {
|
||||||
|
type B = ();
|
||||||
|
|
||||||
|
fn f() {
|
||||||
|
// Check that the type propagates as expected (seen from inside the impl)
|
||||||
|
let _: Self::A = ();
|
||||||
|
let _: Self::B = ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tr for () {
|
||||||
|
type A = Vec<()>;
|
||||||
|
type B = u8;
|
||||||
|
|
||||||
|
fn f() {
|
||||||
|
// Check that the type propagates as expected (seen from inside the impl)
|
||||||
|
let _: Self::A = Vec::<()>::new();
|
||||||
|
let _: Self::B = 0u8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Check that both impls now have the right types (seen from outside the impls)
|
||||||
|
let _: <u8 as Tr>::A = 0u8;
|
||||||
|
let _: <u8 as Tr>::B = 0u8;
|
||||||
|
|
||||||
|
let _: <String as Tr>::A = ();
|
||||||
|
let _: <String as Tr>::B = ();
|
||||||
|
|
||||||
|
let _: <() as Tr>::A = Vec::<()>::new();
|
||||||
|
let _: <() as Tr>::B = 0u8;
|
||||||
|
}
|
56
src/test/ui/associated-types/defaults-cyclic-pass-2.rs
Normal file
56
src/test/ui/associated-types/defaults-cyclic-pass-2.rs
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(associated_type_defaults)]
|
||||||
|
|
||||||
|
// Having a cycle in assoc. type defaults is okay, as long as there's no impl
|
||||||
|
// that retains it.
|
||||||
|
trait Tr {
|
||||||
|
type A = Vec<Self::B>;
|
||||||
|
type B = Box<Self::A>;
|
||||||
|
|
||||||
|
fn f();
|
||||||
|
}
|
||||||
|
|
||||||
|
// An impl has to break the cycle to be accepted.
|
||||||
|
impl Tr for u8 {
|
||||||
|
type A = u8;
|
||||||
|
|
||||||
|
fn f() {
|
||||||
|
// Check that the type propagates as expected (seen from inside the impl)
|
||||||
|
let _: Self::A = 0u8;
|
||||||
|
let _: Self::B = Box::new(0u8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tr for String {
|
||||||
|
type B = ();
|
||||||
|
|
||||||
|
fn f() {
|
||||||
|
// Check that the type propagates as expected (seen from inside the impl)
|
||||||
|
let _: Self::A = Vec::<()>::new();
|
||||||
|
let _: Self::B = ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tr for () {
|
||||||
|
type A = Vec<()>;
|
||||||
|
type B = u8;
|
||||||
|
|
||||||
|
fn f() {
|
||||||
|
// Check that the type propagates as expected (seen from inside the impl)
|
||||||
|
let _: Self::A = Vec::<()>::new();
|
||||||
|
let _: Self::B = 0u8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Check that both impls now have the right types (seen from outside the impls)
|
||||||
|
let _: <u8 as Tr>::A = 0u8;
|
||||||
|
let _: <u8 as Tr>::B = Box::new(0u8);
|
||||||
|
|
||||||
|
let _: <String as Tr>::A = Vec::<()>::new();
|
||||||
|
let _: <String as Tr>::B = ();
|
||||||
|
|
||||||
|
let _: <() as Tr>::A = Vec::<()>::new();
|
||||||
|
let _: <() as Tr>::B = 0u8;
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(associated_type_defaults)]
|
||||||
|
|
||||||
|
trait Tr {
|
||||||
|
type Item = u8;
|
||||||
|
type Container = Vec<Self::Item>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tr for () {}
|
||||||
|
|
||||||
|
impl Tr for u16 {
|
||||||
|
type Item = u16;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tr for String {
|
||||||
|
type Container = String;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tr for usize {
|
||||||
|
type Item = u32;
|
||||||
|
type Container = Vec<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _container: <() as Tr>::Container = Vec::<u8>::new();
|
||||||
|
let _item: <() as Tr>::Item = 0u8;
|
||||||
|
|
||||||
|
let _container: <u16 as Tr>::Container = Vec::<u16>::new();
|
||||||
|
let _item: <u16 as Tr>::Item = 0u16;
|
||||||
|
|
||||||
|
let _container: <String as Tr>::Container = String::new();
|
||||||
|
let _item: <String as Tr>::Item = 0u8;
|
||||||
|
|
||||||
|
let _container: <usize as Tr>::Container = Vec::<()>::new();
|
||||||
|
let _item: <usize as Tr>::Item = 0u32;
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
#![feature(associated_type_defaults)]
|
||||||
|
|
||||||
|
// Associated type defaults may not be assumed inside the trait defining them.
|
||||||
|
// ie. they only resolve to `<Self as Tr>::A`, not the actual type `()`
|
||||||
|
trait Tr {
|
||||||
|
type A = ();
|
||||||
|
|
||||||
|
fn f(p: Self::A) {
|
||||||
|
let () = p;
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
//~| NOTE expected associated type, found `()`
|
||||||
|
//~| NOTE expected associated type `<Self as Tr>::A`
|
||||||
|
//~| NOTE consider constraining the associated type
|
||||||
|
//~| NOTE for more information, visit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// An impl that doesn't override the type *can* assume the default.
|
||||||
|
impl Tr for () {
|
||||||
|
fn f(p: Self::A) {
|
||||||
|
let () = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tr for u8 {
|
||||||
|
type A = ();
|
||||||
|
|
||||||
|
fn f(p: Self::A) {
|
||||||
|
let () = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait AssocConst {
|
||||||
|
type Ty = u8;
|
||||||
|
|
||||||
|
// Assoc. consts also cannot assume that default types hold
|
||||||
|
const C: Self::Ty = 0u8;
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
//~| NOTE expected associated type, found `u8`
|
||||||
|
//~| NOTE expected associated type `<Self as AssocConst>::Ty`
|
||||||
|
//~| NOTE consider constraining the associated type
|
||||||
|
//~| NOTE for more information, visit
|
||||||
|
}
|
||||||
|
|
||||||
|
// An impl can, however
|
||||||
|
impl AssocConst for () {
|
||||||
|
const C: Self::Ty = 0u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,25 @@
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/defaults-in-other-trait-items.rs:9:13
|
||||||
|
|
|
||||||
|
LL | let () = p;
|
||||||
|
| ^^ expected associated type, found `()`
|
||||||
|
|
|
||||||
|
= note: expected associated type `<Self as Tr>::A`
|
||||||
|
found unit type `()`
|
||||||
|
= note: consider constraining the associated type `<Self as Tr>::A` to `()` or calling a method that returns `<Self as Tr>::A`
|
||||||
|
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/defaults-in-other-trait-items.rs:37:25
|
||||||
|
|
|
||||||
|
LL | const C: Self::Ty = 0u8;
|
||||||
|
| ^^^ expected associated type, found `u8`
|
||||||
|
|
|
||||||
|
= note: expected associated type `<Self as AssocConst>::Ty`
|
||||||
|
found type `u8`
|
||||||
|
= note: consider constraining the associated type `<Self as AssocConst>::Ty` to `u8` or calling a method that returns `<Self as AssocConst>::Ty`
|
||||||
|
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
34
src/test/ui/associated-types/defaults-mixed.rs
Normal file
34
src/test/ui/associated-types/defaults-mixed.rs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#![feature(associated_type_defaults)]
|
||||||
|
|
||||||
|
// Tests that a trait with one defaulted and one non-defaulted assoc. type behaves properly.
|
||||||
|
|
||||||
|
trait Trait {
|
||||||
|
type Foo = u8;
|
||||||
|
type Bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
// `Bar` must be specified
|
||||||
|
impl Trait for () {}
|
||||||
|
//~^ error: not all trait items implemented, missing: `Bar`
|
||||||
|
|
||||||
|
impl Trait for bool {
|
||||||
|
//~^ error: not all trait items implemented, missing: `Bar`
|
||||||
|
type Foo = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trait for u8 {
|
||||||
|
type Bar = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trait for u16 {
|
||||||
|
type Foo = String;
|
||||||
|
type Bar = bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _: <u8 as Trait>::Foo = 0u8;
|
||||||
|
let _: <u8 as Trait>::Bar = ();
|
||||||
|
|
||||||
|
let _: <u16 as Trait>::Foo = String::new();
|
||||||
|
let _: <u16 as Trait>::Bar = true;
|
||||||
|
}
|
21
src/test/ui/associated-types/defaults-mixed.stderr
Normal file
21
src/test/ui/associated-types/defaults-mixed.stderr
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
error[E0046]: not all trait items implemented, missing: `Bar`
|
||||||
|
--> $DIR/defaults-mixed.rs:11:1
|
||||||
|
|
|
||||||
|
LL | type Bar;
|
||||||
|
| --------- `Bar` from trait
|
||||||
|
...
|
||||||
|
LL | impl Trait for () {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^ missing `Bar` in implementation
|
||||||
|
|
||||||
|
error[E0046]: not all trait items implemented, missing: `Bar`
|
||||||
|
--> $DIR/defaults-mixed.rs:14:1
|
||||||
|
|
|
||||||
|
LL | type Bar;
|
||||||
|
| --------- `Bar` from trait
|
||||||
|
...
|
||||||
|
LL | impl Trait for bool {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^ missing `Bar` in implementation
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0046`.
|
95
src/test/ui/associated-types/defaults-specialization.rs
Normal file
95
src/test/ui/associated-types/defaults-specialization.rs
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
//! Tests the interaction of associated type defaults and specialization.
|
||||||
|
|
||||||
|
#![feature(associated_type_defaults, specialization)]
|
||||||
|
|
||||||
|
trait Tr {
|
||||||
|
type Ty = u8;
|
||||||
|
|
||||||
|
fn make() -> Self::Ty {
|
||||||
|
0u8
|
||||||
|
//~^ error: mismatched types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct A<T>(T);
|
||||||
|
// In a `default impl`, assoc. types are defaulted as well,
|
||||||
|
// so their values can't be assumed.
|
||||||
|
default impl<T> Tr for A<T> {
|
||||||
|
fn make() -> u8 { 0 }
|
||||||
|
//~^ ERROR method `make` has an incompatible type for trait
|
||||||
|
}
|
||||||
|
|
||||||
|
struct A2<T>(T);
|
||||||
|
// ...same, but in the method body
|
||||||
|
default impl<T> Tr for A2<T> {
|
||||||
|
fn make() -> Self::Ty { 0u8 }
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
}
|
||||||
|
|
||||||
|
struct B<T>(T);
|
||||||
|
// Explicitly defaulting the type does the same.
|
||||||
|
impl<T> Tr for B<T> {
|
||||||
|
default type Ty = bool;
|
||||||
|
|
||||||
|
fn make() -> bool { true }
|
||||||
|
//~^ ERROR method `make` has an incompatible type for trait
|
||||||
|
}
|
||||||
|
|
||||||
|
struct B2<T>(T);
|
||||||
|
// ...same, but in the method body
|
||||||
|
impl<T> Tr for B2<T> {
|
||||||
|
default type Ty = bool;
|
||||||
|
|
||||||
|
fn make() -> Self::Ty { true }
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
}
|
||||||
|
|
||||||
|
struct C<T>(T);
|
||||||
|
// Only the method is defaulted, so this is fine.
|
||||||
|
impl<T> Tr for C<T> {
|
||||||
|
type Ty = bool;
|
||||||
|
|
||||||
|
default fn make() -> bool { true }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Defaulted method *can* assume the type, if the default is kept.
|
||||||
|
struct D<T>(T);
|
||||||
|
impl<T> Tr for D<T> {
|
||||||
|
default fn make() -> u8 { 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tr for D<bool> {
|
||||||
|
fn make() -> u8 { 255 }
|
||||||
|
}
|
||||||
|
|
||||||
|
struct E<T>(T);
|
||||||
|
impl<T> Tr for E<T> {
|
||||||
|
default type Ty = bool;
|
||||||
|
default fn make() -> Self::Ty { panic!(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
// This impl specializes and sets `Ty`, it can rely on `Ty=String`.
|
||||||
|
impl Tr for E<bool> {
|
||||||
|
type Ty = String;
|
||||||
|
|
||||||
|
fn make() -> String { String::new() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Test that we can assume the right set of assoc. types from outside the impl
|
||||||
|
|
||||||
|
// This is a `default impl`, which does *not* mean that `A`/`A2` actually implement the trait.
|
||||||
|
// cf. https://github.com/rust-lang/rust/issues/48515
|
||||||
|
//let _: <A<()> as Tr>::Ty = 0u8;
|
||||||
|
//let _: <A2<()> as Tr>::Ty = 0u8;
|
||||||
|
|
||||||
|
let _: <B<()> as Tr>::Ty = 0u8; //~ error: mismatched types
|
||||||
|
let _: <B<()> as Tr>::Ty = true; //~ error: mismatched types
|
||||||
|
let _: <B2<()> as Tr>::Ty = 0u8; //~ error: mismatched types
|
||||||
|
let _: <B2<()> as Tr>::Ty = true; //~ error: mismatched types
|
||||||
|
|
||||||
|
let _: <C<()> as Tr>::Ty = true;
|
||||||
|
|
||||||
|
let _: <D<()> as Tr>::Ty = 0u8;
|
||||||
|
let _: <D<bool> as Tr>::Ty = 0u8;
|
||||||
|
}
|
123
src/test/ui/associated-types/defaults-specialization.stderr
Normal file
123
src/test/ui/associated-types/defaults-specialization.stderr
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
error[E0053]: method `make` has an incompatible type for trait
|
||||||
|
--> $DIR/defaults-specialization.rs:18:18
|
||||||
|
|
|
||||||
|
LL | fn make() -> Self::Ty {
|
||||||
|
| -------- type in trait
|
||||||
|
...
|
||||||
|
LL | fn make() -> u8 { 0 }
|
||||||
|
| ^^ expected associated type, found `u8`
|
||||||
|
|
|
||||||
|
= note: expected fn pointer `fn() -> <A<T> as Tr>::Ty`
|
||||||
|
found fn pointer `fn() -> u8`
|
||||||
|
= note: consider constraining the associated type `<A<T> as Tr>::Ty` to `u8` or calling a method that returns `<A<T> as Tr>::Ty`
|
||||||
|
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
||||||
|
|
||||||
|
error[E0053]: method `make` has an incompatible type for trait
|
||||||
|
--> $DIR/defaults-specialization.rs:34:18
|
||||||
|
|
|
||||||
|
LL | fn make() -> Self::Ty {
|
||||||
|
| -------- type in trait
|
||||||
|
...
|
||||||
|
LL | fn make() -> bool { true }
|
||||||
|
| ^^^^ expected associated type, found `bool`
|
||||||
|
|
|
||||||
|
= note: expected fn pointer `fn() -> <B<T> as Tr>::Ty`
|
||||||
|
found fn pointer `fn() -> bool`
|
||||||
|
= note: consider constraining the associated type `<B<T> as Tr>::Ty` to `bool` or calling a method that returns `<B<T> as Tr>::Ty`
|
||||||
|
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/defaults-specialization.rs:9:9
|
||||||
|
|
|
||||||
|
LL | fn make() -> Self::Ty {
|
||||||
|
| -------- expected `<Self as Tr>::Ty` because of return type
|
||||||
|
LL | 0u8
|
||||||
|
| ^^^ expected associated type, found `u8`
|
||||||
|
|
|
||||||
|
= note: expected associated type `<Self as Tr>::Ty`
|
||||||
|
found type `u8`
|
||||||
|
= note: consider constraining the associated type `<Self as Tr>::Ty` to `u8` or calling a method that returns `<Self as Tr>::Ty`
|
||||||
|
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/defaults-specialization.rs:25:29
|
||||||
|
|
|
||||||
|
LL | fn make() -> Self::Ty { 0u8 }
|
||||||
|
| -------- ^^^ expected associated type, found `u8`
|
||||||
|
| |
|
||||||
|
| expected `<A2<T> as Tr>::Ty` because of return type
|
||||||
|
|
|
||||||
|
= note: expected associated type `<A2<T> as Tr>::Ty`
|
||||||
|
found type `u8`
|
||||||
|
= note: consider constraining the associated type `<A2<T> as Tr>::Ty` to `u8` or calling a method that returns `<A2<T> as Tr>::Ty`
|
||||||
|
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/defaults-specialization.rs:43:29
|
||||||
|
|
|
||||||
|
LL | fn make() -> Self::Ty { true }
|
||||||
|
| -------- ^^^^ expected associated type, found `bool`
|
||||||
|
| |
|
||||||
|
| expected `<B2<T> as Tr>::Ty` because of return type
|
||||||
|
|
|
||||||
|
= note: expected associated type `<B2<T> as Tr>::Ty`
|
||||||
|
found type `bool`
|
||||||
|
= note: consider constraining the associated type `<B2<T> as Tr>::Ty` to `bool` or calling a method that returns `<B2<T> as Tr>::Ty`
|
||||||
|
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/defaults-specialization.rs:86:32
|
||||||
|
|
|
||||||
|
LL | let _: <B<()> as Tr>::Ty = 0u8;
|
||||||
|
| ----------------- ^^^ expected associated type, found `u8`
|
||||||
|
| |
|
||||||
|
| expected due to this
|
||||||
|
|
|
||||||
|
= note: expected associated type `<B<()> as Tr>::Ty`
|
||||||
|
found type `u8`
|
||||||
|
= note: consider constraining the associated type `<B<()> as Tr>::Ty` to `u8` or calling a method that returns `<B<()> as Tr>::Ty`
|
||||||
|
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/defaults-specialization.rs:87:32
|
||||||
|
|
|
||||||
|
LL | let _: <B<()> as Tr>::Ty = true;
|
||||||
|
| ----------------- ^^^^ expected associated type, found `bool`
|
||||||
|
| |
|
||||||
|
| expected due to this
|
||||||
|
|
|
||||||
|
= note: expected associated type `<B<()> as Tr>::Ty`
|
||||||
|
found type `bool`
|
||||||
|
= note: consider constraining the associated type `<B<()> as Tr>::Ty` to `bool` or calling a method that returns `<B<()> as Tr>::Ty`
|
||||||
|
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/defaults-specialization.rs:88:33
|
||||||
|
|
|
||||||
|
LL | let _: <B2<()> as Tr>::Ty = 0u8;
|
||||||
|
| ------------------ ^^^ expected associated type, found `u8`
|
||||||
|
| |
|
||||||
|
| expected due to this
|
||||||
|
|
|
||||||
|
= note: expected associated type `<B2<()> as Tr>::Ty`
|
||||||
|
found type `u8`
|
||||||
|
= note: consider constraining the associated type `<B2<()> as Tr>::Ty` to `u8` or calling a method that returns `<B2<()> as Tr>::Ty`
|
||||||
|
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/defaults-specialization.rs:89:33
|
||||||
|
|
|
||||||
|
LL | let _: <B2<()> as Tr>::Ty = true;
|
||||||
|
| ------------------ ^^^^ expected associated type, found `bool`
|
||||||
|
| |
|
||||||
|
| expected due to this
|
||||||
|
|
|
||||||
|
= note: expected associated type `<B2<()> as Tr>::Ty`
|
||||||
|
found type `bool`
|
||||||
|
= note: consider constraining the associated type `<B2<()> as Tr>::Ty` to `bool` or calling a method that returns `<B2<()> as Tr>::Ty`
|
||||||
|
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
||||||
|
|
||||||
|
error: aborting due to 9 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0053, E0308.
|
||||||
|
For more information about an error, try `rustc --explain E0053`.
|
106
src/test/ui/associated-types/defaults-suitability.rs
Normal file
106
src/test/ui/associated-types/defaults-suitability.rs
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
//! Checks that associated type defaults are properly validated.
|
||||||
|
//!
|
||||||
|
//! This means:
|
||||||
|
//! * Default types are wfchecked
|
||||||
|
//! * Default types are checked against where clauses on the assoc. type
|
||||||
|
//! (eg. `type Assoc: Clone = NotClone`), and also against where clauses on
|
||||||
|
//! the trait itself when possible
|
||||||
|
|
||||||
|
#![feature(associated_type_defaults)]
|
||||||
|
|
||||||
|
struct NotClone;
|
||||||
|
|
||||||
|
// Assoc. type bounds must hold for the default type
|
||||||
|
trait Tr {
|
||||||
|
type Ty: Clone = NotClone;
|
||||||
|
//~^ ERROR the trait bound `NotClone: std::clone::Clone` is not satisfied
|
||||||
|
}
|
||||||
|
|
||||||
|
// Where-clauses defined on the trait must also be considered
|
||||||
|
trait Tr2 where Self::Ty: Clone {
|
||||||
|
//~^ ERROR the trait bound `NotClone: std::clone::Clone` is not satisfied
|
||||||
|
type Ty = NotClone;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Independent of where-clauses (there are none here), default types must always be wf
|
||||||
|
trait Tr3 {
|
||||||
|
type Ty = Vec<[u8]>;
|
||||||
|
//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
|
||||||
|
}
|
||||||
|
|
||||||
|
// Involved type parameters must fulfill all bounds required by defaults that mention them
|
||||||
|
trait Foo<T> {
|
||||||
|
type Bar: Clone = Vec<T>;
|
||||||
|
//~^ ERROR the trait bound `T: std::clone::Clone` is not satisfied
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Bar: Sized {
|
||||||
|
// `(): Foo<Self>` might hold for some possible impls but not all.
|
||||||
|
type Assoc: Foo<Self> = ();
|
||||||
|
//~^ ERROR the trait bound `(): Foo<Self>` is not satisfied
|
||||||
|
}
|
||||||
|
|
||||||
|
trait IsU8<T> {}
|
||||||
|
impl<T> IsU8<u8> for T {}
|
||||||
|
|
||||||
|
// Test that mentioning the assoc. type inside where clauses works
|
||||||
|
trait C where
|
||||||
|
Vec<Self::Assoc>: Clone,
|
||||||
|
Self::Assoc: IsU8<Self::Assoc>,
|
||||||
|
bool: IsU8<Self::Assoc>,
|
||||||
|
{
|
||||||
|
type Assoc = u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that we get all expected errors if that default is unsuitable
|
||||||
|
trait D where
|
||||||
|
Vec<Self::Assoc>: Clone,
|
||||||
|
//~^ ERROR the trait bound `NotClone: std::clone::Clone` is not satisfied
|
||||||
|
Self::Assoc: IsU8<Self::Assoc>,
|
||||||
|
//~^ ERROR the trait bound `NotClone: IsU8<NotClone>` is not satisfied
|
||||||
|
bool: IsU8<Self::Assoc>,
|
||||||
|
//~^ ERROR the trait bound `bool: IsU8<NotClone>` is not satisfied
|
||||||
|
{
|
||||||
|
type Assoc = NotClone;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test behavior of the check when defaults refer to other defaults:
|
||||||
|
|
||||||
|
// Shallow substitution rejects this trait since `Baz` isn't guaranteed to be
|
||||||
|
// `Clone`.
|
||||||
|
trait Foo2<T> {
|
||||||
|
type Bar: Clone = Vec<Self::Baz>;
|
||||||
|
//~^ ERROR the trait bound `<Self as Foo2<T>>::Baz: std::clone::Clone` is not satisfied
|
||||||
|
type Baz = T;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adding a `T: Clone` bound doesn't help since the requirement doesn't see `T`
|
||||||
|
// because of the shallow substitution. If we did a deep substitution instead,
|
||||||
|
// this would be accepted.
|
||||||
|
trait Foo25<T: Clone> {
|
||||||
|
type Bar: Clone = Vec<Self::Baz>;
|
||||||
|
//~^ ERROR the trait bound `<Self as Foo25<T>>::Baz: std::clone::Clone` is not satisfied
|
||||||
|
type Baz = T;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adding the `Baz: Clone` bound isn't enough since the default is type
|
||||||
|
// parameter `T`, which also might not be `Clone`.
|
||||||
|
trait Foo3<T> where
|
||||||
|
Self::Bar: Clone,
|
||||||
|
Self::Baz: Clone,
|
||||||
|
//~^ ERROR the trait bound `T: std::clone::Clone` is not satisfied
|
||||||
|
{
|
||||||
|
type Bar = Vec<Self::Baz>;
|
||||||
|
type Baz = T;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This one finally works, with `Clone` bounds on all assoc. types and the type
|
||||||
|
// parameter.
|
||||||
|
trait Foo4<T> where
|
||||||
|
T: Clone,
|
||||||
|
{
|
||||||
|
type Bar: Clone = Vec<Self::Baz>;
|
||||||
|
type Baz: Clone = T;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
140
src/test/ui/associated-types/defaults-suitability.stderr
Normal file
140
src/test/ui/associated-types/defaults-suitability.stderr
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
error[E0277]: the trait bound `NotClone: std::clone::Clone` is not satisfied
|
||||||
|
--> $DIR/defaults-suitability.rs:15:14
|
||||||
|
|
|
||||||
|
LL | trait Tr {
|
||||||
|
| -------- required by `Tr`
|
||||||
|
LL | type Ty: Clone = NotClone;
|
||||||
|
| ^^^^^ the trait `std::clone::Clone` is not implemented for `NotClone`
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `NotClone: std::clone::Clone` is not satisfied
|
||||||
|
--> $DIR/defaults-suitability.rs:20:27
|
||||||
|
|
|
||||||
|
LL | trait Tr2 where Self::Ty: Clone {
|
||||||
|
| --------------------------^^^^^
|
||||||
|
| | |
|
||||||
|
| | the trait `std::clone::Clone` is not implemented for `NotClone`
|
||||||
|
| required by `Tr2`
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `T: std::clone::Clone` is not satisfied
|
||||||
|
--> $DIR/defaults-suitability.rs:33:15
|
||||||
|
|
|
||||||
|
LL | trait Foo<T> {
|
||||||
|
| ------------ required by `Foo`
|
||||||
|
LL | type Bar: Clone = Vec<T>;
|
||||||
|
| ^^^^^ the trait `std::clone::Clone` is not implemented for `T`
|
||||||
|
|
|
||||||
|
help: consider restricting this type parameter with `T: std::clone::Clone`
|
||||||
|
--> $DIR/defaults-suitability.rs:32:11
|
||||||
|
|
|
||||||
|
LL | trait Foo<T> {
|
||||||
|
| ^
|
||||||
|
= note: required because of the requirements on the impl of `std::clone::Clone` for `std::vec::Vec<T>`
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `(): Foo<Self>` is not satisfied
|
||||||
|
--> $DIR/defaults-suitability.rs:39:17
|
||||||
|
|
|
||||||
|
LL | trait Bar: Sized {
|
||||||
|
| ---------------- required by `Bar`
|
||||||
|
LL | // `(): Foo<Self>` might hold for some possible impls but not all.
|
||||||
|
LL | type Assoc: Foo<Self> = ();
|
||||||
|
| ^^^^^^^^^ the trait `Foo<Self>` is not implemented for `()`
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `NotClone: IsU8<NotClone>` is not satisfied
|
||||||
|
--> $DIR/defaults-suitability.rs:59:18
|
||||||
|
|
|
||||||
|
LL | / trait D where
|
||||||
|
LL | | Vec<Self::Assoc>: Clone,
|
||||||
|
LL | |
|
||||||
|
LL | | Self::Assoc: IsU8<Self::Assoc>,
|
||||||
|
| | ^^^^^^^^^^^^^^^^^ the trait `IsU8<NotClone>` is not implemented for `NotClone`
|
||||||
|
... |
|
||||||
|
LL | | type Assoc = NotClone;
|
||||||
|
LL | | }
|
||||||
|
| |_- required by `D`
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `bool: IsU8<NotClone>` is not satisfied
|
||||||
|
--> $DIR/defaults-suitability.rs:61:11
|
||||||
|
|
|
||||||
|
LL | / trait D where
|
||||||
|
LL | | Vec<Self::Assoc>: Clone,
|
||||||
|
LL | |
|
||||||
|
LL | | Self::Assoc: IsU8<Self::Assoc>,
|
||||||
|
LL | |
|
||||||
|
LL | | bool: IsU8<Self::Assoc>,
|
||||||
|
| | ^^^^^^^^^^^^^^^^^ the trait `IsU8<NotClone>` is not implemented for `bool`
|
||||||
|
... |
|
||||||
|
LL | | type Assoc = NotClone;
|
||||||
|
LL | | }
|
||||||
|
| |_- required by `D`
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `NotClone: std::clone::Clone` is not satisfied
|
||||||
|
--> $DIR/defaults-suitability.rs:57:23
|
||||||
|
|
|
||||||
|
LL | / trait D where
|
||||||
|
LL | | Vec<Self::Assoc>: Clone,
|
||||||
|
| | ^^^^^ the trait `std::clone::Clone` is not implemented for `NotClone`
|
||||||
|
LL | |
|
||||||
|
LL | | Self::Assoc: IsU8<Self::Assoc>,
|
||||||
|
... |
|
||||||
|
LL | | type Assoc = NotClone;
|
||||||
|
LL | | }
|
||||||
|
| |_- required by `D`
|
||||||
|
|
|
||||||
|
= note: required because of the requirements on the impl of `std::clone::Clone` for `std::vec::Vec<NotClone>`
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `<Self as Foo2<T>>::Baz: std::clone::Clone` is not satisfied
|
||||||
|
--> $DIR/defaults-suitability.rs:72:15
|
||||||
|
|
|
||||||
|
LL | trait Foo2<T> {
|
||||||
|
| -------------- help: consider further restricting the associated type: `where <Self as Foo2<T>>::Baz: std::clone::Clone`
|
||||||
|
| |
|
||||||
|
| required by `Foo2`
|
||||||
|
LL | type Bar: Clone = Vec<Self::Baz>;
|
||||||
|
| ^^^^^ the trait `std::clone::Clone` is not implemented for `<Self as Foo2<T>>::Baz`
|
||||||
|
|
|
||||||
|
= note: required because of the requirements on the impl of `std::clone::Clone` for `std::vec::Vec<<Self as Foo2<T>>::Baz>`
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `<Self as Foo25<T>>::Baz: std::clone::Clone` is not satisfied
|
||||||
|
--> $DIR/defaults-suitability.rs:81:15
|
||||||
|
|
|
||||||
|
LL | trait Foo25<T: Clone> {
|
||||||
|
| ---------------------- help: consider further restricting the associated type: `where <Self as Foo25<T>>::Baz: std::clone::Clone`
|
||||||
|
| |
|
||||||
|
| required by `Foo25`
|
||||||
|
LL | type Bar: Clone = Vec<Self::Baz>;
|
||||||
|
| ^^^^^ the trait `std::clone::Clone` is not implemented for `<Self as Foo25<T>>::Baz`
|
||||||
|
|
|
||||||
|
= note: required because of the requirements on the impl of `std::clone::Clone` for `std::vec::Vec<<Self as Foo25<T>>::Baz>`
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `T: std::clone::Clone` is not satisfied
|
||||||
|
--> $DIR/defaults-suitability.rs:90:16
|
||||||
|
|
|
||||||
|
LL | / trait Foo3<T> where
|
||||||
|
LL | | Self::Bar: Clone,
|
||||||
|
LL | | Self::Baz: Clone,
|
||||||
|
| | ^^^^^ the trait `std::clone::Clone` is not implemented for `T`
|
||||||
|
LL | |
|
||||||
|
... |
|
||||||
|
LL | | type Baz = T;
|
||||||
|
LL | | }
|
||||||
|
| |_- required by `Foo3`
|
||||||
|
|
|
||||||
|
help: consider restricting this type parameter with `where T: std::clone::Clone`
|
||||||
|
--> $DIR/defaults-suitability.rs:88:12
|
||||||
|
|
|
||||||
|
LL | trait Foo3<T> where
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||||
|
--> $DIR/defaults-suitability.rs:27:5
|
||||||
|
|
|
||||||
|
LL | type Ty = Vec<[u8]>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: the trait `std::marker::Sized` is not implemented for `[u8]`
|
||||||
|
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
|
||||||
|
= note: required by `std::vec::Vec`
|
||||||
|
|
||||||
|
error: aborting due to 11 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
63
src/test/ui/associated-types/defaults-unsound-62211-1.rs
Normal file
63
src/test/ui/associated-types/defaults-unsound-62211-1.rs
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
//! Regression test for https://github.com/rust-lang/rust/issues/62211
|
||||||
|
//!
|
||||||
|
//! The old implementation of defaults did not check whether the provided
|
||||||
|
//! default actually fulfills all bounds on the assoc. type, leading to
|
||||||
|
//! unsoundness, demonstrated here as a use-after-free.
|
||||||
|
//!
|
||||||
|
//! Note that the underlying cause of this is still not yet fixed.
|
||||||
|
//! See: https://github.com/rust-lang/rust/issues/33017
|
||||||
|
|
||||||
|
#![feature(associated_type_defaults)]
|
||||||
|
|
||||||
|
use std::{
|
||||||
|
fmt::Display,
|
||||||
|
ops::{AddAssign, Deref}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
trait UncheckedCopy: Sized {
|
||||||
|
// This Output is said to be Copy. Yet we default to Self
|
||||||
|
// and it's accepted, not knowing if Self ineed is Copy
|
||||||
|
type Output: Copy
|
||||||
|
//~^ ERROR the trait bound `Self: std::marker::Copy` is not satisfied
|
||||||
|
+ Deref<Target = str>
|
||||||
|
//~^ ERROR the trait bound `Self: std::ops::Deref` is not satisfied
|
||||||
|
+ AddAssign<&'static str>
|
||||||
|
//~^ ERROR cannot add-assign `&'static str` to `Self`
|
||||||
|
+ From<Self>
|
||||||
|
+ Display = Self;
|
||||||
|
//~^ ERROR `Self` doesn't implement `std::fmt::Display`
|
||||||
|
|
||||||
|
// We said the Output type was Copy, so we can Copy it freely!
|
||||||
|
fn unchecked_copy(other: &Self::Output) -> Self::Output {
|
||||||
|
(*other)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_origin(s: Self) -> Self::Output {
|
||||||
|
s.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> UncheckedCopy for T {}
|
||||||
|
//~^ ERROR `T` doesn't implement `std::fmt::Display`
|
||||||
|
//~| ERROR the trait bound `T: std::ops::Deref` is not satisfied
|
||||||
|
//~| ERROR cannot add-assign `&'static str` to `T`
|
||||||
|
//~| ERROR the trait bound `T: std::marker::Copy` is not satisfied
|
||||||
|
|
||||||
|
fn bug<T: UncheckedCopy>(origin: T) {
|
||||||
|
let origin = T::make_origin(origin);
|
||||||
|
let mut copy = T::unchecked_copy(&origin);
|
||||||
|
|
||||||
|
// assert we indeed have 2 strings pointing to the same buffer.
|
||||||
|
assert_eq!(origin.as_ptr(), copy.as_ptr());
|
||||||
|
|
||||||
|
// Drop the origin. Any use of `copy` is UB.
|
||||||
|
drop(origin);
|
||||||
|
|
||||||
|
copy += "This is invalid!";
|
||||||
|
println!("{}", copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
bug(String::from("hello!"));
|
||||||
|
}
|
95
src/test/ui/associated-types/defaults-unsound-62211-1.stderr
Normal file
95
src/test/ui/associated-types/defaults-unsound-62211-1.stderr
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
error[E0277]: the trait bound `Self: std::marker::Copy` is not satisfied
|
||||||
|
--> $DIR/defaults-unsound-62211-1.rs:21:18
|
||||||
|
|
|
||||||
|
LL | trait UncheckedCopy: Sized {
|
||||||
|
| -------------------------- required by `UncheckedCopy`
|
||||||
|
...
|
||||||
|
LL | type Output: Copy
|
||||||
|
| ^^^^ the trait `std::marker::Copy` is not implemented for `Self`
|
||||||
|
|
||||||
|
error[E0277]: cannot add-assign `&'static str` to `Self`
|
||||||
|
--> $DIR/defaults-unsound-62211-1.rs:25:7
|
||||||
|
|
|
||||||
|
LL | trait UncheckedCopy: Sized {
|
||||||
|
| -------------------------- required by `UncheckedCopy`
|
||||||
|
...
|
||||||
|
LL | + AddAssign<&'static str>
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `Self += &'static str`
|
||||||
|
|
|
||||||
|
= help: the trait `std::ops::AddAssign<&'static str>` is not implemented for `Self`
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `Self: std::ops::Deref` is not satisfied
|
||||||
|
--> $DIR/defaults-unsound-62211-1.rs:23:7
|
||||||
|
|
|
||||||
|
LL | trait UncheckedCopy: Sized {
|
||||||
|
| -------------------------- required by `UncheckedCopy`
|
||||||
|
...
|
||||||
|
LL | + Deref<Target = str>
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Deref` is not implemented for `Self`
|
||||||
|
|
||||||
|
error[E0277]: `Self` doesn't implement `std::fmt::Display`
|
||||||
|
--> $DIR/defaults-unsound-62211-1.rs:28:7
|
||||||
|
|
|
||||||
|
LL | trait UncheckedCopy: Sized {
|
||||||
|
| -------------------------- required by `UncheckedCopy`
|
||||||
|
...
|
||||||
|
LL | + Display = Self;
|
||||||
|
| ^^^^^^^ `Self` cannot be formatted with the default formatter
|
||||||
|
|
|
||||||
|
= help: the trait `std::fmt::Display` is not implemented for `Self`
|
||||||
|
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
|
||||||
|
|
||||||
|
error[E0277]: `T` doesn't implement `std::fmt::Display`
|
||||||
|
--> $DIR/defaults-unsound-62211-1.rs:41:9
|
||||||
|
|
|
||||||
|
LL | impl<T> UncheckedCopy for T {}
|
||||||
|
| ^^^^^^^^^^^^^ `T` cannot be formatted with the default formatter
|
||||||
|
|
|
||||||
|
= help: the trait `std::fmt::Display` is not implemented for `T`
|
||||||
|
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
|
||||||
|
help: consider restricting this type parameter with `T: std::fmt::Display`
|
||||||
|
--> $DIR/defaults-unsound-62211-1.rs:41:6
|
||||||
|
|
|
||||||
|
LL | impl<T> UncheckedCopy for T {}
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `T: std::ops::Deref` is not satisfied
|
||||||
|
--> $DIR/defaults-unsound-62211-1.rs:41:9
|
||||||
|
|
|
||||||
|
LL | impl<T> UncheckedCopy for T {}
|
||||||
|
| ^^^^^^^^^^^^^ the trait `std::ops::Deref` is not implemented for `T`
|
||||||
|
|
|
||||||
|
help: consider restricting this type parameter with `T: std::ops::Deref`
|
||||||
|
--> $DIR/defaults-unsound-62211-1.rs:41:6
|
||||||
|
|
|
||||||
|
LL | impl<T> UncheckedCopy for T {}
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error[E0277]: cannot add-assign `&'static str` to `T`
|
||||||
|
--> $DIR/defaults-unsound-62211-1.rs:41:9
|
||||||
|
|
|
||||||
|
LL | impl<T> UncheckedCopy for T {}
|
||||||
|
| ^^^^^^^^^^^^^ no implementation for `T += &'static str`
|
||||||
|
|
|
||||||
|
= help: the trait `std::ops::AddAssign<&'static str>` is not implemented for `T`
|
||||||
|
help: consider restricting this type parameter with `T: std::ops::AddAssign<&'static str>`
|
||||||
|
--> $DIR/defaults-unsound-62211-1.rs:41:6
|
||||||
|
|
|
||||||
|
LL | impl<T> UncheckedCopy for T {}
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
|
||||||
|
--> $DIR/defaults-unsound-62211-1.rs:41:9
|
||||||
|
|
|
||||||
|
LL | impl<T> UncheckedCopy for T {}
|
||||||
|
| ^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
|
||||||
|
|
|
||||||
|
help: consider restricting this type parameter with `T: std::marker::Copy`
|
||||||
|
--> $DIR/defaults-unsound-62211-1.rs:41:6
|
||||||
|
|
|
||||||
|
LL | impl<T> UncheckedCopy for T {}
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
63
src/test/ui/associated-types/defaults-unsound-62211-2.rs
Normal file
63
src/test/ui/associated-types/defaults-unsound-62211-2.rs
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
//! Regression test for https://github.com/rust-lang/rust/issues/62211
|
||||||
|
//!
|
||||||
|
//! The old implementation of defaults did not check whether the provided
|
||||||
|
//! default actually fulfills all bounds on the assoc. type, leading to
|
||||||
|
//! unsoundness and ICEs, the latter being demonstrated here.
|
||||||
|
//!
|
||||||
|
//! Note that the underlying cause of this is still not yet fixed.
|
||||||
|
//! See: https://github.com/rust-lang/rust/issues/33017
|
||||||
|
|
||||||
|
#![feature(associated_type_defaults)]
|
||||||
|
|
||||||
|
use std::{
|
||||||
|
fmt::Display,
|
||||||
|
ops::{AddAssign, Deref}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
trait UncheckedCopy: Sized {
|
||||||
|
// This Output is said to be Copy. Yet we default to Self
|
||||||
|
// and it's accepted, not knowing if Self ineed is Copy
|
||||||
|
type Output: Copy
|
||||||
|
//~^ ERROR the trait bound `Self: std::marker::Copy` is not satisfied
|
||||||
|
+ Deref<Target = str>
|
||||||
|
//~^ ERROR the trait bound `Self: std::ops::Deref` is not satisfied
|
||||||
|
+ AddAssign<&'static str>
|
||||||
|
//~^ ERROR cannot add-assign `&'static str` to `Self`
|
||||||
|
+ From<Self>
|
||||||
|
+ Display = Self;
|
||||||
|
//~^ ERROR `Self` doesn't implement `std::fmt::Display`
|
||||||
|
|
||||||
|
// We said the Output type was Copy, so we can Copy it freely!
|
||||||
|
fn unchecked_copy(other: &Self::Output) -> Self::Output {
|
||||||
|
(*other)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_origin(s: Self) -> Self::Output {
|
||||||
|
s.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> UncheckedCopy for T {}
|
||||||
|
//~^ ERROR `T` doesn't implement `std::fmt::Display`
|
||||||
|
//~| ERROR the trait bound `T: std::ops::Deref` is not satisfied
|
||||||
|
//~| ERROR cannot add-assign `&'static str` to `T`
|
||||||
|
//~| ERROR the trait bound `T: std::marker::Copy` is not satisfied
|
||||||
|
|
||||||
|
fn bug<T: UncheckedCopy>(origin: T) {
|
||||||
|
let origin = T::make_origin(origin);
|
||||||
|
let mut copy = T::unchecked_copy(&origin);
|
||||||
|
|
||||||
|
// assert we indeed have 2 strings pointing to the same buffer.
|
||||||
|
assert_eq!(origin.as_ptr(), copy.as_ptr());
|
||||||
|
|
||||||
|
// Drop the origin. Any use of `copy` is UB.
|
||||||
|
drop(origin);
|
||||||
|
|
||||||
|
copy += "This is invalid!";
|
||||||
|
println!("{}", copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
bug(());
|
||||||
|
}
|
95
src/test/ui/associated-types/defaults-unsound-62211-2.stderr
Normal file
95
src/test/ui/associated-types/defaults-unsound-62211-2.stderr
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
error[E0277]: the trait bound `Self: std::marker::Copy` is not satisfied
|
||||||
|
--> $DIR/defaults-unsound-62211-2.rs:21:18
|
||||||
|
|
|
||||||
|
LL | trait UncheckedCopy: Sized {
|
||||||
|
| -------------------------- required by `UncheckedCopy`
|
||||||
|
...
|
||||||
|
LL | type Output: Copy
|
||||||
|
| ^^^^ the trait `std::marker::Copy` is not implemented for `Self`
|
||||||
|
|
||||||
|
error[E0277]: cannot add-assign `&'static str` to `Self`
|
||||||
|
--> $DIR/defaults-unsound-62211-2.rs:25:7
|
||||||
|
|
|
||||||
|
LL | trait UncheckedCopy: Sized {
|
||||||
|
| -------------------------- required by `UncheckedCopy`
|
||||||
|
...
|
||||||
|
LL | + AddAssign<&'static str>
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `Self += &'static str`
|
||||||
|
|
|
||||||
|
= help: the trait `std::ops::AddAssign<&'static str>` is not implemented for `Self`
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `Self: std::ops::Deref` is not satisfied
|
||||||
|
--> $DIR/defaults-unsound-62211-2.rs:23:7
|
||||||
|
|
|
||||||
|
LL | trait UncheckedCopy: Sized {
|
||||||
|
| -------------------------- required by `UncheckedCopy`
|
||||||
|
...
|
||||||
|
LL | + Deref<Target = str>
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Deref` is not implemented for `Self`
|
||||||
|
|
||||||
|
error[E0277]: `Self` doesn't implement `std::fmt::Display`
|
||||||
|
--> $DIR/defaults-unsound-62211-2.rs:28:7
|
||||||
|
|
|
||||||
|
LL | trait UncheckedCopy: Sized {
|
||||||
|
| -------------------------- required by `UncheckedCopy`
|
||||||
|
...
|
||||||
|
LL | + Display = Self;
|
||||||
|
| ^^^^^^^ `Self` cannot be formatted with the default formatter
|
||||||
|
|
|
||||||
|
= help: the trait `std::fmt::Display` is not implemented for `Self`
|
||||||
|
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
|
||||||
|
|
||||||
|
error[E0277]: `T` doesn't implement `std::fmt::Display`
|
||||||
|
--> $DIR/defaults-unsound-62211-2.rs:41:9
|
||||||
|
|
|
||||||
|
LL | impl<T> UncheckedCopy for T {}
|
||||||
|
| ^^^^^^^^^^^^^ `T` cannot be formatted with the default formatter
|
||||||
|
|
|
||||||
|
= help: the trait `std::fmt::Display` is not implemented for `T`
|
||||||
|
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
|
||||||
|
help: consider restricting this type parameter with `T: std::fmt::Display`
|
||||||
|
--> $DIR/defaults-unsound-62211-2.rs:41:6
|
||||||
|
|
|
||||||
|
LL | impl<T> UncheckedCopy for T {}
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `T: std::ops::Deref` is not satisfied
|
||||||
|
--> $DIR/defaults-unsound-62211-2.rs:41:9
|
||||||
|
|
|
||||||
|
LL | impl<T> UncheckedCopy for T {}
|
||||||
|
| ^^^^^^^^^^^^^ the trait `std::ops::Deref` is not implemented for `T`
|
||||||
|
|
|
||||||
|
help: consider restricting this type parameter with `T: std::ops::Deref`
|
||||||
|
--> $DIR/defaults-unsound-62211-2.rs:41:6
|
||||||
|
|
|
||||||
|
LL | impl<T> UncheckedCopy for T {}
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error[E0277]: cannot add-assign `&'static str` to `T`
|
||||||
|
--> $DIR/defaults-unsound-62211-2.rs:41:9
|
||||||
|
|
|
||||||
|
LL | impl<T> UncheckedCopy for T {}
|
||||||
|
| ^^^^^^^^^^^^^ no implementation for `T += &'static str`
|
||||||
|
|
|
||||||
|
= help: the trait `std::ops::AddAssign<&'static str>` is not implemented for `T`
|
||||||
|
help: consider restricting this type parameter with `T: std::ops::AddAssign<&'static str>`
|
||||||
|
--> $DIR/defaults-unsound-62211-2.rs:41:6
|
||||||
|
|
|
||||||
|
LL | impl<T> UncheckedCopy for T {}
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
|
||||||
|
--> $DIR/defaults-unsound-62211-2.rs:41:9
|
||||||
|
|
|
||||||
|
LL | impl<T> UncheckedCopy for T {}
|
||||||
|
| ^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
|
||||||
|
|
|
||||||
|
help: consider restricting this type parameter with `T: std::marker::Copy`
|
||||||
|
--> $DIR/defaults-unsound-62211-2.rs:41:6
|
||||||
|
|
|
||||||
|
LL | impl<T> UncheckedCopy for T {}
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
20
src/test/ui/associated-types/issue-26681.rs
Normal file
20
src/test/ui/associated-types/issue-26681.rs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#![feature(associated_type_defaults)]
|
||||||
|
|
||||||
|
// This is a partial regression test for #26681, which used to fail to resolve
|
||||||
|
// `Self` in the assoc. constant, and now fails with a type mismatch because
|
||||||
|
// `Self::Fv` cannot be assumed to equal `u8` inside the trait.
|
||||||
|
|
||||||
|
trait Foo {
|
||||||
|
type Bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Foo for u8 {
|
||||||
|
type Bar = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Baz {
|
||||||
|
type Fv: Foo = u8;
|
||||||
|
const C: <Self::Fv as Foo>::Bar = 6665; //~ error: mismatched types
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
14
src/test/ui/associated-types/issue-26681.stderr
Normal file
14
src/test/ui/associated-types/issue-26681.stderr
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/issue-26681.rs:17:39
|
||||||
|
|
|
||||||
|
LL | const C: <Self::Fv as Foo>::Bar = 6665;
|
||||||
|
| ^^^^ expected associated type, found integer
|
||||||
|
|
|
||||||
|
= note: expected associated type `<<Self as Baz>::Fv as Foo>::Bar`
|
||||||
|
found type `{integer}`
|
||||||
|
= note: consider constraining the associated type `<<Self as Baz>::Fv as Foo>::Bar` to `{integer}` or calling a method that returns `<<Self as Baz>::Fv as Foo>::Bar`
|
||||||
|
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
29
src/test/ui/associated-types/issue-32350.rs
Normal file
29
src/test/ui/associated-types/issue-32350.rs
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
// This is another instance of the "normalizations don't work" issue with
|
||||||
|
// defaulted associated types.
|
||||||
|
|
||||||
|
#![feature(associated_type_defaults)]
|
||||||
|
|
||||||
|
pub trait Emitter<'a> {
|
||||||
|
type Ctxt: 'a;
|
||||||
|
type CtxtBrw: 'a = &'a Self::Ctxt;
|
||||||
|
|
||||||
|
fn get_cx(&'a self) -> Self::CtxtBrw;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MyCtxt;
|
||||||
|
|
||||||
|
struct MyEmitter {
|
||||||
|
ctxt: MyCtxt
|
||||||
|
}
|
||||||
|
|
||||||
|
impl <'a> Emitter<'a> for MyEmitter {
|
||||||
|
type Ctxt = MyCtxt;
|
||||||
|
|
||||||
|
fn get_cx(&'a self) -> &'a MyCtxt {
|
||||||
|
&self.ctxt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
23
src/test/ui/associated-types/issue-41868.rs
Normal file
23
src/test/ui/associated-types/issue-41868.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
// Defaulted assoc. types should normalize properly in impls that don't
|
||||||
|
// override them.
|
||||||
|
|
||||||
|
#![feature(associated_type_defaults)]
|
||||||
|
|
||||||
|
pub struct Foo;
|
||||||
|
|
||||||
|
pub trait CanDecode: Sized {
|
||||||
|
type Output = Self;
|
||||||
|
fn read(rdr: &mut Foo) -> Option<Self::Output>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CanDecode for u8 {
|
||||||
|
fn read(rdr: &mut Foo) -> Option<Self::Output> { Some(42) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CanDecode for u16 {
|
||||||
|
fn read(rdr: &mut Foo) -> Option<u16> { Some(17) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
15
src/test/ui/associated-types/issue-43924.rs
Normal file
15
src/test/ui/associated-types/issue-43924.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#![feature(associated_type_defaults)]
|
||||||
|
|
||||||
|
// This used to cause an ICE because assoc. type defaults weren't properly
|
||||||
|
// type-checked.
|
||||||
|
|
||||||
|
trait Foo<T: Default + ToString> {
|
||||||
|
type Out: Default + ToString + ?Sized = dyn ToString; //~ error: not satisfied
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Foo<u32> for () {} //~ error: not satisfied
|
||||||
|
impl Foo<u64> for () {} //~ error: not satisfied
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert_eq!(<() as Foo<u32>>::Out::default().to_string(), "false");
|
||||||
|
}
|
23
src/test/ui/associated-types/issue-43924.stderr
Normal file
23
src/test/ui/associated-types/issue-43924.stderr
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
error[E0277]: the trait bound `(dyn std::string::ToString + 'static): std::default::Default` is not satisfied
|
||||||
|
--> $DIR/issue-43924.rs:7:15
|
||||||
|
|
|
||||||
|
LL | trait Foo<T: Default + ToString> {
|
||||||
|
| -------------------------------- required by `Foo`
|
||||||
|
LL | type Out: Default + ToString + ?Sized = dyn ToString;
|
||||||
|
| ^^^^^^^ the trait `std::default::Default` is not implemented for `(dyn std::string::ToString + 'static)`
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `(dyn std::string::ToString + 'static): std::default::Default` is not satisfied
|
||||||
|
--> $DIR/issue-43924.rs:10:6
|
||||||
|
|
|
||||||
|
LL | impl Foo<u32> for () {}
|
||||||
|
| ^^^^^^^^ the trait `std::default::Default` is not implemented for `(dyn std::string::ToString + 'static)`
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `(dyn std::string::ToString + 'static): std::default::Default` is not satisfied
|
||||||
|
--> $DIR/issue-43924.rs:11:6
|
||||||
|
|
|
||||||
|
LL | impl Foo<u64> for () {}
|
||||||
|
| ^^^^^^^^ the trait `std::default::Default` is not implemented for `(dyn std::string::ToString + 'static)`
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
16
src/test/ui/associated-types/issue-47385.rs
Normal file
16
src/test/ui/associated-types/issue-47385.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(associated_type_defaults)]
|
||||||
|
|
||||||
|
pub struct Foo;
|
||||||
|
|
||||||
|
pub trait Bar: From<<Self as Bar>::Input> {
|
||||||
|
type Input = Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Bar for Foo {
|
||||||
|
// Will compile with explicit type:
|
||||||
|
// type Input = Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
92
src/test/ui/associated-types/issue-54182-1.rs
Normal file
92
src/test/ui/associated-types/issue-54182-1.rs
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
// run-pass
|
||||||
|
|
||||||
|
// Tests that the return type of trait methods is correctly normalized when
|
||||||
|
// checking that a method in an impl matches the trait definition when the
|
||||||
|
// return type involves a defaulted associated type.
|
||||||
|
// ie. the trait has a method with return type `-> Self::R`, and `type R = ()`,
|
||||||
|
// but the impl leaves out the return type (resulting in `()`).
|
||||||
|
// Note that specialization is not involved in this test; no items in
|
||||||
|
// implementations may be overridden. If they were, the normalization wouldn't
|
||||||
|
// happen.
|
||||||
|
|
||||||
|
#![feature(associated_type_defaults)]
|
||||||
|
|
||||||
|
macro_rules! overload {
|
||||||
|
($a:expr, $b:expr) => {
|
||||||
|
overload::overload2($a, $b)
|
||||||
|
};
|
||||||
|
($a:expr, $b:expr, $c:expr) => {
|
||||||
|
overload::overload3($a, $b, $c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let () = overload!(42, true);
|
||||||
|
|
||||||
|
let r: f32 = overload!("Hello world", 13.0);
|
||||||
|
assert_eq!(r, 13.0);
|
||||||
|
|
||||||
|
let () = overload!(42, true, 42.5);
|
||||||
|
|
||||||
|
let r: i32 = overload!("Hello world", 13.0, 42);
|
||||||
|
assert_eq!(r, 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
mod overload {
|
||||||
|
/// This trait has an assoc. type defaulting to `()`, and a required method returning a value
|
||||||
|
/// of that assoc. type.
|
||||||
|
pub trait Overload {
|
||||||
|
// type R;
|
||||||
|
type R = ();
|
||||||
|
fn overload(self) -> Self::R;
|
||||||
|
}
|
||||||
|
|
||||||
|
// overloads for 2 args
|
||||||
|
impl Overload for (i32, bool) {
|
||||||
|
// type R = ();
|
||||||
|
|
||||||
|
/// This function has no return type specified, and so defaults to `()`.
|
||||||
|
///
|
||||||
|
/// This should work, but didn't, until RFC 2532 was implemented.
|
||||||
|
fn overload(self) /*-> Self::R*/ {
|
||||||
|
let (a, b) = self; // destructure args
|
||||||
|
println!("i32 and bool {:?}", (a, b));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'a> Overload for (&'a str, f32) {
|
||||||
|
type R = f32;
|
||||||
|
fn overload(self) -> Self::R {
|
||||||
|
let (a, b) = self; // destructure args
|
||||||
|
println!("&str and f32 {:?}", (a, b));
|
||||||
|
b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// overloads for 3 args
|
||||||
|
impl Overload for (i32, bool, f32) {
|
||||||
|
// type R = ();
|
||||||
|
fn overload(self) /*-> Self::R*/ {
|
||||||
|
let (a, b, c) = self; // destructure args
|
||||||
|
println!("i32 and bool and f32 {:?}", (a, b, c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'a> Overload for (&'a str, f32, i32) {
|
||||||
|
type R = i32;
|
||||||
|
fn overload(self) -> Self::R {
|
||||||
|
let (a, b, c) = self; // destructure args
|
||||||
|
println!("&str and f32 and i32: {:?}", (a, b, c));
|
||||||
|
c
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// overloads for more args
|
||||||
|
// ...
|
||||||
|
|
||||||
|
pub fn overload2<R, A, B>(a: A, b: B) -> R where (A, B): Overload<R = R> {
|
||||||
|
(a, b).overload()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn overload3<R, A, B, C>(a: A, b: B, c: C) -> R where (A, B, C): Overload<R = R> {
|
||||||
|
(a, b, c).overload()
|
||||||
|
}
|
||||||
|
}
|
19
src/test/ui/associated-types/issue-54182-2.rs
Normal file
19
src/test/ui/associated-types/issue-54182-2.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
// Before RFC 2532, normalizing a defaulted assoc. type didn't work at all,
|
||||||
|
// unless the impl in question overrides that type, which makes the default
|
||||||
|
// pointless.
|
||||||
|
|
||||||
|
#![feature(associated_type_defaults)]
|
||||||
|
|
||||||
|
trait Tr {
|
||||||
|
type Assoc = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tr for () {}
|
||||||
|
|
||||||
|
fn f(thing: <() as Tr>::Assoc) {
|
||||||
|
let c: () = thing;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
13
src/test/ui/associated-types/issue-63593.rs
Normal file
13
src/test/ui/associated-types/issue-63593.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#![feature(associated_type_defaults)]
|
||||||
|
|
||||||
|
// Tests that `Self` is not assumed to implement `Sized` when used as an
|
||||||
|
// associated type default.
|
||||||
|
|
||||||
|
trait Inner<S> {}
|
||||||
|
|
||||||
|
trait MyTrait {
|
||||||
|
type This = Self; //~ error: size for values of type `Self` cannot be known
|
||||||
|
fn something<I: Inner<Self::This>>(i: I);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
14
src/test/ui/associated-types/issue-63593.stderr
Normal file
14
src/test/ui/associated-types/issue-63593.stderr
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
error[E0277]: the size for values of type `Self` cannot be known at compilation time
|
||||||
|
--> $DIR/issue-63593.rs:9:5
|
||||||
|
|
|
||||||
|
LL | trait MyTrait {
|
||||||
|
| ------------- required by `MyTrait`
|
||||||
|
LL | type This = Self;
|
||||||
|
| ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: the trait `std::marker::Sized` is not implemented for `Self`
|
||||||
|
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
58
src/test/ui/associated-types/issue-65774-1.rs
Normal file
58
src/test/ui/associated-types/issue-65774-1.rs
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
#![feature(associated_type_defaults)]
|
||||||
|
|
||||||
|
trait MyDisplay { fn method(&self) { } }
|
||||||
|
|
||||||
|
impl<'a, T: MyDisplay> MyDisplay for &'a mut T { }
|
||||||
|
|
||||||
|
struct T;
|
||||||
|
|
||||||
|
trait MPU {
|
||||||
|
type MpuConfig: MyDisplay = T;
|
||||||
|
//~^ ERROR the trait bound `T: MyDisplay` is not satisfied
|
||||||
|
}
|
||||||
|
|
||||||
|
struct S;
|
||||||
|
|
||||||
|
impl MPU for S { }
|
||||||
|
//~^ ERROR the trait bound `T: MyDisplay` is not satisfied
|
||||||
|
|
||||||
|
trait MyWrite {
|
||||||
|
fn my_write(&self, _: &dyn MyDisplay) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
trait ProcessType {
|
||||||
|
fn process_detail_fmt(&self, _: &mut dyn MyWrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Process;
|
||||||
|
|
||||||
|
impl ProcessType for Process {
|
||||||
|
fn process_detail_fmt(&self, writer: &mut dyn MyWrite)
|
||||||
|
{
|
||||||
|
|
||||||
|
let mut val: Option<<S as MPU>::MpuConfig> = None;
|
||||||
|
let valref: &mut <S as MPU>::MpuConfig = val.as_mut().unwrap();
|
||||||
|
|
||||||
|
// // This causes a different ICE (but its similar if you squint right):
|
||||||
|
// //
|
||||||
|
// // `Unimplemented` selecting `Binder(<T as MyDisplay>)` during codegen
|
||||||
|
//
|
||||||
|
// writer.my_write(valref)
|
||||||
|
|
||||||
|
// This one causes the ICE:
|
||||||
|
// FulfillmentError(Obligation(predicate=Binder(TraitPredicate(<T as MyDisplay>)),
|
||||||
|
// depth=1),Unimplemented)
|
||||||
|
let closure = |config: &mut <S as MPU>::MpuConfig| writer.my_write(&config);
|
||||||
|
closure(valref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create() -> &'static dyn ProcessType {
|
||||||
|
let input: Option<&mut Process> = None;
|
||||||
|
let process: &mut Process = input.unwrap();
|
||||||
|
process
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
create();
|
||||||
|
}
|
17
src/test/ui/associated-types/issue-65774-1.stderr
Normal file
17
src/test/ui/associated-types/issue-65774-1.stderr
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
error[E0277]: the trait bound `T: MyDisplay` is not satisfied
|
||||||
|
--> $DIR/issue-65774-1.rs:10:21
|
||||||
|
|
|
||||||
|
LL | trait MPU {
|
||||||
|
| --------- required by `MPU`
|
||||||
|
LL | type MpuConfig: MyDisplay = T;
|
||||||
|
| ^^^^^^^^^ the trait `MyDisplay` is not implemented for `T`
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `T: MyDisplay` is not satisfied
|
||||||
|
--> $DIR/issue-65774-1.rs:16:6
|
||||||
|
|
|
||||||
|
LL | impl MPU for S { }
|
||||||
|
| ^^^ the trait `MyDisplay` is not implemented for `T`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
58
src/test/ui/associated-types/issue-65774-2.rs
Normal file
58
src/test/ui/associated-types/issue-65774-2.rs
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
#![feature(associated_type_defaults)]
|
||||||
|
|
||||||
|
trait MyDisplay { fn method(&self) { } }
|
||||||
|
|
||||||
|
impl<'a, T: MyDisplay> MyDisplay for &'a mut T { }
|
||||||
|
|
||||||
|
struct T;
|
||||||
|
|
||||||
|
trait MPU {
|
||||||
|
type MpuConfig: MyDisplay = T;
|
||||||
|
//~^ ERROR the trait bound `T: MyDisplay` is not satisfied
|
||||||
|
}
|
||||||
|
|
||||||
|
struct S;
|
||||||
|
|
||||||
|
impl MPU for S { }
|
||||||
|
//~^ ERROR the trait bound `T: MyDisplay` is not satisfied
|
||||||
|
|
||||||
|
trait MyWrite {
|
||||||
|
fn my_write(&self, _: &dyn MyDisplay) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
trait ProcessType {
|
||||||
|
fn process_detail_fmt(&self, _: &mut dyn MyWrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Process;
|
||||||
|
|
||||||
|
impl ProcessType for Process {
|
||||||
|
fn process_detail_fmt(&self, writer: &mut dyn MyWrite)
|
||||||
|
{
|
||||||
|
|
||||||
|
let mut val: Option<<S as MPU>::MpuConfig> = None;
|
||||||
|
let valref: &mut <S as MPU>::MpuConfig = val.as_mut().unwrap();
|
||||||
|
|
||||||
|
// // This causes a different ICE (but its similar if you squint right):
|
||||||
|
// //
|
||||||
|
// // `Unimplemented` selecting `Binder(<T as MyDisplay>)` during codegen
|
||||||
|
//
|
||||||
|
writer.my_write(valref)
|
||||||
|
|
||||||
|
// This one causes the ICE:
|
||||||
|
// FulfillmentError(Obligation(predicate=Binder(TraitPredicate(<T as MyDisplay>)),
|
||||||
|
// depth=1),Unimplemented)
|
||||||
|
/*let closure = |config: &mut <S as MPU>::MpuConfig| writer.my_write(&config);
|
||||||
|
closure(valref);*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create() -> &'static dyn ProcessType {
|
||||||
|
let input: Option<&mut Process> = None;
|
||||||
|
let process: &mut Process = input.unwrap();
|
||||||
|
process
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
create();
|
||||||
|
}
|
17
src/test/ui/associated-types/issue-65774-2.stderr
Normal file
17
src/test/ui/associated-types/issue-65774-2.stderr
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
error[E0277]: the trait bound `T: MyDisplay` is not satisfied
|
||||||
|
--> $DIR/issue-65774-2.rs:10:21
|
||||||
|
|
|
||||||
|
LL | trait MPU {
|
||||||
|
| --------- required by `MPU`
|
||||||
|
LL | type MpuConfig: MyDisplay = T;
|
||||||
|
| ^^^^^^^^^ the trait `MyDisplay` is not implemented for `T`
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `T: MyDisplay` is not satisfied
|
||||||
|
--> $DIR/issue-65774-2.rs:16:6
|
||||||
|
|
|
||||||
|
LL | impl MPU for S { }
|
||||||
|
| ^^^ the trait `MyDisplay` is not implemented for `T`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
|
@ -60,7 +60,7 @@ pub trait D {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// dox
|
/// dox
|
||||||
pub trait E {
|
pub trait E: Sized {
|
||||||
type AssociatedType; //~ ERROR: missing documentation for an associated type
|
type AssociatedType; //~ ERROR: missing documentation for an associated type
|
||||||
type AssociatedTypeDef = Self; //~ ERROR: missing documentation for an associated type
|
type AssociatedTypeDef = Self; //~ ERROR: missing documentation for an associated type
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,7 @@ mod priv_trait {
|
||||||
<Pub as PrivTr>::CONST;
|
<Pub as PrivTr>::CONST;
|
||||||
//~^ ERROR associated constant `PrivTr::CONST` is private
|
//~^ ERROR associated constant `PrivTr::CONST` is private
|
||||||
let _: <Pub as PrivTr>::AssocTy;
|
let _: <Pub as PrivTr>::AssocTy;
|
||||||
//~^ ERROR trait `priv_trait::PrivTr` is private
|
//~^ ERROR associated type `PrivTr::AssocTy` is private
|
||||||
//~| ERROR trait `priv_trait::PrivTr` is private
|
|
||||||
pub type InSignatureTy = <Pub as PrivTr>::AssocTy;
|
pub type InSignatureTy = <Pub as PrivTr>::AssocTy;
|
||||||
//~^ ERROR trait `priv_trait::PrivTr` is private
|
//~^ ERROR trait `priv_trait::PrivTr` is private
|
||||||
pub trait InSignatureTr: PrivTr {}
|
pub trait InSignatureTr: PrivTr {}
|
||||||
|
@ -116,15 +115,11 @@ mod priv_parent_substs {
|
||||||
<Priv as PubTr<_>>::CONST;
|
<Priv as PubTr<_>>::CONST;
|
||||||
//~^ ERROR type `priv_parent_substs::Priv` is private
|
//~^ ERROR type `priv_parent_substs::Priv` is private
|
||||||
|
|
||||||
let _: <Pub as PubTr>::AssocTy;
|
let _: <Pub as PubTr>::AssocTy; // FIXME no longer an error?!
|
||||||
//~^ ERROR type `priv_parent_substs::Priv` is private
|
|
||||||
//~| ERROR type `priv_parent_substs::Priv` is private
|
|
||||||
let _: <Pub as PubTr<_>>::AssocTy;
|
let _: <Pub as PubTr<_>>::AssocTy;
|
||||||
//~^ ERROR type `priv_parent_substs::Priv` is private
|
//~^ ERROR type `priv_parent_substs::Priv` is private
|
||||||
//~| ERROR type `priv_parent_substs::Priv` is private
|
|
||||||
let _: <Priv as PubTr<_>>::AssocTy;
|
let _: <Priv as PubTr<_>>::AssocTy;
|
||||||
//~^ ERROR type `priv_parent_substs::Priv` is private
|
//~^ ERROR type `priv_parent_substs::Priv` is private
|
||||||
//~| ERROR type `priv_parent_substs::Priv` is private
|
|
||||||
|
|
||||||
pub type InSignatureTy1 = <Pub as PubTr>::AssocTy;
|
pub type InSignatureTy1 = <Pub as PubTr>::AssocTy;
|
||||||
//~^ ERROR type `priv_parent_substs::Priv` is private
|
//~^ ERROR type `priv_parent_substs::Priv` is private
|
||||||
|
|
|
@ -42,18 +42,7 @@ LL | priv_trait::mac!();
|
||||||
|
|
|
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: trait `priv_trait::PrivTr` is private
|
error: associated type `PrivTr::AssocTy` is private
|
||||||
--> $DIR/associated-item-privacy-trait.rs:25:13
|
|
||||||
|
|
|
||||||
LL | let _: <Pub as PrivTr>::AssocTy;
|
|
||||||
| ^
|
|
||||||
...
|
|
||||||
LL | priv_trait::mac!();
|
|
||||||
| ------------------- in this macro invocation
|
|
||||||
|
|
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: trait `priv_trait::PrivTr` is private
|
|
||||||
--> $DIR/associated-item-privacy-trait.rs:25:16
|
--> $DIR/associated-item-privacy-trait.rs:25:16
|
||||||
|
|
|
|
||||||
LL | let _: <Pub as PrivTr>::AssocTy;
|
LL | let _: <Pub as PrivTr>::AssocTy;
|
||||||
|
@ -65,7 +54,7 @@ LL | priv_trait::mac!();
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: trait `priv_trait::PrivTr` is private
|
error: trait `priv_trait::PrivTr` is private
|
||||||
--> $DIR/associated-item-privacy-trait.rs:28:34
|
--> $DIR/associated-item-privacy-trait.rs:27:34
|
||||||
|
|
|
|
||||||
LL | pub type InSignatureTy = <Pub as PrivTr>::AssocTy;
|
LL | pub type InSignatureTy = <Pub as PrivTr>::AssocTy;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -76,7 +65,7 @@ LL | priv_trait::mac!();
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: trait `priv_trait::PrivTr` is private
|
error: trait `priv_trait::PrivTr` is private
|
||||||
--> $DIR/associated-item-privacy-trait.rs:30:34
|
--> $DIR/associated-item-privacy-trait.rs:29:34
|
||||||
|
|
|
|
||||||
LL | pub trait InSignatureTr: PrivTr {}
|
LL | pub trait InSignatureTr: PrivTr {}
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
@ -87,7 +76,7 @@ LL | priv_trait::mac!();
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: trait `priv_trait::PrivTr` is private
|
error: trait `priv_trait::PrivTr` is private
|
||||||
--> $DIR/associated-item-privacy-trait.rs:32:14
|
--> $DIR/associated-item-privacy-trait.rs:31:14
|
||||||
|
|
|
|
||||||
LL | impl PrivTr for u8 {}
|
LL | impl PrivTr for u8 {}
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
@ -98,7 +87,7 @@ LL | priv_trait::mac!();
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: type `priv_signature::Priv` is private
|
error: type `priv_signature::Priv` is private
|
||||||
--> $DIR/associated-item-privacy-trait.rs:49:21
|
--> $DIR/associated-item-privacy-trait.rs:48:21
|
||||||
|
|
|
|
||||||
LL | let value = <Pub as PubTr>::method;
|
LL | let value = <Pub as PubTr>::method;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -109,7 +98,7 @@ LL | priv_signature::mac!();
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: type `priv_signature::Priv` is private
|
error: type `priv_signature::Priv` is private
|
||||||
--> $DIR/associated-item-privacy-trait.rs:51:9
|
--> $DIR/associated-item-privacy-trait.rs:50:9
|
||||||
|
|
|
|
||||||
LL | value;
|
LL | value;
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
@ -120,7 +109,7 @@ LL | priv_signature::mac!();
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: type `priv_signature::Priv` is private
|
error: type `priv_signature::Priv` is private
|
||||||
--> $DIR/associated-item-privacy-trait.rs:53:13
|
--> $DIR/associated-item-privacy-trait.rs:52:13
|
||||||
|
|
|
|
||||||
LL | Pub.method(loop {});
|
LL | Pub.method(loop {});
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
@ -131,7 +120,7 @@ LL | priv_signature::mac!();
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: type `priv_substs::Priv` is private
|
error: type `priv_substs::Priv` is private
|
||||||
--> $DIR/associated-item-privacy-trait.rs:70:21
|
--> $DIR/associated-item-privacy-trait.rs:69:21
|
||||||
|
|
|
|
||||||
LL | let value = <Pub as PubTr>::method::<Priv>;
|
LL | let value = <Pub as PubTr>::method::<Priv>;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -142,7 +131,7 @@ LL | priv_substs::mac!();
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: type `priv_substs::Priv` is private
|
error: type `priv_substs::Priv` is private
|
||||||
--> $DIR/associated-item-privacy-trait.rs:72:9
|
--> $DIR/associated-item-privacy-trait.rs:71:9
|
||||||
|
|
|
|
||||||
LL | value;
|
LL | value;
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
@ -153,7 +142,7 @@ LL | priv_substs::mac!();
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: type `priv_substs::Priv` is private
|
error: type `priv_substs::Priv` is private
|
||||||
--> $DIR/associated-item-privacy-trait.rs:74:9
|
--> $DIR/associated-item-privacy-trait.rs:73:9
|
||||||
|
|
|
|
||||||
LL | Pub.method::<Priv>();
|
LL | Pub.method::<Priv>();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -164,7 +153,7 @@ LL | priv_substs::mac!();
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: type `priv_parent_substs::Priv` is private
|
error: type `priv_parent_substs::Priv` is private
|
||||||
--> $DIR/associated-item-privacy-trait.rs:94:21
|
--> $DIR/associated-item-privacy-trait.rs:93:21
|
||||||
|
|
|
|
||||||
LL | let value = <Pub as PubTr>::method;
|
LL | let value = <Pub as PubTr>::method;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -175,7 +164,7 @@ LL | priv_parent_substs::mac!();
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: type `priv_parent_substs::Priv` is private
|
error: type `priv_parent_substs::Priv` is private
|
||||||
--> $DIR/associated-item-privacy-trait.rs:96:9
|
--> $DIR/associated-item-privacy-trait.rs:95:9
|
||||||
|
|
|
|
||||||
LL | value;
|
LL | value;
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
@ -186,7 +175,7 @@ LL | priv_parent_substs::mac!();
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: type `priv_parent_substs::Priv` is private
|
error: type `priv_parent_substs::Priv` is private
|
||||||
--> $DIR/associated-item-privacy-trait.rs:98:21
|
--> $DIR/associated-item-privacy-trait.rs:97:21
|
||||||
|
|
|
|
||||||
LL | let value = <Pub as PubTr<_>>::method;
|
LL | let value = <Pub as PubTr<_>>::method;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -197,7 +186,7 @@ LL | priv_parent_substs::mac!();
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: type `priv_parent_substs::Priv` is private
|
error: type `priv_parent_substs::Priv` is private
|
||||||
--> $DIR/associated-item-privacy-trait.rs:100:9
|
--> $DIR/associated-item-privacy-trait.rs:99:9
|
||||||
|
|
|
|
||||||
LL | value;
|
LL | value;
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
@ -208,7 +197,7 @@ LL | priv_parent_substs::mac!();
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: type `priv_parent_substs::Priv` is private
|
error: type `priv_parent_substs::Priv` is private
|
||||||
--> $DIR/associated-item-privacy-trait.rs:102:9
|
--> $DIR/associated-item-privacy-trait.rs:101:9
|
||||||
|
|
|
|
||||||
LL | Pub.method();
|
LL | Pub.method();
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
|
@ -219,7 +208,7 @@ LL | priv_parent_substs::mac!();
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: type `priv_parent_substs::Priv` is private
|
error: type `priv_parent_substs::Priv` is private
|
||||||
--> $DIR/associated-item-privacy-trait.rs:105:21
|
--> $DIR/associated-item-privacy-trait.rs:104:21
|
||||||
|
|
|
|
||||||
LL | let value = <Priv as PubTr<_>>::method;
|
LL | let value = <Priv as PubTr<_>>::method;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -230,7 +219,7 @@ LL | priv_parent_substs::mac!();
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: type `priv_parent_substs::Priv` is private
|
error: type `priv_parent_substs::Priv` is private
|
||||||
--> $DIR/associated-item-privacy-trait.rs:107:9
|
--> $DIR/associated-item-privacy-trait.rs:106:9
|
||||||
|
|
|
|
||||||
LL | value;
|
LL | value;
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
@ -241,7 +230,7 @@ LL | priv_parent_substs::mac!();
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: type `priv_parent_substs::Priv` is private
|
error: type `priv_parent_substs::Priv` is private
|
||||||
--> $DIR/associated-item-privacy-trait.rs:109:9
|
--> $DIR/associated-item-privacy-trait.rs:108:9
|
||||||
|
|
|
|
||||||
LL | Priv.method();
|
LL | Priv.method();
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
@ -252,7 +241,7 @@ LL | priv_parent_substs::mac!();
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: type `priv_parent_substs::Priv` is private
|
error: type `priv_parent_substs::Priv` is private
|
||||||
--> $DIR/associated-item-privacy-trait.rs:112:9
|
--> $DIR/associated-item-privacy-trait.rs:111:9
|
||||||
|
|
|
|
||||||
LL | <Pub as PubTr>::CONST;
|
LL | <Pub as PubTr>::CONST;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -263,7 +252,7 @@ LL | priv_parent_substs::mac!();
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: type `priv_parent_substs::Priv` is private
|
error: type `priv_parent_substs::Priv` is private
|
||||||
--> $DIR/associated-item-privacy-trait.rs:114:9
|
--> $DIR/associated-item-privacy-trait.rs:113:9
|
||||||
|
|
|
|
||||||
LL | <Pub as PubTr<_>>::CONST;
|
LL | <Pub as PubTr<_>>::CONST;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -274,7 +263,7 @@ LL | priv_parent_substs::mac!();
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: type `priv_parent_substs::Priv` is private
|
error: type `priv_parent_substs::Priv` is private
|
||||||
--> $DIR/associated-item-privacy-trait.rs:116:9
|
--> $DIR/associated-item-privacy-trait.rs:115:9
|
||||||
|
|
|
|
||||||
LL | <Priv as PubTr<_>>::CONST;
|
LL | <Priv as PubTr<_>>::CONST;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -285,32 +274,10 @@ LL | priv_parent_substs::mac!();
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: type `priv_parent_substs::Priv` is private
|
error: type `priv_parent_substs::Priv` is private
|
||||||
--> $DIR/associated-item-privacy-trait.rs:119:13
|
--> $DIR/associated-item-privacy-trait.rs:119:30
|
||||||
|
|
|
||||||
LL | let _: <Pub as PubTr>::AssocTy;
|
|
||||||
| ^
|
|
||||||
...
|
|
||||||
LL | priv_parent_substs::mac!();
|
|
||||||
| --------------------------- in this macro invocation
|
|
||||||
|
|
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: type `priv_parent_substs::Priv` is private
|
|
||||||
--> $DIR/associated-item-privacy-trait.rs:119:16
|
|
||||||
|
|
|
||||||
LL | let _: <Pub as PubTr>::AssocTy;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
...
|
|
||||||
LL | priv_parent_substs::mac!();
|
|
||||||
| --------------------------- in this macro invocation
|
|
||||||
|
|
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: type `priv_parent_substs::Priv` is private
|
|
||||||
--> $DIR/associated-item-privacy-trait.rs:122:13
|
|
||||||
|
|
|
|
||||||
LL | let _: <Pub as PubTr<_>>::AssocTy;
|
LL | let _: <Pub as PubTr<_>>::AssocTy;
|
||||||
| ^
|
| ^
|
||||||
...
|
...
|
||||||
LL | priv_parent_substs::mac!();
|
LL | priv_parent_substs::mac!();
|
||||||
| --------------------------- in this macro invocation
|
| --------------------------- in this macro invocation
|
||||||
|
@ -318,21 +285,10 @@ LL | priv_parent_substs::mac!();
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: type `priv_parent_substs::Priv` is private
|
error: type `priv_parent_substs::Priv` is private
|
||||||
--> $DIR/associated-item-privacy-trait.rs:122:16
|
--> $DIR/associated-item-privacy-trait.rs:121:17
|
||||||
|
|
|
||||||
LL | let _: <Pub as PubTr<_>>::AssocTy;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
...
|
|
||||||
LL | priv_parent_substs::mac!();
|
|
||||||
| --------------------------- in this macro invocation
|
|
||||||
|
|
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: type `priv_parent_substs::Priv` is private
|
|
||||||
--> $DIR/associated-item-privacy-trait.rs:125:13
|
|
||||||
|
|
|
|
||||||
LL | let _: <Priv as PubTr<_>>::AssocTy;
|
LL | let _: <Priv as PubTr<_>>::AssocTy;
|
||||||
| ^
|
| ^^^^
|
||||||
...
|
...
|
||||||
LL | priv_parent_substs::mac!();
|
LL | priv_parent_substs::mac!();
|
||||||
| --------------------------- in this macro invocation
|
| --------------------------- in this macro invocation
|
||||||
|
@ -340,18 +296,7 @@ LL | priv_parent_substs::mac!();
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: type `priv_parent_substs::Priv` is private
|
error: type `priv_parent_substs::Priv` is private
|
||||||
--> $DIR/associated-item-privacy-trait.rs:125:16
|
--> $DIR/associated-item-privacy-trait.rs:124:35
|
||||||
|
|
|
||||||
LL | let _: <Priv as PubTr<_>>::AssocTy;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
...
|
|
||||||
LL | priv_parent_substs::mac!();
|
|
||||||
| --------------------------- in this macro invocation
|
|
||||||
|
|
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: type `priv_parent_substs::Priv` is private
|
|
||||||
--> $DIR/associated-item-privacy-trait.rs:129:35
|
|
||||||
|
|
|
|
||||||
LL | pub type InSignatureTy1 = <Pub as PubTr>::AssocTy;
|
LL | pub type InSignatureTy1 = <Pub as PubTr>::AssocTy;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -362,7 +307,7 @@ LL | priv_parent_substs::mac!();
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: type `priv_parent_substs::Priv` is private
|
error: type `priv_parent_substs::Priv` is private
|
||||||
--> $DIR/associated-item-privacy-trait.rs:131:35
|
--> $DIR/associated-item-privacy-trait.rs:126:35
|
||||||
|
|
|
|
||||||
LL | pub type InSignatureTy2 = <Priv as PubTr<Pub>>::AssocTy;
|
LL | pub type InSignatureTy2 = <Priv as PubTr<Pub>>::AssocTy;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -373,7 +318,7 @@ LL | priv_parent_substs::mac!();
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: type `priv_parent_substs::Priv` is private
|
error: type `priv_parent_substs::Priv` is private
|
||||||
--> $DIR/associated-item-privacy-trait.rs:133:14
|
--> $DIR/associated-item-privacy-trait.rs:128:14
|
||||||
|
|
|
|
||||||
LL | impl PubTr for u8 {}
|
LL | impl PubTr for u8 {}
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
@ -383,5 +328,5 @@ LL | priv_parent_substs::mac!();
|
||||||
|
|
|
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: aborting due to 35 previous errors
|
error: aborting due to 30 previous errors
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,11 @@ mod m {
|
||||||
impl PrivTr for Priv {}
|
impl PrivTr for Priv {}
|
||||||
pub trait PubTrAux1<T> {}
|
pub trait PubTrAux1<T> {}
|
||||||
pub trait PubTrAux2 { type A; }
|
pub trait PubTrAux2 { type A; }
|
||||||
|
impl<T> PubTrAux1<T> for u8 {}
|
||||||
|
impl PubTrAux2 for u8 {
|
||||||
|
type A = Priv;
|
||||||
|
//~^ ERROR private type `m::Priv` in public interface
|
||||||
|
}
|
||||||
|
|
||||||
// "Private-in-public in associated types is hard error" in RFC 2145
|
// "Private-in-public in associated types is hard error" in RFC 2145
|
||||||
// applies only to the aliased types, not bounds.
|
// applies only to the aliased types, not bounds.
|
||||||
|
|
|
@ -1,5 +1,14 @@
|
||||||
|
error[E0446]: private type `m::Priv` in public interface
|
||||||
|
--> $DIR/private-in-public-assoc-ty.rs:15:9
|
||||||
|
|
|
||||||
|
LL | struct Priv;
|
||||||
|
| - `m::Priv` declared as private
|
||||||
|
...
|
||||||
|
LL | type A = Priv;
|
||||||
|
| ^^^^^^^^^^^^^^ can't leak private type
|
||||||
|
|
||||||
warning: private trait `m::PrivTr` in public interface (error E0445)
|
warning: private trait `m::PrivTr` in public interface (error E0445)
|
||||||
--> $DIR/private-in-public-assoc-ty.rs:16:5
|
--> $DIR/private-in-public-assoc-ty.rs:21:5
|
||||||
|
|
|
|
||||||
LL | / pub trait PubTr {
|
LL | / pub trait PubTr {
|
||||||
LL | |
|
LL | |
|
||||||
|
@ -15,7 +24,7 @@ LL | | }
|
||||||
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
|
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
|
||||||
|
|
||||||
warning: private type `m::Priv` in public interface (error E0446)
|
warning: private type `m::Priv` in public interface (error E0446)
|
||||||
--> $DIR/private-in-public-assoc-ty.rs:16:5
|
--> $DIR/private-in-public-assoc-ty.rs:21:5
|
||||||
|
|
|
|
||||||
LL | / pub trait PubTr {
|
LL | / pub trait PubTr {
|
||||||
LL | |
|
LL | |
|
||||||
|
@ -30,7 +39,7 @@ LL | | }
|
||||||
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
|
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
|
||||||
|
|
||||||
warning: private type `m::Priv` in public interface (error E0446)
|
warning: private type `m::Priv` in public interface (error E0446)
|
||||||
--> $DIR/private-in-public-assoc-ty.rs:16:5
|
--> $DIR/private-in-public-assoc-ty.rs:21:5
|
||||||
|
|
|
|
||||||
LL | / pub trait PubTr {
|
LL | / pub trait PubTr {
|
||||||
LL | |
|
LL | |
|
||||||
|
@ -45,7 +54,7 @@ LL | | }
|
||||||
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
|
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
|
||||||
|
|
||||||
error[E0446]: private type `m::Priv` in public interface
|
error[E0446]: private type `m::Priv` in public interface
|
||||||
--> $DIR/private-in-public-assoc-ty.rs:27:9
|
--> $DIR/private-in-public-assoc-ty.rs:32:9
|
||||||
|
|
|
|
||||||
LL | struct Priv;
|
LL | struct Priv;
|
||||||
| - `m::Priv` declared as private
|
| - `m::Priv` declared as private
|
||||||
|
@ -54,7 +63,7 @@ LL | type Alias4 = Priv;
|
||||||
| ^^^^^^^^^^^^^^^^^^^ can't leak private type
|
| ^^^^^^^^^^^^^^^^^^^ can't leak private type
|
||||||
|
|
||||||
error[E0446]: private type `m::Priv` in public interface
|
error[E0446]: private type `m::Priv` in public interface
|
||||||
--> $DIR/private-in-public-assoc-ty.rs:34:9
|
--> $DIR/private-in-public-assoc-ty.rs:39:9
|
||||||
|
|
|
|
||||||
LL | struct Priv;
|
LL | struct Priv;
|
||||||
| - `m::Priv` declared as private
|
| - `m::Priv` declared as private
|
||||||
|
@ -63,7 +72,7 @@ LL | type Alias1 = Priv;
|
||||||
| ^^^^^^^^^^^^^^^^^^^ can't leak private type
|
| ^^^^^^^^^^^^^^^^^^^ can't leak private type
|
||||||
|
|
||||||
error[E0445]: private trait `m::PrivTr` in public interface
|
error[E0445]: private trait `m::PrivTr` in public interface
|
||||||
--> $DIR/private-in-public-assoc-ty.rs:37:9
|
--> $DIR/private-in-public-assoc-ty.rs:42:9
|
||||||
|
|
|
|
||||||
LL | trait PrivTr {}
|
LL | trait PrivTr {}
|
||||||
| - `m::PrivTr` declared as private
|
| - `m::PrivTr` declared as private
|
||||||
|
@ -72,7 +81,7 @@ LL | type Exist = impl PrivTr;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait
|
||||||
|
|
||||||
error[E0445]: private trait `m::PrivTr` in public interface
|
error[E0445]: private trait `m::PrivTr` in public interface
|
||||||
--> $DIR/private-in-public-assoc-ty.rs:37:9
|
--> $DIR/private-in-public-assoc-ty.rs:42:9
|
||||||
|
|
|
|
||||||
LL | trait PrivTr {}
|
LL | trait PrivTr {}
|
||||||
| - `m::PrivTr` declared as private
|
| - `m::PrivTr` declared as private
|
||||||
|
@ -80,7 +89,7 @@ LL | trait PrivTr {}
|
||||||
LL | type Exist = impl PrivTr;
|
LL | type Exist = impl PrivTr;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0445, E0446.
|
Some errors have detailed explanations: E0445, E0446.
|
||||||
For more information about an error, try `rustc --explain E0445`.
|
For more information about an error, try `rustc --explain E0445`.
|
||||||
|
|
|
@ -35,7 +35,7 @@ fn main() {
|
||||||
<u8 as A>::N::NN; //~ ERROR cannot find associated type `N` in `A`
|
<u8 as A>::N::NN; //~ ERROR cannot find associated type `N` in `A`
|
||||||
let _: <u8 as Tr>::Y::NN; //~ ERROR ambiguous associated type
|
let _: <u8 as Tr>::Y::NN; //~ ERROR ambiguous associated type
|
||||||
let _: <u8 as E>::Y::NN; //~ ERROR expected associated type, found variant `E::Y`
|
let _: <u8 as E>::Y::NN; //~ ERROR expected associated type, found variant `E::Y`
|
||||||
<u8 as Tr>::Y::NN; //~ ERROR no associated item named `NN` found
|
<u8 as Tr>::Y::NN; //~ ERROR no associated item named `NN` found for type `u16`
|
||||||
<u8 as E>::Y::NN; //~ ERROR expected associated type, found variant `E::Y`
|
<u8 as E>::Y::NN; //~ ERROR expected associated type, found variant `E::Y`
|
||||||
|
|
||||||
let _: <u8 as Tr::N>::NN; //~ ERROR cannot find associated type `NN` in `Tr::N`
|
let _: <u8 as Tr::N>::NN; //~ ERROR cannot find associated type `NN` in `Tr::N`
|
||||||
|
@ -52,5 +52,5 @@ fn main() {
|
||||||
let _: <u8 as Dr>::Z; //~ ERROR expected associated type, found method `Dr::Z`
|
let _: <u8 as Dr>::Z; //~ ERROR expected associated type, found method `Dr::Z`
|
||||||
<u8 as Dr>::X; //~ ERROR expected method or associated constant, found associated type `Dr::X`
|
<u8 as Dr>::X; //~ ERROR expected method or associated constant, found associated type `Dr::X`
|
||||||
let _: <u8 as Dr>::Z::N; //~ ERROR expected associated type, found method `Dr::Z`
|
let _: <u8 as Dr>::Z::N; //~ ERROR expected associated type, found method `Dr::Z`
|
||||||
<u8 as Dr>::X::N; //~ ERROR no associated item named `N` found
|
<u8 as Dr>::X::N; //~ ERROR no associated item named `N` found for type `u16`
|
||||||
}
|
}
|
||||||
|
|
|
@ -205,19 +205,19 @@ error[E0223]: ambiguous associated type
|
||||||
--> $DIR/ufcs-partially-resolved.rs:36:12
|
--> $DIR/ufcs-partially-resolved.rs:36:12
|
||||||
|
|
|
|
||||||
LL | let _: <u8 as Tr>::Y::NN;
|
LL | let _: <u8 as Tr>::Y::NN;
|
||||||
| ^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<<u8 as Tr>::Y as Trait>::NN`
|
| ^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<u16 as Trait>::NN`
|
||||||
|
|
||||||
error[E0599]: no associated item named `NN` found for associated type `<u8 as Tr>::Y` in the current scope
|
error[E0599]: no associated item named `NN` found for type `u16` in the current scope
|
||||||
--> $DIR/ufcs-partially-resolved.rs:38:20
|
--> $DIR/ufcs-partially-resolved.rs:38:20
|
||||||
|
|
|
|
||||||
LL | <u8 as Tr>::Y::NN;
|
LL | <u8 as Tr>::Y::NN;
|
||||||
| ^^ associated item not found in `<u8 as Tr>::Y`
|
| ^^ associated item not found in `u16`
|
||||||
|
|
||||||
error[E0599]: no associated item named `N` found for associated type `<u8 as Dr>::X` in the current scope
|
error[E0599]: no associated item named `N` found for type `u16` in the current scope
|
||||||
--> $DIR/ufcs-partially-resolved.rs:55:20
|
--> $DIR/ufcs-partially-resolved.rs:55:20
|
||||||
|
|
|
|
||||||
LL | <u8 as Dr>::X::N;
|
LL | <u8 as Dr>::X::N;
|
||||||
| ^ associated item not found in `<u8 as Dr>::X`
|
| ^ associated item not found in `u16`
|
||||||
|
|
||||||
error: aborting due to 32 previous errors
|
error: aborting due to 32 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue