Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement RFC 2532 – Associated Type Defaults #61812

Open
wants to merge 12 commits into
base: master
from

Conversation

@jonas-schievink
Copy link
Member

commented Jun 13, 2019

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).

cc #29661
Fixes #53907
Fixes #54182
Fixes #62211

@rust-highfive

This comment was marked as outdated.

Copy link
Collaborator

commented Jun 13, 2019

r? @cramertj

(rust_highfive has picked a reviewer for you, use r? to override)

@@ -1104,27 +1104,41 @@ fn assemble_candidates_from_impls<'cx, 'gcx, 'tcx>(
// an error when we confirm the candidate
// (which will ultimately lead to `normalize_to_error`
// being invoked).
node_item.item.defaultness.has_value()
false

This comment has been minimized.

Copy link
@jonas-schievink

jonas-schievink Jun 13, 2019

Author Member

This looks very wrong to me, since it sounds like it'd allow assuming defaults inside the trait. For some reason that doesn't happen (the tests pass).

This comment has been minimized.

Copy link
@arielb1

arielb1 Jul 4, 2019

Contributor

@jonas-schievink

Inside the trait, you won't be having a VtableImpl (which indicates a specific impl was selected), but a VtableParam (because of an "implicit where-clause").

This comment has been minimized.

Copy link
@arielb1

arielb1 Jul 4, 2019

Contributor

However, this does not correctly handle the case where an associated type default is overridden in a derived impl:

#![feature(associated_type_defaults, specialization)]

trait Foo {
    type Xyz = u32;
    fn foobar() -> Self::Xyz;
}

// 1)
impl<T> Foo for T {
    fn foobar() -> Self::Xyz { 0u32 }
}

// 2)
impl Foo for u32 {
    type Xyz = &'static u32;
}

fn main() {
    u32::foobar();
}

This comment has been minimized.

Copy link
@arielb1

arielb1 Jul 4, 2019

Contributor

However, according to the spec, the problem is somewhere else, because of

To permit this is not a problem because Foo for Vec<T> is not further specializable since Bar in the implementation has not been marked as default.

This comment has been minimized.

Copy link
@Centril

Centril Jul 6, 2019

Member

However, according to the spec, the problem is somewhere else, because of

So the RFC says:

If an implementation does make the associated type available for further specialization, then other definitions in the implementation may not assume the given underlying specified type of the associated type and may only assume that it is Self::TheAssociatedType.

which the snippet above clearly violates... but the more interesting question is "how do we ban it?"...

...For the sake of separate compilation (i.e. imagine 2) is in a different crate), I think we need to say that 1) is legitimate but 2) is not. Why? Because it overrides type Xyz which should not be up for specialization since it was not marked as default in 1) (if it did then fn foobar could not assume type Xyz's definition). Moreover fn foobar here assumes type Xyz's definition.

This comment has been minimized.

Copy link
@arielb1

arielb1 Jul 6, 2019

Contributor

Sure. If we go by the RFC, the default associated type type Xyz = u32; should only be specializable by the first impl that matches, not by any specializing impls (this can be checked at 2) time because of the orphan rules), so 2) should give an E0520 (Xyz specializes an item from a parent impl, but that item is not marked default).

I'll note that this contradicts the way associated fns work:

#![feature(specialization)]

trait Foo {
    fn foobar() -> bool { false }
}

impl<T> Foo for T {
}

impl Foo for u32 {
    fn foobar() -> bool { true }
}

fn main() {
    println!("{:?}", u32::foobar()); // prints `true`
}

also, if we do that, we have to decide whether associated consts should work like associated types or like associated fns.

This comment has been minimized.

Copy link
@Centril

Centril Jul 6, 2019

Member

also, if we do that, we have to decide whether associated consts should work like associated types or like associated fns.

The RFC applies to associated fns as well so how they work will need to be changed as well but not necessarily in this PR. The RFC says:

This applies generally to any item inside a trait. [...]

which includes fns and consts also.

This comment has been minimized.

Copy link
@arielb1

arielb1 Jul 6, 2019

Contributor

This is an open question in the design of specialization (#31844):

Should default trait items be considered default (i.e. specializable)?

Specialization is unstable, so I don't think there's a real reason not to forbid respecialization of associated types and associated fns together. However, I might want to do this in an earlier PR, and assess crater impact.

That change that has a fair bit of breaking impact, so I'm for implementing it fairly quickly. However, I'll still be OK with opening an issue for the specialization rules change and linking it from the OP of #29661.

This comment has been minimized.

Copy link
@arielb1

arielb1 Jul 6, 2019

Contributor

If we continue on this question: can you have default provided trait items that can be re-overriden?

#![feature(specialization)]

trait Foo {
    default fn foobar() -> bool { false }
}

impl<T> Foo for T {
}

impl Foo for u32 {
    fn foobar() -> bool { true } // OK
}

fn main() {
    println!("{:?}", u32::foobar()); // prints `true`
}

I think either option would be worth writing clearly in a "changes to specialization" section in RFC 2532, along with examples.

This comment has been minimized.

Copy link
@Centril

Centril Jul 6, 2019

Member

This is an open question in the design of specialization (#31844):

Should default trait items be considered default (i.e. specializable)?

This is a bit of an orthogonal question; the main question is instead whether re-overriding is allowed as you point out later. I think it flows from the reference of the RFC and the spirit of it that re-overriding is banned. Instead, the idea is that 1) in both of your snippets "lock in" what they do not explicitly allow for further specialization (with default $item in impls). Whether trait items must be prefixed with default to be specializable is not a particularly interesting question from this perspective and especially not from the POV of specialization groups as per in the "future possibilities" section of the RFC.

I think either option would be worth writing clearly in a "changes to specialization" section in RFC 2532, along with examples.

It's a good idea to write down interesting points and decisions somewhere be it in the RFC or in the tracking issue. I think we can link to this discussion in a bullet point in the tracking issue description and then consider amending the RFC with new information at a later point (when things have slowed down and the pieces are in place). These notes will be useful when I (or someone else, but most likely not...) writes the stabilization report.

let _: <Pub as PubTr>::AssocTy;
//~^ ERROR type `priv_parent_substs::Priv` is private
//~| ERROR type `priv_parent_substs::Priv` is private
let _: <Pub as PubTr>::AssocTy; // TODO no longer an error?!

This comment has been minimized.

Copy link
@jonas-schievink

jonas-schievink Jun 13, 2019

Author Member

This also looks extremely wrong to me since the only difference to the code below is the omission of <_>, but I can't imagine how this patch caused this, so it might be preexisting?

@@ -184,19 +184,19 @@ error[E0223]: ambiguous associated type
--> $DIR/ufcs-partially-resolved.rs:36:12
|
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`

This comment has been minimized.

Copy link
@jonas-schievink

jonas-schievink Jun 13, 2019

Author Member

These suggestions are now worse due to the projection succeeding

@rust-highfive

This comment was marked as resolved.

Copy link
Collaborator

commented Jun 13, 2019

The job x86_64-gnu-llvm-6.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_time:end:1051bc8a:start=1560454881355272569,finish=1560454969695586405,duration=88340313836
$ git checkout -qf FETCH_HEAD
travis_fold:end:git.checkout

Encrypted environment variables have been removed for security reasons.
See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions
$ export SCCACHE_BUCKET=rust-lang-ci-sccache2
$ export SCCACHE_REGION=us-west-1
$ export GCP_CACHE_BUCKET=rust-lang-ci-cache
$ export AWS_ACCESS_KEY_ID=AKIA46X5W6CZEJZ6XT55
---

[00:04:12] travis_fold:start:tidy
travis_time:start:tidy
tidy check
[00:04:13] tidy error: /checkout/src/test/ui/privacy/associated-item-privacy-trait.rs:118: TODO is deprecated; use FIXME
[00:04:17] some tidy checks failed
[00:04:17] 
[00:04:17] 
[00:04:17] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/tidy" "/checkout/src" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "--no-vendor" "--quiet"
[00:04:17] 
[00:04:17] 
[00:04:17] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test src/tools/tidy
[00:04:17] Build completed unsuccessfully in 0:01:12
---
travis_time:end:2248f4ff:start=1560455237421235546,finish=1560455237426042414,duration=4806868
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:0e0e58fa
$ ln -s . checkout && for CORE in obj/cores/core.*; do EXE=$(echo $CORE | sed 's|obj/cores/core\.[0-9]*\.!checkout!\(.*\)|\1|;y|!|/|'); if [ -f "$EXE" ]; then printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" "$CORE"; gdb --batch -q -c "$CORE" "$EXE" -iex 'set auto-load off' -iex 'dir src/' -iex 'set sysroot .' -ex bt -ex q; echo travis_fold":"end:crashlog; fi; done || true
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:0ac03467
travis_time:start:0ac03467
$ cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
cat: ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers: No such file or directory
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:1ab08f80
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@Centril

This comment has been minimized.

Copy link
Member

commented Jun 13, 2019

@jonas-schievink jonas-schievink force-pushed the jonas-schievink:assoc-ty-defaults branch from e2eeee1 to 62bd57c Jun 13, 2019

@Centril

This comment was marked as resolved.

Copy link
Member

commented Jun 13, 2019

It would be good to have tests for:
https://github.com/rust-lang/rfcs/blob/master/text/2532-associated-type-defaults.md#1-when-do-suitability-of-defaults-need-to-be-proven

I'm inclined that we should enforce condition (1) rather than (2) as it is more conservative. In particular, we do not allow:

trait A {
    const B: u8;
}

trait Foo<T> {
    const BAR: u8 = T::B;
}

so it seems most consistent with associated constants to not allow (2).

@Centril

This comment was marked as resolved.

Copy link
Member

commented Jun 13, 2019

(This was done)


While specialization is unstable, it would also be good to ensure that the aspects re. specialization and default as per the RFC are tested. If there are existing files that's good, maybe we can enhance them a bit. Otherwise let's add some.

RFC says:

When an associated type default exists in a trait definition, it need not be specified in the implementations of that trait. If implementations of that trait do not make that associated type available for specialization, the $default_type may be assumed in other items specified in the implementation. If an implementation does make the associated type available for further specialization, then other definitions in the implementation may not assume the given underlying specified type of the associated type and may only assume that it is Self::TheAssociatedType.

@rust-highfive

This comment was marked as outdated.

Copy link
Collaborator

commented Jun 14, 2019

The job x86_64-gnu-llvm-6.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_time:end:0082a3a2:start=1560464437639262387,finish=1560464438497883463,duration=858621076
$ git checkout -qf FETCH_HEAD
travis_fold:end:git.checkout

Encrypted environment variables have been removed for security reasons.
See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions
$ export SCCACHE_BUCKET=rust-lang-ci-sccache2
$ export SCCACHE_REGION=us-west-1
$ export GCP_CACHE_BUCKET=rust-lang-ci-cache
$ export AWS_ACCESS_KEY_ID=AKIA46X5W6CZEJZ6XT55
---
    99% |███████████████████████████████▉| 5.5MB 49.3MB/s eta 0:00:01
    99% |████████████████████████████████| 5.5MB 48.0MB/s eta 0:00:01
    99% |████████████████████████████████| 5.5MB 48.1MB/s eta 0:00:01
    100% |████████████████████████████████| 5.5MB 4.2MB/s 
Requirement already satisfied: PyYAML<=5.1,>=3.10; python_version != "2.6" in /usr/lib/python2.7/dist-packages (from awscli) (3.11)
  Downloading https://files.pythonhosted.org/packages/e1/ae/baedc9cb175552e95f3395c43055a6a5e125ae4d48a1d7a924baca83e92e/rsa-3.4.2-py2.py3-none-any.whl (46kB)
    21% |███████                         | 10kB 23.6MB/s eta 0:00:01
    43% |██████████████                  | 20kB 30.2MB/s eta 0:00:01
    65% |█████████████████████           | 30kB 34.7MB/s eta 0:00:01
---
travis_time:start:test_assembly
Check compiletest suite=assembly mode=assembly (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
[01:07:09] 
[01:07:09] running 9 tests
[01:07:09] iiiiiiiii
[01:07:09] 
[01:07:09]  finished in 0.148
[01:07:09] travis_fold:end:test_assembly

---
travis_time:start:test_debuginfo
Check compiletest suite=debuginfo mode=debuginfo-gdb+lldb (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
[01:07:24] 
[01:07:24] running 122 tests
[01:07:49] .iiiii...i.....i..i...i..i.i.i..i.ii..i.i.....i..i....i..........iiii..........i...ii...i.......ii.i 100/122
[01:07:53] .i.i......iii.i.....ii
[01:07:53] 
[01:07:53]  finished in 29.446
[01:07:53] travis_fold:end:test_debuginfo

---
[01:43:56] 
[01:43:56] failures:
[01:43:56] 
[01:43:56] ---- /checkout/obj/build/x86_64-unknown-linux-gnu/test/error-index.md - Rust_Compiler_Error_Index::E0399 (line 6170) stdout ----
[01:43:56] Test compiled successfully, but it's marked `compile_fail`.
[01:43:56] failures:
[01:43:56]     /checkout/obj/build/x86_64-unknown-linux-gnu/test/error-index.md - Rust_Compiler_Error_Index::E0399 (line 6170)
[01:43:56] 
[01:43:56] test result: FAILED. 679 passed; 1 failed; 24 ignored; 0 measured; 0 filtered out
---
travis_time:end:040cca9b:start=1560470687961666180,finish=1560470687966288178,duration=4621998
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:03ef4135
$ ln -s . checkout && for CORE in obj/cores/core.*; do EXE=$(echo $CORE | sed 's|obj/cores/core\.[0-9]*\.!checkout!\(.*\)|\1|;y|!|/|'); if [ -f "$EXE" ]; then printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" "$CORE"; gdb --batch -q -c "$CORE" "$EXE" -iex 'set auto-load off' -iex 'dir src/' -iex 'set sysroot .' -ex bt -ex q; echo travis_fold":"end:crashlog; fi; done || true
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:00f2d243
travis_time:start:00f2d243
$ cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
cat: ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers: No such file or directory
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:1105ee94
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@rust-highfive

This comment was marked as outdated.

Copy link
Collaborator

commented Jun 14, 2019

The job x86_64-gnu-llvm-6.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_time:end:2804af1e:start=1560540731265439520,finish=1560540822310006157,duration=91044566637
$ git checkout -qf FETCH_HEAD
travis_fold:end:git.checkout

Encrypted environment variables have been removed for security reasons.
See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions
$ export SCCACHE_BUCKET=rust-lang-ci-sccache2
$ export SCCACHE_REGION=us-west-1
$ export GCP_CACHE_BUCKET=rust-lang-ci-cache
$ export AWS_ACCESS_KEY_ID=AKIA46X5W6CZEJZ6XT55
---

[00:03:53] travis_fold:start:tidy
travis_time:start:tidy
tidy check
[00:03:54] tidy error: /checkout/src/test/ui/associated-types/defaults-specialization.rs: too many trailing newlines (2)
[00:03:58] some tidy checks failed
[00:03:58] 
[00:03:58] 
[00:03:58] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/tidy" "/checkout/src" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "--no-vendor" "--quiet"
[00:03:58] 
[00:03:58] 
[00:03:58] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test src/tools/tidy
[00:03:58] Build completed unsuccessfully in 0:01:13
---
travis_time:end:258cd9f4:start=1560541070903647819,finish=1560541070908370197,duration=4722378
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:11d12c50
$ ln -s . checkout && for CORE in obj/cores/core.*; do EXE=$(echo $CORE | sed 's|obj/cores/core\.[0-9]*\.!checkout!\(.*\)|\1|;y|!|/|'); if [ -f "$EXE" ]; then printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" "$CORE"; gdb --batch -q -c "$CORE" "$EXE" -iex 'set auto-load off' -iex 'dir src/' -iex 'set sysroot .' -ex bt -ex q; echo travis_fold":"end:crashlog; fi; done || true
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:1a18bdfa
travis_time:start:1a18bdfa
$ cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
cat: ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers: No such file or directory
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:1e310f2c
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

Show resolved Hide resolved src/test/ui/associated-types/defaults-specialization.rs
Show resolved Hide resolved src/test/ui/associated-types/defaults-specialization.rs
| ^^ expected associated type, found u8
|
= note: expected type `fn() -> <A<T> as Tr>::Ty`
found type `fn() -> u8`

This comment has been minimized.

Copy link
@Centril

Centril Jun 14, 2019

Member

I wonder if it would be feasible in a not-too-hacky a manner to tell the user that defaults are the cause of the failure (both when using specialization and not). Otherwise the user might be reasonably confused as to why they don't get to assume the default since they are unlikely to be aware of the type theoretical reasons.

This comment has been minimized.

Copy link
@Centril

Centril Jun 14, 2019

Member

This could also be left as future work; if you prefer that, please leave a checkbox in the tracking issue :)

Also cc @estebank

This comment has been minimized.

Copy link
@jonas-schievink

jonas-schievink Jun 14, 2019

Author Member

Yeah I'll do this. This is challenging enough as is ;)

This comment has been minimized.

Copy link
@Centril

Centril Jun 14, 2019

Member

For that future work... One thing you might try in the unhappy path is to check whether there is a default that would have allowed it to succeed if not for our rules.

@jonas-schievink jonas-schievink force-pushed the jonas-schievink:assoc-ty-defaults branch from b192b4b to a134319 Jun 14, 2019


if let Some(default_ty) = default {
let default_ty = AstConv::ast_ty_to_ty(&ItemCtxt::new(tcx, def_id), default_ty);
let preds = AstConv::compute_bounds(

This comment has been minimized.

Copy link
@Centril

Centril Jun 14, 2019

Member

Can you add a test to also make sure that bounds are respected when not written directly on the associated type itself?

trait Foo<T>
where
    // Same bound as `type Bar: Clone` but written indirectly:
    <Self as Foo<T>>::Bar: Clone,
{
    type Bar = Vec<T>;
}

This comment has been minimized.

Copy link
@Centril

Centril Jun 14, 2019

Member

Another case to consider is when you have multiple defaults:

trait Foo<T>
where
    <Self as Foo<T>>::Bar: Clone,
{
    type Bar = Vec<Self::Baz>;
    type Baz = T;
}

This comment has been minimized.

Copy link
@jonas-schievink

jonas-schievink Jun 15, 2019

Author Member

Yeah this doesn't work at all right now, this check needs to be implemented differently.

This gets particularly tricky when you have a where-clause like where Self::Ty: Con<Self> on the trait. You can't really know if this holds for the defaulted type because Self isn't yet known.

This comment has been minimized.

Copy link
@Centril

Centril Jun 15, 2019

Member

In general, when faced with a situation "you can't really know yet" this should be treated as if it wasn't so. In other words, we want constructive proof that something holds. So in a situation with where Self::Ty: Con<Self>, because Self isn't yet known, the answer is to treat it as a type variable (which it is...) and then error.

I think the check should be something along the lines of substituting the associated types for the defaults and then try to prove the normalized where clauses. It seems to me that rejecting where Self::Ty: Con<Self>, should just "fall out".

This comment has been minimized.

Copy link
@jonas-schievink

jonas-schievink Jun 15, 2019

Author Member

Just pushed a better implementation of the check and a comprehensive test

This comment has been minimized.

Copy link
@Centril

Centril Jun 15, 2019

Member

Looks great!

Can you also add my last snippet to that so we check for scenarios involving more than one associated type?

This comment has been minimized.

Copy link
@jonas-schievink

jonas-schievink Jun 15, 2019

Author Member

Done. Right now the behavior is to do a shallow replacement of associated types with their defaults, so <Self as Foo<T>>::Bar: Clone is turned into Vec<Self::Baz>, not Vec<T>. I guess this needs to be fixed.

This comment has been minimized.

Copy link
@jonas-schievink

jonas-schievink Jun 15, 2019

Author Member

Ah, I think the shallow substitution is actually beneficial here, since it forces the trait to work with any combination of defaults and non-defaults: If we did the deep substitution and had a T: Clone bound, we'd prove that Vec<T>: Clone and the trait would be accepted. If a user then implements it and overrides only Baz, suddenly Vec<Self::Baz>: Clone might no longer hold, and the user would be forced to also override Bar. With the shallow substitution, the trait would have to add a Self::Baz: Clone bound instead/in addition to the T: Clone bound, which means that an implementation could replace either assoc. type without making others not work anymore.

This comment has been minimized.

Copy link
@Centril

Centril Jun 15, 2019

Member

Interesting; it seems to me a shallow substitution is strictly more conservative than the deeper one, right? So we can relax it later if we want.

I think it would be good to demonstrate the difference in a special test file and then also leave a description of the distinction (with examples) on the tracking issue so that these interesting aspects aren't lost in comments here.

@rust-highfive

This comment was marked as outdated.

Copy link
Collaborator

commented Jun 14, 2019

The job x86_64-gnu-llvm-6.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_time:end:2885cb31:start=1560549390561877673,finish=1560549500272797708,duration=109710920035
$ git checkout -qf FETCH_HEAD
travis_fold:end:git.checkout

Encrypted environment variables have been removed for security reasons.
See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions
$ export SCCACHE_BUCKET=rust-lang-ci-sccache2
$ export SCCACHE_REGION=us-west-1
$ export GCP_CACHE_BUCKET=rust-lang-ci-cache
$ export AWS_ACCESS_KEY_ID=AKIA46X5W6CZEJZ6XT55
---
[00:58:18] .................................................................................................... 4000/5690
[00:58:21] ....i............................................................................................... 4100/5690
[00:58:23] ....................................................................i............................... 4200/5690
[00:58:25] .................................................................................................... 4300/5690
[00:58:33] .....................................................F.............................................. 4400/5690
[00:58:47] .................................................................................................... 4600/5690
[00:58:50] .................................................................................................... 4700/5690
[00:58:54] .................................................................................................... 4800/5690
[00:58:54] .................................................................................................... 4800/5690
[00:59:01] ........F........................................................................................... 4900/5690
[00:59:09] .................................................................................................... 5100/5690
[00:59:14] .................................................................................................... 5200/5690
[00:59:18] .................................................................................................... 5300/5690
[00:59:22] .................................................................................................... 5400/5690
[00:59:22] .................................................................................................... 5400/5690
[00:59:24] .................................................................................................... 5500/5690
[00:59:27] .................................................................................................... 5600/5690
[00:59:30] ............................i...............................F.F...........................
[00:59:30] 
[00:59:30] ---- [ui] ui/privacy/private-in-public-warn.rs stdout ----
[00:59:30] diff of stderr:
[00:59:30] 
[00:59:30] 
[00:59:30] 31    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 32 
[00:59:30] 33 error: private type `types::Priv` in public interface (error E0446)
[00:59:30] +    |
[00:59:30] + LL | /     pub trait Tr {
[00:59:30] + LL | /     pub trait Tr {
[00:59:30] + LL | |         const C: Priv = Priv;
[00:59:30] + LL | |
[00:59:30] + LL | |         type Alias = Priv;
[00:59:30] + ...  |
[00:59:30] + LL | |
[00:59:30] + LL | |     }
[00:59:30] +    |
[00:59:30] +    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30] +    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] + 
[00:59:30] + 
[00:59:30] + error: private type `types::Priv` in public interface (error E0446)
[00:59:30] 35    |
[00:59:30] 35    |
[00:59:30] 36 LL |         const C: Priv = Priv;
[00:59:30] 350    |
[00:59:30] 351    = help: the clause will not be checked when the type alias is used, and should be removed
[00:59:30] 352 
[00:59:30] - error: aborting due to 36 previous errors
[00:59:30] - error: aborting due to 36 previous errors
[00:59:30] + error: aborting due to 37 previous errors
[00:59:30] 354 
[00:59:30] 355 For more information about this error, try `rustc --explain E0446`.
[00:59:30] 356 
[00:59:30] 
[00:59:30] 
[00:59:30] The actual stderr differed from the expected stderr.
[00:59:30] Actual stderr saved to /checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/privacy/private-in-public-warn/private-in-public-warn.stderr
[00:59:30] To update references, rerun the tests and pass the `--bless` flag
[00:59:30] To only update this specific test, also pass `--test-args privacy/private-in-public-warn.rs`
[00:59:30] error: 1 errors occurred comparing output.
[00:59:30] status: exit code: 1
[00:59:30] status: exit code: 1
[00:59:30] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/ui/privacy/private-in-public-warn.rs" "-Zthreads=1" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/privacy/private-in-public-warn" "-Crpath" "-O" "-Cdebuginfo=0" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/privacy/private-in-public-warn/auxiliary" "-A" "unused"
[00:59:30] ------------------------------------------
[00:59:30] 
[00:59:30] ------------------------------------------
[00:59:30] stderr:
[00:59:30] stderr:
[00:59:30] ------------------------------------------
[00:59:30] error: private type `types::Priv` in public interface (error E0446)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |     pub type Alias = Priv; //~ ERROR private type `types::Priv` in public interface
[00:59:30]    |
[00:59:30] note: lint level defined here
[00:59:30]   --> /checkout/src/test/ui/privacy/private-in-public-warn.rs:5:9
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL | #![deny(private_in_public)]
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] error: private type `types::Priv` in public interface (error E0446)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |         V1(Priv), //~ ERROR private type `types::Priv` in public interface
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] error: private type `types::Priv` in public interface (error E0446)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |         V2 { field: Priv }, //~ ERROR private type `types::Priv` in public interface
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] error: private type `types::Priv` in public interface (error E0446)
[00:59:30]    |
[00:59:30] LL | /     pub trait Tr {
[00:59:30] LL | /     pub trait Tr {
[00:59:30] LL | |         const C: Priv = Priv; //~ ERROR private type `types::Priv` in public interface
[00:59:30] LL | |         //~^ WARNING hard error
[00:59:30] LL | |         type Alias = Priv; //~ ERROR private type `types::Priv` in public interface
[00:59:30] ...  |
[00:59:30] LL | |         //~^ WARNING hard error
[00:59:30]    | |_____^
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] error: private type `types::Priv` in public interface (error E0446)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |         const C: Priv = Priv; //~ ERROR private type `types::Priv` in public interface
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] error[E0446]: private type `types::Priv` in public interface
[00:59:30]   --> /checkout/src/test/ui/privacy/private-in-public-warn.rs:26:9
[00:59:30]    |
[00:59:30] LL |     struct Priv;
[00:59:30]    |     - `types::Priv` declared as private
[00:59:30] ...
[00:59:30] LL |         type Alias = Priv; //~ ERROR private type `types::Priv` in public interface
[00:59:30] 
[00:59:30] 
[00:59:30] error: private type `types::Priv` in public interface (error E0446)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |         fn f1(arg: Priv) {} //~ ERROR private type `types::Priv` in public interface
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] error: private type `types::Priv` in public interface (error E0446)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |         fn f2() -> Priv { panic!() } //~ ERROR private type `types::Priv` in public interface
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] error: private type `types::Priv` in public interface (error E0446)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |         pub static ES: Priv; //~ ERROR private type `types::Priv` in public interface
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] error: private type `types::Priv` in public interface (error E0446)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |         pub fn ef1(arg: Priv); //~ ERROR private type `types::Priv` in public interface
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] error: private type `types::Priv` in public interface (error E0446)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |         pub fn ef2() -> Priv; //~ ERROR private type `types::Priv` in public interface
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] error[E0446]: private type `types::Priv` in public interface
[00:59:30]   --> /checkout/src/test/ui/privacy/private-in-public-warn.rs:41:9
[00:59:30]    |
[00:59:30] LL |     struct Priv;
[00:59:30]    |     - `types::Priv` declared as private
[00:59:30] ...
[00:59:30] LL |         type Alias = Priv; //~ ERROR private type `types::Priv` in public interface
[00:59:30] 
[00:59:30] 
[00:59:30] error: private trait `traits::PrivTr` in public interface (error E0445)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |     pub type Alias<T: PrivTr> = T; //~ ERROR private trait `traits::PrivTr` in public interface
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] error: private trait `traits::PrivTr` in public interface (error E0445)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |     pub trait Tr1: PrivTr {} //~ ERROR private trait `traits::PrivTr` in public interface
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] error: private trait `traits::PrivTr` in public interface (error E0445)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |     pub trait Tr2<T: PrivTr> {} //~ ERROR private trait `traits::PrivTr` in public interface
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] error: private trait `traits::PrivTr` in public interface (error E0445)
[00:59:30]    |
[00:59:30] LL | /     pub trait Tr3 {
[00:59:30] LL | /     pub trait Tr3 {
[00:59:30] LL | |         //~^ ERROR private trait `traits::PrivTr` in public interface
[00:59:30] LL | |         //~| WARNING hard error
[00:59:30] LL | |         type Alias: PrivTr;
[00:59:30] LL | |         fn f<T: PrivTr>(arg: T) {} //~ ERROR private trait `traits::PrivTr` in public interface
[00:59:30] LL | |         //~^ WARNING hard error
[00:59:30]    | |_____^
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] error: private trait `traits::PrivTr` in public interface (error E0445)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |         fn f<T: PrivTr>(arg: T) {} //~ ERROR private trait `traits::PrivTr` in public interface
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] error: private trait `traits::PrivTr` in public interface (error E0445)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |     impl<T: PrivTr> Pub<T> {} //~ ERROR private trait `traits::PrivTr` in public interface
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] error: private trait `traits::PrivTr` in public interface (error E0445)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |     impl<T: PrivTr> PubTr for Pub<T> {} //~ ERROR private trait `traits::PrivTr` in public interface
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] error: private trait `traits_where::PrivTr` in public interface (error E0445)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |     pub type Alias<T> where T: PrivTr = T;
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] error: private trait `traits_where::PrivTr` in public interface (error E0445)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |     pub trait Tr2<T> where T: PrivTr {}
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] error: private trait `traits_where::PrivTr` in public interface (error E0445)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |         fn f<T>(arg: T) where T: PrivTr {}
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] error: private trait `traits_where::PrivTr` in public interface (error E0445)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |     impl<T> Pub<T> where T: PrivTr {}
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] error: private trait `traits_where::PrivTr` in public interface (error E0445)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |     impl<T> PubTr for Pub<T> where T: PrivTr {}
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] error: private trait `generics::PrivTr<generics::Pub>` in public interface (error E0445)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |     pub trait Tr1: PrivTr<Pub> {}
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] error: private type `generics::Priv` in public interface (error E0446)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |     pub trait Tr2: PubTr<Priv> {} //~ ERROR private type `generics::Priv` in public interface
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] error: private type `generics::Priv` in public interface (error E0446)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |     pub trait Tr3: PubTr<[Priv; 1]> {} //~ ERROR private type `generics::Priv` in public interface
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] error: private type `generics::Priv` in public interface (error E0446)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |     pub trait Tr4: PubTr<Pub<Priv>> {} //~ ERROR private type `generics::Priv` in public interface
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] error[E0446]: private type `impls::Priv` in public interface
[00:59:30]    |
[00:59:30] LL |     struct Priv;
[00:59:30] LL |     struct Priv;
[00:59:30]    |     - `impls::Priv` declared as private
[00:59:30] ...
[00:59:30] LL |         type Alias = Priv; //~ ERROR private type `impls::Priv` in public interface
[00:59:30] 
[00:59:30] 
[00:59:30] error: private type `aliases_pub::Priv` in public interface (error E0446)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |         pub fn f(arg: Priv) {} //~ ERROR private type `aliases_pub::Priv` in public interface
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] error[E0446]: private type `aliases_pub::Priv` in public interface
[00:59:30]    |
[00:59:30] LL |     struct Priv;
[00:59:30] LL |     struct Priv;
[00:59:30]    |     - `aliases_pub::Priv` declared as private
[00:59:30] ...
[00:59:30] LL |         type Check = Priv; //~ ERROR private type `aliases_pub::Priv` in public interface
[00:59:30] 
[00:59:30] 
[00:59:30] error[E0446]: private type `aliases_pub::Priv` in public interface
[00:59:30]    |
[00:59:30] LL |     struct Priv;
[00:59:30] LL |     struct Priv;
[00:59:30]    |     - `aliases_pub::Priv` declared as private
[00:59:30] ...
[00:59:30] LL |         type Check = Priv; //~ ERROR private type `aliases_pub::Priv` in public interface
[00:59:30] 
[00:59:30] 
[00:59:30] error[E0446]: private type `aliases_pub::Priv` in public interface
[00:59:30]    |
[00:59:30] LL |     struct Priv;
[00:59:30] LL |     struct Priv;
[00:59:30]    |     - `aliases_pub::Priv` declared as private
[00:59:30] ...
[00:59:30] LL |         type Check = Priv; //~ ERROR private type `aliases_pub::Priv` in public interface
[00:59:30] 
[00:59:30] 
[00:59:30] error[E0446]: private type `aliases_pub::Priv` in public interface
[00:59:30]    |
[00:59:30] LL |     struct Priv;
[00:59:30] LL |     struct Priv;
[00:59:30]    |     - `aliases_pub::Priv` declared as private
[00:59:30] ...
[00:59:30] LL |         type Check = Priv; //~ ERROR private type `aliases_pub::Priv` in public interface
[00:59:30] 
[00:59:30] 
[00:59:30] error: private trait `aliases_priv::PrivTr1` in public interface (error E0445)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |     pub trait Tr1: PrivUseAliasTr {}
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] error: private trait `aliases_priv::PrivTr1<aliases_priv::Priv2>` in public interface (error E0445)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |     pub trait Tr2: PrivUseAliasTr<PrivAlias> {}
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] error: private type `aliases_priv::Priv2` in public interface (error E0446)
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |     pub trait Tr2: PrivUseAliasTr<PrivAlias> {}
[00:59:30]    |
[00:59:30]    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
[00:59:30]    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
[00:59:30] 
[00:59:30] 
[00:59:30] warning: bounds on generic parameters are not enforced in type aliases
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |     pub type Alias<T: PrivTr> = T; //~ ERROR private trait `traits::PrivTr` in public interface
[00:59:30]    |
[00:59:30]    = note: #[warn(type_alias_bounds)] on by default
[00:59:30]    = help: the bound will not be checked when the type alias is used, and should be removed
[00:59:30] 
[00:59:30] 
[00:59:30] warning: where clauses are not enforced in type aliases
[00:59:30]   --> /checkout/src/test/ui/privacy/private-in-public-warn.rs:75:29
[00:59:30]    |
[00:59:30] LL |     pub type Alias<T> where T: PrivTr = T;
[00:59:30]    |
[00:59:30]    = help: the clause will not be checked when the type alias is used, and should be removed
[00:59:30] 
[00:59:30] error: aborting due to 37 previous errors
---
[00:59:30] 6 
[00:59:30] 7 error[E0109]: type arguments are not allowed for this type
[00:59:30] +   --> $DIR/collections.rs:17:71
[00:59:30] +    |
[00:59:30] + LL |         <<Self as Collection<T>>::Family as CollectionFamily>::Member<U>;
[00:59:30] +    |                                                                       ^ type argument not allowed
[00:59:30] + error[E0109]: type arguments are not allowed for this type
[00:59:30] 8   --> $DIR/collections.rs:56:90
[00:59:30] 9    |
[00:59:30] 9    |
[00:59:30] 10 LL | fn floatify<C>(ints: &C) -> <<C as Collection<i32>>::Family as CollectionFamily>::Member<f32>
[00:59:30] 15    |
[00:59:30] 15    |
[00:59:30] 16 LL | fn floatify_sibling<C>(ints: &C) -> <C as Collection<i32>>::Sibling<f32>
[00:59:30] - 
[00:59:30] - error[E0109]: type arguments are not allowed for this type
[00:59:30] -   --> $DIR/collections.rs:17:71
[00:59:30] -    |
[00:59:30] -    |
[00:59:30] - LL |         <<Self as Collection<T>>::Family as CollectionFamily>::Member<U>;
[00:59:30] -    |                                                                       ^ type argument not allowed
[00:59:30] 25 error[E0109]: lifetime arguments are not allowed for this type
[00:59:30] 26   --> $DIR/collections.rs:24:50
[00:59:30] 
[00:59:30] 
[00:59:30] 
[00:59:30] The actual stderr differed from the expected stderr.
[00:59:30] Actual stderr saved to /checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/rfc1598-generic-associated-types/collections/collections.stderr
[00:59:30] To update references, rerun the tests and pass the `--bless` flag
[00:59:30] To only update this specific test, also pass `--test-args rfc1598-generic-associated-types/collections.rs`
[00:59:30] error: 1 errors occurred comparing output.
[00:59:30] status: exit code: 1
[00:59:30] status: exit code: 1
[00:59:30] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/ui/rfc1598-generic-associated-types/collections.rs" "-Zthreads=1" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/rfc1598-generic-associated-types/collections" "-Crpath" "-O" "-Cdebuginfo=0" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/rfc1598-generic-associated-types/collections/auxiliary" "-A" "unused"
[00:59:30] ------------------------------------------
[00:59:30] 
[00:59:30] ------------------------------------------
[00:59:30] stderr:
---
[00:59:30] 
[00:59:30] error[E0109]: type arguments are not allowed for this type
[00:59:30]   --> /checkout/src/test/ui/rfc1598-generic-associated-types/collections.rs:17:71
[00:59:30]    |
[00:59:30] LL |         <<Self as Collection<T>>::Family as CollectionFamily>::Member<U>;
[00:59:30]    |                                                                       ^ type argument not allowed
[00:59:30] error[E0109]: type arguments are not allowed for this type
[00:59:30]   --> /checkout/src/test/ui/rfc1598-generic-associated-types/collections.rs:56:90
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL | fn floatify<C>(ints: &C) -> <<C as Collection<i32>>::Family as CollectionFamily>::Member<f32>
[00:59:30] 
[00:59:30] error[E0109]: type arguments are not allowed for this type
[00:59:30]   --> /checkout/src/test/ui/rfc1598-generic-associated-types/collections.rs:68:69
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL | fn floatify_sibling<C>(ints: &C) -> <C as Collection<i32>>::Sibling<f32>
[00:59:30] 
[00:59:30] error[E0109]: lifetime arguments are not allowed for this type
[00:59:30]   --> /checkout/src/test/ui/rfc1598-generic-associated-types/collections.rs:24:50
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |     fn iterate<'iter>(&'iter self) -> Self::Iter<'iter>;
[00:59:30] 
[00:59:30] error[E0109]: lifetime arguments are not allowed for this type
[00:59:30]   --> /checkout/src/test/ui/rfc1598-generic-associated-types/collections.rs:50:50
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |     fn iterate<'iter>(&'iter self) -> Self::Iter<'iter> {
[00:59:30] 
[00:59:30] error: aborting due to 5 previous errors
[00:59:30] 
[00:59:30] For more information about this error, try `rustc --explain E0109`.
[00:59:30] For more information about this error, try `rustc --explain E0109`.
[00:59:30] 
[00:59:30] ------------------------------------------
[00:59:30] 
[00:59:30] 
[00:59:30] ---- [ui] ui/wf/wf-trait-associated-type-region.rs stdout ----
[00:59:30] diff of stderr:
[00:59:30] 
[00:59:30] 1 error[E0309]: the associated type `<Self as SomeTrait<'a>>::Type1` may not live long enough
[00:59:30] +   --> $DIR/wf-trait-associated-type-region.rs:7:1
[00:59:30] +    |
[00:59:30] + LL | / trait SomeTrait<'a> {
[00:59:30] + LL | |     type Type1;
[00:59:30] + LL | |     type Type2 = &'a Self::Type1;
[00:59:30] + LL | |
[00:59:30] + LL | | }
[00:59:30] +    |
[00:59:30] +    |
[00:59:30] +    = help: consider adding an explicit lifetime bound `<Self as SomeTrait<'a>>::Type1: 'a`...
[00:59:30] + note: ...so that the reference type `&'a <Self as SomeTrait<'a>>::Type1` does not outlive the data it points at
[00:59:30] +   --> $DIR/wf-trait-associated-type-region.rs:7:1
[00:59:30] +    |
[00:59:30] + LL | / trait SomeTrait<'a> {
[00:59:30] + LL | |     type Type1;
[00:59:30] + LL | |     type Type2 = &'a Self::Type1;
[00:59:30] + LL | |
[00:59:30] + LL | | }
[00:59:30] + 
[00:59:30] + 
[00:59:30] + error[E0309]: the associated type `<Self as SomeTrait<'a>>::Type1` may not live long enough
[00:59:30] 2   --> $DIR/wf-trait-associated-type-region.rs:9:5
[00:59:30] 4 LL |     type Type2 = &'a Self::Type1;
[00:59:30] 
[00:59:30] 11 LL |     type Type2 = &'a Self::Type1;
[00:59:30] 12    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
---
[00:59:30] 17 
[00:59:30] 
[00:59:30] 
[00:59:30] The actual stderr differed from the expected stderr.
[00:59:30] Actual stderr saved to /checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/wf/wf-trait-associated-type-region/wf-trait-associated-type-region.stderr
[00:59:30] To update references, rerun the tests and pass the `--bless` flag
[00:59:30] To only update this specific test, also pass `--test-args wf/wf-trait-associated-type-region.rs`
[00:59:30] error: 1 errors occurred comparing output.
[00:59:30] status: exit code: 1
[00:59:30] status: exit code: 1
[00:59:30] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/ui/wf/wf-trait-associated-type-region.rs" "-Zthreads=1" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/wf/wf-trait-associated-type-region" "-Crpath" "-O" "-Cdebuginfo=0" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/wf/wf-trait-associated-type-region/auxiliary" "-A" "unused"
[00:59:30] ------------------------------------------
[00:59:30] 
[00:59:30] ------------------------------------------
[00:59:30] stderr:
[00:59:30] stderr:
[00:59:30] ------------------------------------------
[00:59:30] error[E0309]: the associated type `<Self as SomeTrait<'a>>::Type1` may not live long enough
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL | / trait SomeTrait<'a> {
[00:59:30] LL | |     type Type1;
[00:59:30] LL | |     type Type2 = &'a Self::Type1;
[00:59:30] LL | |     //~^ ERROR E0309
[00:59:30]    | |_^
[00:59:30]    |
[00:59:30]    |
[00:59:30]    = help: consider adding an explicit lifetime bound `<Self as SomeTrait<'a>>::Type1: 'a`...
[00:59:30] note: ...so that the reference type `&'a <Self as SomeTrait<'a>>::Type1` does not outlive the data it points at
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL | / trait SomeTrait<'a> {
[00:59:30] LL | |     type Type1;
[00:59:30] LL | |     type Type2 = &'a Self::Type1;
[00:59:30] LL | |     //~^ ERROR E0309
[00:59:30]    | |_^
[00:59:30] 
[00:59:30] 
[00:59:30] error[E0309]: the associated type `<Self as SomeTrait<'a>>::Type1` may not live long enough
[00:59:30]    |
[00:59:30] LL |     type Type2 = &'a Self::Type1;
[00:59:30]    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[00:59:30]    |
[00:59:30]    |
[00:59:30]    = help: consider adding an explicit lifetime bound `<Self as SomeTrait<'a>>::Type1: 'a`...
[00:59:30] note: ...so that the reference type `&'a <Self as SomeTrait<'a>>::Type1` does not outlive the data it points at
[00:59:30]    |
[00:59:30] LL |     type Type2 = &'a Self::Type1;
[00:59:30]    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[00:59:30] 
---
[00:59:30] 
[00:59:30] ---- [ui] ui/wf/wf-trait-associated-type-trait.rs stdout ----
[00:59:30] diff of stderr:
[00:59:30] 
[00:59:30] 1 error[E0277]: the trait bound `<Self as SomeTrait>::Type1: std::marker::Copy` is not satisfied
[00:59:30] +   --> $DIR/wf-trait-associated-type-trait.rs:9:1
[00:59:30] +    |
[00:59:30] + LL | / trait SomeTrait {
[00:59:30] + LL | |     type Type1;
[00:59:30] + LL | |     type Type2 = IsCopy<Self::Type1>;
[00:59:30] + LL | |
[00:59:30] + LL | | }
[00:59:30] +    | |_^ the trait `std::marker::Copy` is not implemented for `<Self as SomeTrait>::Type1`
[00:59:30] +    |
[00:59:30] +    = help: consider adding a `where <Self as SomeTrait>::Type1: std::marker::Copy` bound
[00:59:30] + note: required by `IsCopy`
[00:59:30] +   --> $DIR/wf-trait-associated-type-trait.rs:7:1
[00:59:30] +    |
[00:59:30] + LL | struct IsCopy<T:Copy> { x: T }
[00:59:30] + 
[00:59:30] + 
[00:59:30] + error[E0277]: the trait bound `<Self as SomeTrait>::Type1: std::marker::Copy` is not satisfied
[00:59:30] 2   --> $DIR/wf-trait-associated-type-trait.rs:11:5
[00:59:30] 3    |
[00:59:30] 4 LL |     type Type2 = IsCopy<Self::Type1>;
[00:59:30] 
[00:59:30] 11 LL | struct IsCopy<T:Copy> { x: T }
[00:59:30] 13 
[00:59:30] - error: aborting due to previous error
[00:59:30] + error: aborting due to 2 previous errors
[00:59:30] 15 
[00:59:30] 15 
[00:59:30] 16 For more information about this error, try `rustc --explain E0277`.
[00:59:30] 17 
[00:59:30] 
[00:59:30] 
[00:59:30] The actual stderr differed from the expected stderr.
[00:59:30] Actual stderr saved to /checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/wf/wf-trait-associated-type-trait/wf-trait-associated-type-trait.stderr
[00:59:30] To update references, rerun the tests and pass the `--bless` flag
[00:59:30] To only update this specific test, also pass `--test-args wf/wf-trait-associated-type-trait.rs`
[00:59:30] error: 1 errors occurred comparing output.
[00:59:30] status: exit code: 1
[00:59:30] status: exit code: 1
[00:59:30] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/ui/wf/wf-trait-associated-type-trait.rs" "-Zthreads=1" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/wf/wf-trait-associated-type-trait" "-Crpath" "-O" "-Cdebuginfo=0" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/wf/wf-trait-associated-type-trait/auxiliary" "-A" "unused"
[00:59:30] ------------------------------------------
[00:59:30] 
[00:59:30] ------------------------------------------
[00:59:30] stderr:
[00:59:30] stderr:
[00:59:30] ------------------------------------------
[00:59:30] error[E0277]: the trait bound `<Self as SomeTrait>::Type1: std::marker::Copy` is not satisfied
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL | / trait SomeTrait {
[00:59:30] LL | |     type Type1;
[00:59:30] LL | |     type Type2 = IsCopy<Self::Type1>;
[00:59:30] LL | |     //~^ ERROR E0277
[00:59:30] LL | | }
[00:59:30]    | |_^ the trait `std::marker::Copy` is not implemented for `<Self as SomeTrait>::Type1`
[00:59:30]    |
[00:59:30]    = help: consider adding a `where <Self as SomeTrait>::Type1: std::marker::Copy` bound
[00:59:30] note: required by `IsCopy`
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL | struct IsCopy<T:Copy> { x: T }
[00:59:30] 
[00:59:30] 
[00:59:30] error[E0277]: the trait bound `<Self as SomeTrait>::Type1: std::marker::Copy` is not satisfied
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL |     type Type2 = IsCopy<Self::Type1>;
[00:59:30]    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `<Self as SomeTrait>::Type1`
[00:59:30]    |
[00:59:30]    = help: consider adding a `where <Self as SomeTrait>::Type1: std::marker::Copy` bound
[00:59:30] note: required by `IsCopy`
[00:59:30]    |
[00:59:30]    |
[00:59:30] LL | struct IsCopy<T:Copy> { x: T }
[00:59:30] 
[00:59:30] error: aborting due to 2 previous errors
[00:59:30] 
[00:59:30] For more information about this error, try `rustc --explain E0277`.
---
[00:59:30] thread 'main' panicked at 'Some tests failed', src/tools/compiletest/src/main.rs:521:22
[00:59:30] note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
[00:59:30] 
[00:59:30] 
[00:59:30] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/compiletest" "--compile-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib" "--run-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" "--rustc-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "--src-base" "/checkout/src/test/ui" "--build-base" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui" "--stage-id" "stage2-x86_64-unknown-linux-gnu" "--mode" "ui" "--target" "x86_64-unknown-linux-gnu" "--host" "x86_64-unknown-linux-gnu" "--llvm-filecheck" "/usr/lib/llvm-6.0/bin/FileCheck" "--host-rustcflags" "-Crpath -O -Cdebuginfo=0 -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--target-rustcflags" "-Crpath -O -Cdebuginfo=0 -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--docck-python" "/usr/bin/python2.7" "--lldb-python" "/usr/bin/python2.7" "--gdb" "/usr/bin/gdb" "--quiet" "--llvm-version" "6.0.0\n" "--system-llvm" "--cc" "" "--cxx" "" "--cflags" "" "--llvm-components" "" "--llvm-cxxflags" "" "--adb-path" "adb" "--adb-test-dir" "/data/tmp/work" "--android-cross-path" "" "--color" "always"
[00:59:30] 
[00:59:30] 
[00:59:30] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[00:59:30] Build completed unsuccessfully in 0:55:26
---
travis_time:end:02e85650:start=1560553081547391124,finish=1560553081552883060,duration=5491936
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:05c27c1c
$ ln -s . checkout && for CORE in obj/cores/core.*; do EXE=$(echo $CORE | sed 's|obj/cores/core\.[0-9]*\.!checkout!\(.*\)|\1|;y|!|/|'); if [ -f "$EXE" ]; then printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" "$CORE"; gdb --batch -q -c "$CORE" "$EXE" -iex 'set auto-load off' -iex 'dir src/' -iex 'set sysroot .' -ex bt -ex q; echo travis_fold":"end:crashlog; fi; done || true
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:0e0d32fe
travis_time:start:0e0d32fe
$ cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
cat: ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers: No such file or directory
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:1ec51ed0
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@jonas-schievink

This comment has been minimized.

Copy link
Member Author

commented Jun 15, 2019

I'm inclined that we should enforce condition (1) rather than (2) as it is more conservative. In particular, we do not allow:

trait A {
    const B: u8;
}

trait Foo<T> {
    const BAR: u8 = T::B;
}

so it seems most consistent with associated constants to not allow (2).

Hmm, so I'm not sure if this is really the same thing, since specifying an invalid default for BAR, like 255u8 + 1, gets accepted without warning. Even an impl that doesn't change this default gets accepted silently. This is only an error when using the default value somewhere, or when the impl overrides the default... with the default:

trait Tr {
    const C: u8 = 255u8 + 1;
}

impl Tr for () {
    const C: u8 = 255u8 + 1;
}
error: attempt to add with overflow
 --> src/lib.rs:6:19
  |
6 |     const C: u8 = 255u8 + 1;
  |                   ^^^^^^^^^
  |
  = note: #[deny(const_err)] on by default

This seems pretty inconsistent.

@jonas-schievink jonas-schievink force-pushed the jonas-schievink:assoc-ty-defaults branch from 6b36b1a to 46dc447 Jun 15, 2019

@jonas-schievink jonas-schievink force-pushed the jonas-schievink:assoc-ty-defaults branch from 2fbdf83 to 1ca4a6b Jun 28, 2019

@arielb1

This comment has been minimized.

Copy link
Contributor

commented Jun 29, 2019

I'm looking at this PR.

| expected `<A2<T> as Tr>::Ty` because of return type
|
= note: expected type `<A2<T> as Tr>::Ty`
found type `u8`

This comment has been minimized.

Copy link
@estebank

estebank Jul 1, 2019

Contributor

I would love to see a more general way to expand the wording for these to help people understand how to actually return a value that conforms to the associated type. This is super confusing even for people with intermediate knowledge of the language.

@bors

This comment has been minimized.

Copy link
Contributor

commented Jul 4, 2019

☔️ The latest upstream changes (presumably #62355) made this pull request unmergeable. Please resolve the merge conflicts.

@arielb1

This comment has been minimized.

Copy link
Contributor

commented Jul 4, 2019

Sorry for the delay, was busy with some personal things. Am looking at this PR now.

// 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() {

This comment has been minimized.

Copy link
@arielb1

arielb1 Jul 4, 2019

Contributor

this is a bit subtle, I'll like to think about it a bit.

This comment has been minimized.

Copy link
@arielb1

arielb1 Jul 6, 2019

Contributor

First, this check is not necessary for soundness - the trait predicates are always checked in the implementing impl. Might be worth commenting on that.

Second, I find it hard to come with an interesting invariant this check guarantees. Might be worth thinking about that?

This comment has been minimized.

Copy link
@Centril

Centril Jul 6, 2019

Member

Might be worth commenting on that.

👍

Second, I find it hard to come with an interesting invariant this check guarantees. Might be worth thinking about that?

The options are laid out briefly in https://github.com/rust-lang/rfcs/blob/master/text/2532-associated-type-defaults.md#1-when-do-suitability-of-defaults-need-to-be-proven but the pros and cons aren't really discussed. In #61812 (comment) the rationale for a shallow substitution is discussed and @jonas-schievink makes a compelling point from a semver perspective. In any case, this check is more conservative so it is a good starting point that we can relax later if we want to.

const B: u8 = Self::A;
}

// This impl is *allowed* unless its assoc. consts are used

This comment has been minimized.

Copy link
@arielb1

arielb1 Jul 6, 2019

Contributor

add

// this matches the behavior without defaults.
@@ -1,3 +1,8 @@
// compile-pass

This comment has been minimized.

Copy link
@arielb1

arielb1 Jul 6, 2019

Contributor

ok

@@ -0,0 +1,22 @@
// compile-pass

This comment has been minimized.

Copy link
@arielb1

arielb1 Jul 6, 2019

Contributor

change the test name from defaults-cyclic-pass (to e.g. default-override-item-used-in-other-associated-type) - there is no cycle involved here

This comment has been minimized.

Copy link
@arielb1

arielb1 Jul 6, 2019

Contributor

Or defaults-in-other-trait-items-pass


// As soon as at least one is redefined, it works:
impl Tr for u8 {
type A = u8;

This comment has been minimized.

Copy link
@arielb1

arielb1 Jul 6, 2019

Contributor

is there a cpass test for this? I think an actual defaults-cyclic-pass test (that contains just this impl) would be a good idea.

fn make() -> u8 { 255 }
}

fn main() {}

This comment has been minimized.

Copy link
@arielb1

arielb1 Jul 6, 2019

Contributor

ok

@@ -0,0 +1,62 @@
//! Regression test for https://github.com/rust-lang/rust/issues/62211

This comment has been minimized.

Copy link
@arielb1

arielb1 Jul 6, 2019

Contributor

I'll note that the root cause of #62211 is the same as #33017 - wfcheck can rely on the projection predicate it is itself checking, and that still isn't fixed.

This comment has been minimized.

Copy link
@Centril

Centril Jul 6, 2019

Member

^--- should be added as a comment in the regression test. :)

@arielb1

This comment has been minimized.

Copy link
Contributor

commented Jul 6, 2019

re: shallow substitution (posting it here because I don't want this to disappear on commit diffs)

I'm still trying to figure out which guarantee it is trying to uphold. There are subtle examples like this:

#![feature(associated_type_defaults, specialization)]

trait Eq<T> {}
impl<T> Eq<T> for T {}

trait Foo { // no error here
    type Xyz : Eq<Self::Uvw> = u32;
    type Uvw = u32;
}

impl Foo for () { //~ ERROR here
    type Xyz = ();
}

fn main() {
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
9 participants
You can’t perform that action at this time.