From 8b1742ea6a8a560736a7656db1456f69c00c0704 Mon Sep 17 00:00:00 2001 From: kyren Date: Sun, 10 Mar 2019 22:18:38 -0400 Subject: [PATCH 1/2] Fix #54822 and associated faulty tests Type checking associated constants can require trait bounds, but an empty parameter environment was provided to the trait solver. Providing an appropriate parameter environment seems to fix #54822 and also make one of the cases in src/test/ui/nll/trait-associated-constant.rs that should compile successfully do so. It also (slightly) improves the error message in src/test/ui/associated-const/associated-const-generic-obligations.rs --- src/librustc_typeck/check/compare_method.rs | 2 +- .../associated-const-generic-obligations.rs | 2 +- ...ssociated-const-generic-obligations.stderr | 14 ++++++++----- .../associated-const-trait-bound.rs | 21 +++++++++++++++++++ src/test/ui/nll/trait-associated-constant.rs | 1 - .../ui/nll/trait-associated-constant.stderr | 21 +------------------ 6 files changed, 33 insertions(+), 28 deletions(-) create mode 100644 src/test/ui/associated-const/associated-const-trait-bound.rs diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 1e5f5d244e9c4..f79bf4e999d54 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -917,7 +917,7 @@ pub fn compare_const_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, debug!("compare_const_impl(impl_trait_ref={:?})", impl_trait_ref); tcx.infer_ctxt().enter(|infcx| { - let param_env = ty::ParamEnv::empty(); + let param_env = tcx.param_env(impl_c.def_id); let inh = Inherited::new(infcx, impl_c.def_id); let infcx = &inh.infcx; diff --git a/src/test/ui/associated-const/associated-const-generic-obligations.rs b/src/test/ui/associated-const/associated-const-generic-obligations.rs index e0b502edaa15e..498e315b5c83c 100644 --- a/src/test/ui/associated-const/associated-const-generic-obligations.rs +++ b/src/test/ui/associated-const/associated-const-generic-obligations.rs @@ -12,7 +12,7 @@ trait Bar: Foo { impl Bar for T { const FROM: &'static str = "foo"; - //~^ ERROR the trait bound `T: Foo` is not satisfied [E0277] + //~^ ERROR implemented const `FROM` has an incompatible type for trait [E0326] } fn main() {} diff --git a/src/test/ui/associated-const/associated-const-generic-obligations.stderr b/src/test/ui/associated-const/associated-const-generic-obligations.stderr index e4b86d84cafc9..eeee26a75671f 100644 --- a/src/test/ui/associated-const/associated-const-generic-obligations.stderr +++ b/src/test/ui/associated-const/associated-const-generic-obligations.stderr @@ -1,11 +1,15 @@ -error[E0277]: the trait bound `T: Foo` is not satisfied - --> $DIR/associated-const-generic-obligations.rs:14:5 +error[E0326]: implemented const `FROM` has an incompatible type for trait + --> $DIR/associated-const-generic-obligations.rs:14:17 | +LL | const FROM: Self::Out; + | --------- type in trait +... LL | const FROM: &'static str = "foo"; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `T` + | ^^^^^^^^^^^^ expected associated type, found reference | - = help: consider adding a `where T: Foo` bound + = note: expected type `::Out` + found type `&'static str` error: aborting due to previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0326`. diff --git a/src/test/ui/associated-const/associated-const-trait-bound.rs b/src/test/ui/associated-const/associated-const-trait-bound.rs new file mode 100644 index 0000000000000..0ce46d312afef --- /dev/null +++ b/src/test/ui/associated-const/associated-const-trait-bound.rs @@ -0,0 +1,21 @@ +// compile-pass + +trait ConstDefault { + const DEFAULT: Self; +} + +trait Foo: Sized {} + +trait FooExt: Foo { + type T: ConstDefault; +} + +trait Bar { + const T: F::T; +} + +impl Bar for () { + const T: F::T = ::DEFAULT; +} + +fn main() {} diff --git a/src/test/ui/nll/trait-associated-constant.rs b/src/test/ui/nll/trait-associated-constant.rs index 9d3e1a690f001..2ba65e10ea70f 100644 --- a/src/test/ui/nll/trait-associated-constant.rs +++ b/src/test/ui/nll/trait-associated-constant.rs @@ -26,7 +26,6 @@ struct FailStruct2 { } impl<'a: 'b, 'b> Anything<'a, 'b> for FailStruct2 { const AC: Option<&'a str> = None; - //~^ ERROR: mismatched types } fn main() {} diff --git a/src/test/ui/nll/trait-associated-constant.stderr b/src/test/ui/nll/trait-associated-constant.stderr index 78ef513f3eecb..786ca8e19e4cd 100644 --- a/src/test/ui/nll/trait-associated-constant.stderr +++ b/src/test/ui/nll/trait-associated-constant.stderr @@ -17,25 +17,6 @@ note: ...does not necessarily outlive the lifetime 'b as defined on the impl at LL | impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct1 { | ^^ -error[E0308]: mismatched types - --> $DIR/trait-associated-constant.rs:28:5 - | -LL | const AC: Option<&'a str> = None; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch - | - = note: expected type `std::option::Option<&'b str>` - found type `std::option::Option<&'a str>` -note: the lifetime 'a as defined on the impl at 27:6... - --> $DIR/trait-associated-constant.rs:27:6 - | -LL | impl<'a: 'b, 'b> Anything<'a, 'b> for FailStruct2 { - | ^^ -note: ...does not necessarily outlive the lifetime 'b as defined on the impl at 27:14 - --> $DIR/trait-associated-constant.rs:27:14 - | -LL | impl<'a: 'b, 'b> Anything<'a, 'b> for FailStruct2 { - | ^^ - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. From aa9bd68fa8134e55ded5e65abef745f96ba0e622 Mon Sep 17 00:00:00 2001 From: kyren Date: Tue, 12 Mar 2019 18:33:27 -0400 Subject: [PATCH 2/2] Rename test struct names to something more sensible --- src/test/ui/nll/trait-associated-constant.rs | 12 ++++++------ src/test/ui/nll/trait-associated-constant.stderr | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/test/ui/nll/trait-associated-constant.rs b/src/test/ui/nll/trait-associated-constant.rs index 2ba65e10ea70f..31dc58185e90a 100644 --- a/src/test/ui/nll/trait-associated-constant.rs +++ b/src/test/ui/nll/trait-associated-constant.rs @@ -9,22 +9,22 @@ trait Anything<'a: 'b, 'b> { const AC: Option<&'b str>; } -struct OKStruct { } +struct OKStruct1 { } -impl<'a: 'b, 'b> Anything<'a, 'b> for OKStruct { +impl<'a: 'b, 'b> Anything<'a, 'b> for OKStruct1 { const AC: Option<&'b str> = None; } -struct FailStruct1 { } +struct FailStruct { } -impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct1 { +impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct { const AC: Option<&'c str> = None; //~^ ERROR: mismatched types } -struct FailStruct2 { } +struct OKStruct2 { } -impl<'a: 'b, 'b> Anything<'a, 'b> for FailStruct2 { +impl<'a: 'b, 'b> Anything<'a, 'b> for OKStruct2 { const AC: Option<&'a str> = None; } diff --git a/src/test/ui/nll/trait-associated-constant.stderr b/src/test/ui/nll/trait-associated-constant.stderr index 786ca8e19e4cd..f39f668e2329a 100644 --- a/src/test/ui/nll/trait-associated-constant.stderr +++ b/src/test/ui/nll/trait-associated-constant.stderr @@ -9,12 +9,12 @@ LL | const AC: Option<&'c str> = None; note: the lifetime 'c as defined on the impl at 20:18... --> $DIR/trait-associated-constant.rs:20:18 | -LL | impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct1 { +LL | impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct { | ^^ note: ...does not necessarily outlive the lifetime 'b as defined on the impl at 20:14 --> $DIR/trait-associated-constant.rs:20:14 | -LL | impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct1 { +LL | impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct { | ^^ error: aborting due to previous error