From 479ce39939014f0071f8600fa4ce150e33cb7d5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 25 Aug 2019 21:58:59 -0700 Subject: [PATCH 01/11] Add explanation to type mismatch involving type params and assoc types --- src/librustc/traits/mod.rs | 10 +- src/librustc/traits/util.rs | 25 +++-- src/librustc/ty/error.rs | 96 ++++++++++++++++++- ...ssociated-const-generic-obligations.stderr | 2 + .../associated-types-eq-3.stderr | 2 + .../associated-types-issue-20346.stderr | 2 + ...ated-types-multiple-types-one-trait.stderr | 4 + .../reordered-type-param.stderr | 2 + src/test/ui/hrtb/issue-62203-hrtb-ice.stderr | 2 + .../bound-normalization-fail.stderr | 4 + src/test/ui/impl-trait/equality2.stderr | 2 + .../impl-generic-mismatch-ab.stderr | 2 + .../universal-mismatched-type.stderr | 2 + .../universal-two-impl-traits.stderr | 2 + src/test/ui/issues/issue-13853.stderr | 2 + src/test/ui/issues/issue-20225.stderr | 6 ++ src/test/ui/issues/issue-24204.stderr | 1 + src/test/ui/issues/issue-2951.stderr | 2 + src/test/ui/issues/issue-32323.stderr | 2 + .../ui/mismatched_types/issue-35030.stderr | 2 + .../specialization-default-projection.stderr | 4 + .../specialization-default-types.stderr | 4 + .../struct-path-self-type-mismatch.stderr | 4 + .../enum-variant-generic-args.stderr | 12 +++ src/test/ui/type/type-parameter-names.stderr | 2 + .../type-params-in-different-spaces-1.stderr | 2 + .../type-params-in-different-spaces-3.stderr | 2 + 27 files changed, 180 insertions(+), 22 deletions(-) diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index d2683090add4..7154962b5929 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -655,11 +655,11 @@ pub struct VtableTraitAliasData<'tcx, N> { } /// Creates predicate obligations from the generic bounds. -pub fn predicates_for_generics<'tcx>(cause: ObligationCause<'tcx>, - param_env: ty::ParamEnv<'tcx>, - generic_bounds: &ty::InstantiatedPredicates<'tcx>) - -> PredicateObligations<'tcx> -{ +pub fn predicates_for_generics<'tcx>( + cause: ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, + generic_bounds: &ty::InstantiatedPredicates<'tcx>, +) -> PredicateObligations<'tcx> { util::predicates_for_generics(cause, 0, param_env, generic_bounds) } diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index 3d36790c94b8..3e5520dd4655 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -513,20 +513,19 @@ pub fn impl_trait_ref_and_oblig<'a, 'tcx>( } /// See [`super::obligations_for_generics`]. -pub fn predicates_for_generics<'tcx>(cause: ObligationCause<'tcx>, - recursion_depth: usize, - param_env: ty::ParamEnv<'tcx>, - generic_bounds: &ty::InstantiatedPredicates<'tcx>) - -> Vec> -{ - debug!("predicates_for_generics(generic_bounds={:?})", - generic_bounds); +pub fn predicates_for_generics<'tcx>( + cause: ObligationCause<'tcx>, + recursion_depth: usize, + param_env: ty::ParamEnv<'tcx>, + generic_bounds: &ty::InstantiatedPredicates<'tcx>, +) -> Vec> { + debug!("predicates_for_generics(generic_bounds={:?})", generic_bounds); - generic_bounds.predicates.iter().map(|predicate| { - Obligation { cause: cause.clone(), - recursion_depth, - param_env, - predicate: predicate.clone() } + generic_bounds.predicates.iter().map(|predicate| Obligation { + cause: cause.clone(), + recursion_depth, + param_env, + predicate: predicate.clone(), }).collect() } diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 62910ec32049..993d627d6e17 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -275,10 +275,10 @@ impl<'tcx> TyCtxt<'tcx> { `.await`ing on both of them"); } } - if let (ty::Infer(ty::IntVar(_)), ty::Float(_)) = - (&values.found.sty, &values.expected.sty) // Issue #53280 - { - if let Ok(snippet) = self.sess.source_map().span_to_snippet(sp) { + match (&values.expected.sty, &values.found.sty) { + (ty::Float(_), ty::Infer(ty::IntVar(_))) => if let Ok( // Issue #53280 + snippet, + ) = self.sess.source_map().span_to_snippet(sp) { if snippet.chars().all(|c| c.is_digit(10) || c == '-' || c == '_') { db.span_suggestion( sp, @@ -287,8 +287,96 @@ impl<'tcx> TyCtxt<'tcx> { Applicability::MachineApplicable ); } + }, + (ty::Param(_), ty::Param(_)) => { + db.note("a type parameter was expected, but a different one was found; \ + you might be missing a type parameter or trait bound"); + db.note("for more information, visit \ + https://doc.rust-lang.org/book/ch10-02-traits.html\ + #traits-as-parameters"); } + (ty::Projection(_), ty::Projection(_)) => { + db.note("an associated type was expected, but a different one was found"); + } + (ty::Param(_), ty::Projection(_)) | (ty::Projection(_), ty::Param(_)) => { + db.note("you might be missing a type parameter or trait bound"); + } + (ty::Param(_), _) | (_, ty::Param(_)) => { + db.help("type parameters must be constrained to match other types"); + if self.sess.teach(&db.get_code().unwrap()) { + db.help("given a type parameter `T` and a method `foo`: +``` +trait Trait { fn foo(&self) -> T; } +``` +the only ways to implement method `foo` are: +- constrain `T` with an explicit type: +``` +impl Trait for X { + fn foo(&self) -> String { String::new() } +} +``` +- add a trait bound to `T` and call a method on that trait that returns `Self`: +``` +impl Trait for X { + fn foo(&self) -> T { ::default() } +} +``` +- change `foo` to return an argument of type `T`: +``` +impl Trait for X { + fn foo(&self, x: T) -> T { x } +} +```"); + } + db.note("for more information, visit \ + https://doc.rust-lang.org/book/ch10-02-traits.html\ + #traits-as-parameters"); + } + (ty::Projection(_), _) => { + db.note(&format!( + "consider constraining the associated type `{}` to `{}` or calling a \ + method that returns `{}`", + values.expected, + values.found, + values.expected, + )); + if self.sess.teach(&db.get_code().unwrap()) { + db.help("given an associated type `T` and a method `foo`: +``` +trait Trait { + type T; + fn foo(&self) -> Self::T; +} +``` +the only way of implementing method `foo` is to constrain `T` with an explicit associated type: +``` +impl Trait for X { + type T = String; + fn foo(&self) -> Self::T { String::new() } +} +```"); + } + db.note("for more information, visit \ + https://doc.rust-lang.org/book/ch19-03-advanced-traits.html"); + } + (_, ty::Projection(_)) => { + db.note(&format!( + "consider constraining the associated type `{}` to `{}`", + values.found, + values.expected, + )); + db.note("for more information, visit \ + https://doc.rust-lang.org/book/ch19-03-advanced-traits.html"); + } + _ => {} } + debug!( + "note_and_explain_type_err expected={:?} ({:?}) found={:?} ({:?})", + values.expected, + values.expected.sty, + values.found, + values.found.sty, + ); }, CyclicTy(ty) => { // Watch out for various cases of cyclic types and try to explain. 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 eeee26a75671..ca6118cb3ba9 100644 --- a/src/test/ui/associated-const/associated-const-generic-obligations.stderr +++ b/src/test/ui/associated-const/associated-const-generic-obligations.stderr @@ -9,6 +9,8 @@ LL | const FROM: &'static str = "foo"; | = note: expected type `::Out` found type `&'static str` + = note: consider constraining the associated type `::Out` to `&'static str` or calling a method that returns `::Out` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error: aborting due to previous error diff --git a/src/test/ui/associated-types/associated-types-eq-3.stderr b/src/test/ui/associated-types/associated-types-eq-3.stderr index 0f8c5257d445..c9d88b7af075 100644 --- a/src/test/ui/associated-types/associated-types-eq-3.stderr +++ b/src/test/ui/associated-types/associated-types-eq-3.stderr @@ -6,6 +6,8 @@ LL | let _: Bar = x.boo(); | = note: expected type `Bar` found type `::A` + = note: consider constraining the associated type `::A` to `Bar` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error[E0271]: type mismatch resolving `::A == Bar` --> $DIR/associated-types-eq-3.rs:38:5 diff --git a/src/test/ui/associated-types/associated-types-issue-20346.stderr b/src/test/ui/associated-types/associated-types-issue-20346.stderr index 7d6c025d69d5..e037bd851ca2 100644 --- a/src/test/ui/associated-types/associated-types-issue-20346.stderr +++ b/src/test/ui/associated-types/associated-types-issue-20346.stderr @@ -9,6 +9,8 @@ LL | is_iterator_of::, _>(&adapter); | = note: expected type `T` found type `std::option::Option` + = help: type parameters must be constrained to match other types + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error: aborting due to previous error diff --git a/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr b/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr index 4a2a6d03c607..d6328a64c7c7 100644 --- a/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr +++ b/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr @@ -9,6 +9,8 @@ LL | fn want_y>(t: &T) { } | = note: expected type `::Y` found type `i32` + = note: consider constraining the associated type `::Y` to `i32` or calling a method that returns `::Y` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error[E0271]: type mismatch resolving `::X == u32` --> $DIR/associated-types-multiple-types-one-trait.rs:18:5 @@ -21,6 +23,8 @@ LL | fn want_x>(t: &T) { } | = note: expected type `::X` found type `u32` + = note: consider constraining the associated type `::X` to `u32` or calling a method that returns `::X` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error: aborting due to 2 previous errors diff --git a/src/test/ui/compare-method/reordered-type-param.stderr b/src/test/ui/compare-method/reordered-type-param.stderr index a33908c01c84..8176e96d6de1 100644 --- a/src/test/ui/compare-method/reordered-type-param.stderr +++ b/src/test/ui/compare-method/reordered-type-param.stderr @@ -9,6 +9,8 @@ LL | fn b(&self, _x: G) -> G { panic!() } | = note: expected type `fn(&E, F) -> F` found type `fn(&E, G) -> G` + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error: aborting due to previous error diff --git a/src/test/ui/hrtb/issue-62203-hrtb-ice.stderr b/src/test/ui/hrtb/issue-62203-hrtb-ice.stderr index c2d0e0c2a26b..fd6fce938b2c 100644 --- a/src/test/ui/hrtb/issue-62203-hrtb-ice.stderr +++ b/src/test/ui/hrtb/issue-62203-hrtb-ice.stderr @@ -6,6 +6,8 @@ LL | let v = Unit2.m( | = note: expected type `Unit4` found type `<_ as Ty<'_>>::V` + = note: consider constraining the associated type `<_ as Ty<'_>>::V` to `Unit4` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error[E0271]: type mismatch resolving `<[closure@$DIR/issue-62203-hrtb-ice.rs:42:17: 42:39] as std::ops::FnOnce<((&u8,),)>>::Output == Unit3` --> $DIR/issue-62203-hrtb-ice.rs:38:19 diff --git a/src/test/ui/impl-trait/bound-normalization-fail.stderr b/src/test/ui/impl-trait/bound-normalization-fail.stderr index 2c4c61a0957f..99c6a8cdd6da 100644 --- a/src/test/ui/impl-trait/bound-normalization-fail.stderr +++ b/src/test/ui/impl-trait/bound-normalization-fail.stderr @@ -14,6 +14,8 @@ LL | fn foo_fail() -> impl FooLike { | = note: expected type `()` found type `::Assoc` + = note: consider constraining the associated type `::Assoc` to `()` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html = note: the return type of a function must have a statically known size error: `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope @@ -30,6 +32,8 @@ LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike { | = note: expected type `()` found type `>::Assoc` + = note: consider constraining the associated type `>::Assoc` to `()` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html = note: the return type of a function must have a statically known size error: aborting due to 3 previous errors diff --git a/src/test/ui/impl-trait/equality2.stderr b/src/test/ui/impl-trait/equality2.stderr index 3e6181adec02..e30e2626e9f3 100644 --- a/src/test/ui/impl-trait/equality2.stderr +++ b/src/test/ui/impl-trait/equality2.stderr @@ -15,6 +15,8 @@ LL | let _: i32 = Leak::leak(hide(0_i32)); | = note: expected type `i32` found type `::T` + = note: consider constraining the associated type `::T` to `i32` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error[E0308]: mismatched types --> $DIR/equality2.rs:38:10 diff --git a/src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr b/src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr index 357e6b026e2a..e4d0a731ebfe 100644 --- a/src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr +++ b/src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr @@ -9,6 +9,8 @@ LL | fn foo(&self, a: &impl Debug, b: &B) { } | = note: expected type `fn(&(), &B, &impl Debug)` found type `fn(&(), &impl Debug, &B)` + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error: aborting due to previous error diff --git a/src/test/ui/impl-trait/universal-mismatched-type.stderr b/src/test/ui/impl-trait/universal-mismatched-type.stderr index d223b9672cfd..d92c3f034e5a 100644 --- a/src/test/ui/impl-trait/universal-mismatched-type.stderr +++ b/src/test/ui/impl-trait/universal-mismatched-type.stderr @@ -8,6 +8,8 @@ LL | x | = note: expected type `std::string::String` found type `impl Debug` + = help: type parameters must be constrained to match other types + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error: aborting due to previous error diff --git a/src/test/ui/impl-trait/universal-two-impl-traits.stderr b/src/test/ui/impl-trait/universal-two-impl-traits.stderr index 145d6a8431bf..98a70f268cf7 100644 --- a/src/test/ui/impl-trait/universal-two-impl-traits.stderr +++ b/src/test/ui/impl-trait/universal-two-impl-traits.stderr @@ -6,6 +6,8 @@ LL | a = y; | = note: expected type `impl Debug` (type parameter) found type `impl Debug` (type parameter) + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error: aborting due to previous error diff --git a/src/test/ui/issues/issue-13853.stderr b/src/test/ui/issues/issue-13853.stderr index c57ca3e25d99..3f2d0aa87adc 100644 --- a/src/test/ui/issues/issue-13853.stderr +++ b/src/test/ui/issues/issue-13853.stderr @@ -9,6 +9,8 @@ LL | self.iter() | = note: expected type `I` found type `std::slice::Iter<'_, N>` + = help: type parameters must be constrained to match other types + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error[E0599]: no method named `iter` found for type `&G` in the current scope --> $DIR/issue-13853.rs:27:23 diff --git a/src/test/ui/issues/issue-20225.stderr b/src/test/ui/issues/issue-20225.stderr index 5ab23cb55bcc..4c464e6d4f68 100644 --- a/src/test/ui/issues/issue-20225.stderr +++ b/src/test/ui/issues/issue-20225.stderr @@ -6,6 +6,8 @@ LL | extern "rust-call" fn call(&self, (_,): (T,)) {} | = note: expected type `extern "rust-call" fn(&Foo, (&'a T,))` found type `extern "rust-call" fn(&Foo, (T,))` + = help: type parameters must be constrained to match other types + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error[E0053]: method `call_mut` has an incompatible type for trait --> $DIR/issue-20225.rs:12:3 @@ -15,6 +17,8 @@ LL | extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {} | = note: expected type `extern "rust-call" fn(&mut Foo, (&'a T,))` found type `extern "rust-call" fn(&mut Foo, (T,))` + = help: type parameters must be constrained to match other types + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error[E0053]: method `call_once` has an incompatible type for trait --> $DIR/issue-20225.rs:20:3 @@ -24,6 +28,8 @@ LL | extern "rust-call" fn call_once(self, (_,): (T,)) {} | = note: expected type `extern "rust-call" fn(Foo, (&'a T,))` found type `extern "rust-call" fn(Foo, (T,))` + = help: type parameters must be constrained to match other types + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error: aborting due to 3 previous errors diff --git a/src/test/ui/issues/issue-24204.stderr b/src/test/ui/issues/issue-24204.stderr index eb9aada389f8..9658f6980be2 100644 --- a/src/test/ui/issues/issue-24204.stderr +++ b/src/test/ui/issues/issue-24204.stderr @@ -9,6 +9,7 @@ LL | fn test>(b: i32) -> T where T::A: MultiDispatch { T::n | = note: expected type `<::A as MultiDispatch>::O` found type `T` + = note: you might be missing a type parameter or trait bound error: aborting due to previous error diff --git a/src/test/ui/issues/issue-2951.stderr b/src/test/ui/issues/issue-2951.stderr index 58e28c1a9dc8..a6ccc4835fa6 100644 --- a/src/test/ui/issues/issue-2951.stderr +++ b/src/test/ui/issues/issue-2951.stderr @@ -6,6 +6,8 @@ LL | xx = y; | = note: expected type `T` found type `U` + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error: aborting due to previous error diff --git a/src/test/ui/issues/issue-32323.stderr b/src/test/ui/issues/issue-32323.stderr index 6256dc0c5502..9c11a02923c8 100644 --- a/src/test/ui/issues/issue-32323.stderr +++ b/src/test/ui/issues/issue-32323.stderr @@ -8,6 +8,8 @@ LL | pub fn f<'a, T: Tr<'a>>() -> >::Out {} | = note: expected type `>::Out` found type `()` + = note: consider constraining the associated type `>::Out` to `()` or calling a method that returns `>::Out` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error: aborting due to previous error diff --git a/src/test/ui/mismatched_types/issue-35030.stderr b/src/test/ui/mismatched_types/issue-35030.stderr index f03067016134..4a9afb9d2494 100644 --- a/src/test/ui/mismatched_types/issue-35030.stderr +++ b/src/test/ui/mismatched_types/issue-35030.stderr @@ -6,6 +6,8 @@ LL | Some(true) | = note: expected type `bool` (type parameter) found type `bool` (bool) + = help: type parameters must be constrained to match other types + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error: aborting due to previous error diff --git a/src/test/ui/specialization/specialization-default-projection.stderr b/src/test/ui/specialization/specialization-default-projection.stderr index ab0bdc44cff1..43cebd7f9c24 100644 --- a/src/test/ui/specialization/specialization-default-projection.stderr +++ b/src/test/ui/specialization/specialization-default-projection.stderr @@ -9,6 +9,8 @@ LL | () | = note: expected type `::Assoc` found type `()` + = note: consider constraining the associated type `::Assoc` to `()` or calling a method that returns `::Assoc` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error[E0308]: mismatched types --> $DIR/specialization-default-projection.rs:28:5 @@ -23,6 +25,8 @@ LL | generic::<()>() | = note: expected type `()` found type `<() as Foo>::Assoc` + = note: consider constraining the associated type `<() as Foo>::Assoc` to `()` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error: aborting due to 2 previous errors diff --git a/src/test/ui/specialization/specialization-default-types.stderr b/src/test/ui/specialization/specialization-default-types.stderr index 1192b0e5cfa5..932087421fbc 100644 --- a/src/test/ui/specialization/specialization-default-types.stderr +++ b/src/test/ui/specialization/specialization-default-types.stderr @@ -8,6 +8,8 @@ LL | Box::new(self) | = note: expected type `::Output` found type `std::boxed::Box` + = note: consider constraining the associated type `::Output` to `std::boxed::Box` or calling a method that returns `::Output` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error[E0308]: mismatched types --> $DIR/specialization-default-types.rs:25:5 @@ -19,6 +21,8 @@ LL | Example::generate(t) | = note: expected type `std::boxed::Box` found type `::Output` + = note: consider constraining the associated type `::Output` to `std::boxed::Box` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error: aborting due to 2 previous errors diff --git a/src/test/ui/structs/struct-path-self-type-mismatch.stderr b/src/test/ui/structs/struct-path-self-type-mismatch.stderr index 72c6d7ae22b4..b905cd1a294c 100644 --- a/src/test/ui/structs/struct-path-self-type-mismatch.stderr +++ b/src/test/ui/structs/struct-path-self-type-mismatch.stderr @@ -12,6 +12,8 @@ LL | inner: u | = note: expected type `T` found type `U` + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error[E0308]: mismatched types --> $DIR/struct-path-self-type-mismatch.rs:13:9 @@ -27,6 +29,8 @@ LL | | } | = note: expected type `Foo` found type `Foo` + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error: aborting due to 3 previous errors diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr index ee73622cb7bd..a0a617fdbbc3 100644 --- a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr +++ b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr @@ -6,6 +6,8 @@ LL | Self::TSVariant(()); | = note: expected type `T` found type `()` + = help: type parameters must be constrained to match other types + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error[E0109]: type arguments are not allowed for this type --> $DIR/enum-variant-generic-args.rs:15:27 @@ -27,6 +29,8 @@ LL | Self::<()>::TSVariant(()); | = note: expected type `T` found type `()` + = help: type parameters must be constrained to match other types + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error[E0109]: type arguments are not allowed for this type --> $DIR/enum-variant-generic-args.rs:20:16 @@ -48,6 +52,8 @@ LL | Self::SVariant { v: () }; | = note: expected type `T` found type `()` + = help: type parameters must be constrained to match other types + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error[E0109]: type arguments are not allowed for this type --> $DIR/enum-variant-generic-args.rs:28:26 @@ -63,6 +69,8 @@ LL | Self::SVariant::<()> { v: () }; | = note: expected type `T` found type `()` + = help: type parameters must be constrained to match other types + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error[E0109]: type arguments are not allowed for this type --> $DIR/enum-variant-generic-args.rs:31:16 @@ -78,6 +86,8 @@ LL | Self::<()>::SVariant { v: () }; | = note: expected type `T` found type `()` + = help: type parameters must be constrained to match other types + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error[E0109]: type arguments are not allowed for this type --> $DIR/enum-variant-generic-args.rs:34:16 @@ -99,6 +109,8 @@ LL | Self::<()>::SVariant::<()> { v: () }; | = note: expected type `T` found type `()` + = help: type parameters must be constrained to match other types + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error[E0109]: type arguments are not allowed for this type --> $DIR/enum-variant-generic-args.rs:41:26 diff --git a/src/test/ui/type/type-parameter-names.stderr b/src/test/ui/type/type-parameter-names.stderr index 9acae5c376d5..3397eec9e050 100644 --- a/src/test/ui/type/type-parameter-names.stderr +++ b/src/test/ui/type/type-parameter-names.stderr @@ -8,6 +8,8 @@ LL | x | = note: expected type `Bar` found type `Foo` + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error: aborting due to previous error diff --git a/src/test/ui/type/type-params-in-different-spaces-1.stderr b/src/test/ui/type/type-params-in-different-spaces-1.stderr index 0448a28ea8e2..a10bf4e0b778 100644 --- a/src/test/ui/type/type-params-in-different-spaces-1.stderr +++ b/src/test/ui/type/type-params-in-different-spaces-1.stderr @@ -6,6 +6,8 @@ LL | *self + rhs | = note: expected type `Self` found type `T` + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error: aborting due to previous error diff --git a/src/test/ui/type/type-params-in-different-spaces-3.stderr b/src/test/ui/type/type-params-in-different-spaces-3.stderr index e25f79947c73..9f0fa5a0ea1f 100644 --- a/src/test/ui/type/type-params-in-different-spaces-3.stderr +++ b/src/test/ui/type/type-params-in-different-spaces-3.stderr @@ -8,6 +8,8 @@ LL | u | = note: expected type `Self` found type `X` + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error: aborting due to previous error From 8112f71fc91bc7618d91bb3180fe80b8fafe1069 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 19 Sep 2019 09:24:42 -0700 Subject: [PATCH 02/11] rustbuild: Turn down compression on exe installers The Windows dist builders are the slowest builders right now, and the distribution phase of them is enormously slow clocking in at around 20 minutes to build all the related installers. This commit starts to optimize these by turning down the compression level in the `exe` installers. These aren't super heavily used so there's no great need for them to be so ultra-compressed, so let's dial back the compression parameters to get closer to the rest of our xz archives. This brings the installer in line with the gz tarball installer locally, and also brings the compression settings on par with the rest of our xz installers. --- src/etc/installer/exe/rust.iss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/etc/installer/exe/rust.iss b/src/etc/installer/exe/rust.iss index c22d60b6c5df..70648beac38b 100644 --- a/src/etc/installer/exe/rust.iss +++ b/src/etc/installer/exe/rust.iss @@ -25,9 +25,9 @@ SourceDir=.\ OutputBaseFilename={#CFG_PACKAGE_NAME}-{#CFG_BUILD} DefaultDirName={sd}\Rust -Compression=lzma2/ultra -InternalCompressLevel=ultra -SolidCompression=true +Compression=lzma2/normal +InternalCompressLevel=normal +SolidCompression=no ChangesEnvironment=true ChangesAssociations=no From fde8cfe130db3826b88247318551d34d2bb63276 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 19 Sep 2019 09:24:42 -0700 Subject: [PATCH 03/11] rustbuild: Turn down compression on msi installers This is the same as #64615 except applied to our MSI installers. The same fix is applied effectively bringing these installers in line with the gz tarball installers, which are about 3x faster to produce locally and likely much faster to produce on CI. --- src/etc/installer/msi/rust.wxs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/etc/installer/msi/rust.wxs b/src/etc/installer/msi/rust.wxs index a471ccc6f5b4..a2e378f7b1db 100644 --- a/src/etc/installer/msi/rust.wxs +++ b/src/etc/installer/msi/rust.wxs @@ -152,7 +152,7 @@ - + From 255dd3ff42aecdc36da800e5bbfe0c09e83fa066 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 19 Sep 2019 11:22:55 -0700 Subject: [PATCH 04/11] rustbuild: Improve output of `dist` step * Pass `/Q` to `iscc` on Windows to supress the thousands of lines of output about compressing documentation. * Print out what's happening before long steps * Use `timeit` to print out timing information for long-running installer assemblies. --- src/bootstrap/dist.rs | 66 ++++++++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 19 deletions(-) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 076bcd878df7..50b20763c43d 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -18,7 +18,7 @@ use build_helper::{output, t}; use crate::{Compiler, Mode, LLVM_TOOLS}; use crate::channel; -use crate::util::{is_dylib, exe}; +use crate::util::{is_dylib, exe, timeit}; use crate::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::compile; use crate::tool::{self, Tool}; @@ -91,14 +91,15 @@ impl Step for Docs { let name = pkgname(builder, "rust-docs"); - builder.info(&format!("Dist docs ({})", host)); if !builder.config.docs { - builder.info("\tskipping - docs disabled"); return distdir(builder).join(format!("{}-{}.tar.gz", name, host)); } builder.default_doc(None); + builder.info(&format!("Dist docs ({})", host)); + let _time = timeit(builder); + let image = tmpdir(builder).join(format!("{}-{}-image", name, host)); let _ = fs::remove_dir_all(&image); @@ -151,9 +152,7 @@ impl Step for RustcDocs { let name = pkgname(builder, "rustc-docs"); - builder.info(&format!("Dist compiler docs ({})", host)); if !builder.config.compiler_docs { - builder.info("\tskipping - compiler docs disabled"); return distdir(builder).join(format!("{}-{}.tar.gz", name, host)); } @@ -179,6 +178,9 @@ impl Step for RustcDocs { .arg("--component-name=rustc-docs") .arg("--legacy-manifest-dirs=rustlib,cargo") .arg("--bulk-dirs=share/doc/rust/html"); + + builder.info(&format!("Dist compiler docs ({})", host)); + let _time = timeit(builder); builder.run(&mut cmd); builder.remove_dir(&image); @@ -350,6 +352,7 @@ impl Step for Mingw { } builder.info(&format!("Dist mingw ({})", host)); + let _time = timeit(builder); let name = pkgname(builder, "rust-mingw"); let image = tmpdir(builder).join(format!("{}-{}-image", name, host)); let _ = fs::remove_dir_all(&image); @@ -403,7 +406,6 @@ impl Step for Rustc { let compiler = self.compiler; let host = self.compiler.host; - builder.info(&format!("Dist rustc stage{} ({})", compiler.stage, host)); let name = pkgname(builder, "rustc"); let image = tmpdir(builder).join(format!("{}-{}-image", name, host)); let _ = fs::remove_dir_all(&image); @@ -460,6 +462,9 @@ impl Step for Rustc { .arg(format!("--package-name={}-{}", name, host)) .arg("--component-name=rustc") .arg("--legacy-manifest-dirs=rustlib,cargo"); + + builder.info(&format!("Dist rustc stage{} ({})", compiler.stage, host)); + let _time = timeit(builder); builder.run(&mut cmd); builder.remove_dir(&image); builder.remove_dir(&overlay); @@ -662,8 +667,6 @@ impl Step for Std { let target = self.target; let name = pkgname(builder, "rust-std"); - builder.info(&format!("Dist std stage{} ({} -> {})", - compiler.stage, &compiler.host, target)); // The only true set of target libraries came from the build triple, so // let's reduce redundant work by only producing archives from that host. @@ -714,6 +717,10 @@ impl Step for Std { .arg(format!("--package-name={}-{}", name, target)) .arg(format!("--component-name=rust-std-{}", target)) .arg("--legacy-manifest-dirs=rustlib,cargo"); + + builder.info(&format!("Dist std stage{} ({} -> {})", + compiler.stage, &compiler.host, target)); + let _time = timeit(builder); builder.run(&mut cmd); builder.remove_dir(&image); distdir(builder).join(format!("{}-{}.tar.gz", name, target)) @@ -754,11 +761,9 @@ impl Step for Analysis { let compiler = self.compiler; let target = self.target; assert!(builder.config.extended); - builder.info("Dist analysis"); let name = pkgname(builder, "rust-analysis"); if &compiler.host != builder.config.build { - builder.info("\tskipping, not a build host"); return distdir(builder).join(format!("{}-{}.tar.gz", name, target)); } @@ -786,6 +791,9 @@ impl Step for Analysis { .arg(format!("--package-name={}-{}", name, target)) .arg(format!("--component-name=rust-analysis-{}", target)) .arg("--legacy-manifest-dirs=rustlib,cargo"); + + builder.info("Dist analysis"); + let _time = timeit(builder); builder.run(&mut cmd); builder.remove_dir(&image); distdir(builder).join(format!("{}-{}.tar.gz", name, target)) @@ -874,8 +882,6 @@ impl Step for Src { /// Creates the `rust-src` installer component fn run(self, builder: &Builder<'_>) -> PathBuf { - builder.info("Dist src"); - let name = pkgname(builder, "rust-src"); let image = tmpdir(builder).join(format!("{}-image", name)); let _ = fs::remove_dir_all(&image); @@ -930,6 +936,9 @@ impl Step for Src { .arg(format!("--package-name={}", name)) .arg("--component-name=rust-src") .arg("--legacy-manifest-dirs=rustlib,cargo"); + + builder.info("Dist src"); + let _time = timeit(builder); builder.run(&mut cmd); builder.remove_dir(&image); @@ -957,8 +966,6 @@ impl Step for PlainSourceTarball { /// Creates the plain source tarball fn run(self, builder: &Builder<'_>) -> PathBuf { - builder.info("Create plain source tarball"); - // Make sure that the root folder of tarball has the correct name let plain_name = format!("{}-src", pkgname(builder, "rustc")); let plain_dst_src = tmpdir(builder).join(&plain_name); @@ -1020,6 +1027,9 @@ impl Step for PlainSourceTarball { .arg("--output").arg(&tarball) .arg("--work-dir=.") .current_dir(tmpdir(builder)); + + builder.info("Create plain source tarball"); + let _time = timeit(builder); builder.run(&mut cmd); distdir(builder).join(&format!("{}.tar.gz", plain_name)) } @@ -1073,7 +1083,6 @@ impl Step for Cargo { let compiler = self.compiler; let target = self.target; - builder.info(&format!("Dist cargo stage{} ({})", compiler.stage, target)); let src = builder.src.join("src/tools/cargo"); let etc = src.join("src/etc"); let release_num = builder.release_num("cargo"); @@ -1126,6 +1135,9 @@ impl Step for Cargo { .arg(format!("--package-name={}-{}", name, target)) .arg("--component-name=cargo") .arg("--legacy-manifest-dirs=rustlib,cargo"); + + builder.info(&format!("Dist cargo stage{} ({})", compiler.stage, target)); + let _time = timeit(builder); builder.run(&mut cmd); distdir(builder).join(format!("{}-{}.tar.gz", name, target)) } @@ -1161,7 +1173,6 @@ impl Step for Rls { let target = self.target; assert!(builder.config.extended); - builder.info(&format!("Dist RLS stage{} ({})", compiler.stage, target)); let src = builder.src.join("src/tools/rls"); let release_num = builder.release_num("rls"); let name = pkgname(builder, "rls"); @@ -1210,6 +1221,8 @@ impl Step for Rls { .arg("--legacy-manifest-dirs=rustlib,cargo") .arg("--component-name=rls-preview"); + builder.info(&format!("Dist RLS stage{} ({})", compiler.stage, target)); + let _time = timeit(builder); builder.run(&mut cmd); Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target))) } @@ -1245,7 +1258,6 @@ impl Step for Clippy { let target = self.target; assert!(builder.config.extended); - builder.info(&format!("Dist clippy stage{} ({})", compiler.stage, target)); let src = builder.src.join("src/tools/clippy"); let release_num = builder.release_num("clippy"); let name = pkgname(builder, "clippy"); @@ -1299,6 +1311,8 @@ impl Step for Clippy { .arg("--legacy-manifest-dirs=rustlib,cargo") .arg("--component-name=clippy-preview"); + builder.info(&format!("Dist clippy stage{} ({})", compiler.stage, target)); + let _time = timeit(builder); builder.run(&mut cmd); Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target))) } @@ -1334,7 +1348,6 @@ impl Step for Miri { let target = self.target; assert!(builder.config.extended); - builder.info(&format!("Dist miri stage{} ({})", compiler.stage, target)); let src = builder.src.join("src/tools/miri"); let release_num = builder.release_num("miri"); let name = pkgname(builder, "miri"); @@ -1389,6 +1402,8 @@ impl Step for Miri { .arg("--legacy-manifest-dirs=rustlib,cargo") .arg("--component-name=miri-preview"); + builder.info(&format!("Dist miri stage{} ({})", compiler.stage, target)); + let _time = timeit(builder); builder.run(&mut cmd); Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target))) } @@ -1423,7 +1438,6 @@ impl Step for Rustfmt { let compiler = self.compiler; let target = self.target; - builder.info(&format!("Dist Rustfmt stage{} ({})", compiler.stage, target)); let src = builder.src.join("src/tools/rustfmt"); let release_num = builder.release_num("rustfmt"); let name = pkgname(builder, "rustfmt"); @@ -1476,6 +1490,8 @@ impl Step for Rustfmt { .arg("--legacy-manifest-dirs=rustlib,cargo") .arg("--component-name=rustfmt-preview"); + builder.info(&format!("Dist Rustfmt stage{} ({})", compiler.stage, target)); + let _time = timeit(builder); builder.run(&mut cmd); Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target))) } @@ -1576,6 +1592,7 @@ impl Step for Extended { input_tarballs.push(tarball); } + builder.info("building combined installer"); let mut cmd = rust_installer(builder); cmd.arg("combine") .arg("--product-name=Rust") @@ -1587,7 +1604,9 @@ impl Step for Extended { .arg("--legacy-manifest-dirs=rustlib,cargo") .arg("--input-tarballs").arg(input_tarballs) .arg("--non-installed-overlay").arg(&overlay); + let time = timeit(&builder); builder.run(&mut cmd); + drop(time); let mut license = String::new(); license += &builder.read(&builder.src.join("COPYRIGHT")); @@ -1643,6 +1662,7 @@ impl Step for Extended { }; if target.contains("apple-darwin") { + builder.info("building pkg installer"); let pkg = tmp.join("pkg"); let _ = fs::remove_dir_all(&pkg); @@ -1692,6 +1712,7 @@ impl Step for Extended { pkgname(builder, "rust"), target))) .arg("--package-path").arg(&pkg); + let _time = timeit(builder); builder.run(&mut cmd); } @@ -1742,14 +1763,18 @@ impl Step for Extended { builder.create(&exe.join("LICENSE.txt"), &license); // Generate exe installer + builder.info("building `exe` installer with `iscc`"); let mut cmd = Command::new("iscc"); cmd.arg("rust.iss") + .arg("/Q") .current_dir(&exe); if target.contains("windows-gnu") { cmd.arg("/dMINGW"); } add_env(builder, &mut cmd, target); + let time = timeit(builder); builder.run(&mut cmd); + drop(time); builder.install(&exe.join(format!("{}-{}.exe", pkgname(builder, "rust"), target)), &distdir(builder), 0o755); @@ -1914,6 +1939,7 @@ impl Step for Extended { builder.install(&etc.join("gfx/banner.bmp"), &exe, 0o644); builder.install(&etc.join("gfx/dialogbg.bmp"), &exe, 0o644); + builder.info(&format!("building `msi` installer with {:?}", light)); let filename = format!("{}-{}.msi", pkgname(builder, "rust"), target); let mut cmd = Command::new(&light); cmd.arg("-nologo") @@ -1946,6 +1972,7 @@ impl Step for Extended { // ICE57 wrongly complains about the shortcuts cmd.arg("-sice:ICE57"); + let _time = timeit(builder); builder.run(&mut cmd); if !builder.config.dry_run { @@ -2114,6 +2141,7 @@ impl Step for LlvmTools { } builder.info(&format!("Dist LlvmTools ({})", target)); + let _time = timeit(builder); let src = builder.src.join("src/llvm-project/llvm"); let name = pkgname(builder, "llvm-tools"); From 633ad73ef17c02e1893becbd030e2d188851042c Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 20 Sep 2019 09:36:03 -0700 Subject: [PATCH 05/11] Update to LLVM 9.0.0 --- .gitmodules | 2 +- src/llvm-project | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index f64e21c5af0e..3ff5af78097f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -43,7 +43,7 @@ [submodule "src/llvm-project"] path = src/llvm-project url = https://github.com/rust-lang/llvm-project.git - branch = rustc/9.0-2019-07-12 + branch = rustc/9.0-2019-09-19 [submodule "src/doc/embedded-book"] path = src/doc/embedded-book url = https://github.com/rust-embedded/book.git diff --git a/src/llvm-project b/src/llvm-project index 71fe7ec06b85..8adf9bdccfef 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 71fe7ec06b85f612fc0e4eb4134c7a7d0f23fac5 +Subproject commit 8adf9bdccfefb8d03f0e8db3b012fb41da1580a4 From 9cf9030e1cc4c6231419f5e9f7a5bd42eb1f55c1 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Fri, 20 Sep 2019 18:39:13 +0200 Subject: [PATCH 06/11] Allow using fn pointers in const fn behind const_fn_ptr gate --- src/librustc_mir/transform/qualify_consts.rs | 20 ++++++++++--- src/libsyntax/feature_gate/active.rs | 3 ++ src/libsyntax_pos/symbol.rs | 1 + src/test/ui/consts/const-eval/const_fn_ptr.rs | 21 ++++++++++++++ .../ui/consts/const-eval/const_fn_ptr_fail.rs | 15 ++++++++++ .../const-eval/const_fn_ptr_fail.stderr | 20 +++++++++++++ .../consts/const-eval/const_fn_ptr_fail2.rs | 21 ++++++++++++++ .../const-eval/const_fn_ptr_fail2.stderr | 28 +++++++++++++++++++ .../const-eval/feature-gate-const_fn_ptr.rs | 11 ++++++++ .../feature-gate-const_fn_ptr.stderr | 12 ++++++++ 10 files changed, 148 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/consts/const-eval/const_fn_ptr.rs create mode 100644 src/test/ui/consts/const-eval/const_fn_ptr_fail.rs create mode 100644 src/test/ui/consts/const-eval/const_fn_ptr_fail.stderr create mode 100644 src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs create mode 100644 src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr create mode 100644 src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.rs create mode 100644 src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.stderr diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 7cc1e634cf81..3842942d97fb 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1407,11 +1407,23 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { } } ty::FnPtr(_) => { + let unleash_miri = self + .tcx + .sess + .opts + .debugging_opts + .unleash_the_miri_inside_of_you; + let const_fn_ptr = self.tcx.features().const_fn_ptr; if self.mode.requires_const_checking() { - let mut err = self.tcx.sess.struct_span_err( - self.span, - &format!("function pointers are not allowed in const fn")); - err.emit(); + if !(unleash_miri || const_fn_ptr) { + emit_feature_err( + &self.tcx.sess.parse_sess, + sym::const_fn_ptr, + self.span, + GateIssue::Language, + "function pointers in const fn are unstable", + ); + } } } _ => { diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs index dd78777b5698..d1a17dc14bdf 100644 --- a/src/libsyntax/feature_gate/active.rs +++ b/src/libsyntax/feature_gate/active.rs @@ -405,6 +405,9 @@ declare_features! ( /// Allows macro invocations in `extern {}` blocks. (active, macros_in_extern, "1.27.0", Some(49476), None), + /// Allows calling function pointers inside `const` functions. + (active, const_fn_ptr, "1.27.0", Some(51909), None), + /// Allows accessing fields of unions inside `const` functions. (active, const_fn_union, "1.27.0", Some(51909), None), diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 597ae83572ce..e6be8a2cb874 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -198,6 +198,7 @@ symbols! { const_compare_raw_pointers, const_constructor, const_fn, + const_fn_ptr, const_fn_union, const_generics, const_indexing, diff --git a/src/test/ui/consts/const-eval/const_fn_ptr.rs b/src/test/ui/consts/const-eval/const_fn_ptr.rs new file mode 100644 index 000000000000..1acb3d8ad106 --- /dev/null +++ b/src/test/ui/consts/const-eval/const_fn_ptr.rs @@ -0,0 +1,21 @@ +// run-pass +#![feature(const_fn)] +#![feature(const_fn_ptr)] + +const fn double(x: usize) -> usize { x * 2 } +const X: fn(usize) -> usize = double; + +const fn bar(x: usize) -> usize { + X(x) +} + +const fn foo(x: fn(usize) -> usize, y: usize) -> usize { + x(y) +} + +fn main() { + const Y: usize = bar(2); + assert_eq!(Y, 4); + const Z: usize = foo(double, 2); + assert_eq!(Z, 4); +} diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail.rs b/src/test/ui/consts/const-eval/const_fn_ptr_fail.rs new file mode 100644 index 000000000000..e8041e56c38f --- /dev/null +++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail.rs @@ -0,0 +1,15 @@ +// run-pass + +// FIXME: this should not pass + +#![feature(const_fn)] +#![feature(const_fn_ptr)] + +fn double(x: usize) -> usize { x * 2 } +const X: fn(usize) -> usize = double; + +const fn bar(x: usize) -> usize { + X(x) +} + +fn main() {} diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail.stderr b/src/test/ui/consts/const-eval/const_fn_ptr_fail.stderr new file mode 100644 index 000000000000..b7f3a74cc44c --- /dev/null +++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail.stderr @@ -0,0 +1,20 @@ +warning: function is never used: `double` + --> $DIR/const_fn_ptr_fail.rs:8:1 + | +LL | fn double(x: usize) -> usize { x * 2 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(dead_code)]` on by default + +warning: constant item is never used: `X` + --> $DIR/const_fn_ptr_fail.rs:9:1 + | +LL | const X: fn(usize) -> usize = double; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: function is never used: `bar` + --> $DIR/const_fn_ptr_fail.rs:11:1 + | +LL | const fn bar(x: usize) -> usize { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs new file mode 100644 index 000000000000..66e01cae3145 --- /dev/null +++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs @@ -0,0 +1,21 @@ +#![feature(const_fn)] +#![feature(const_fn_ptr)] + +fn double(x: usize) -> usize { x * 2 } +const X: fn(usize) -> usize = double; + +const fn bar(x: fn(usize) -> usize, y: usize) -> usize { + x(y) +} + +const Y: usize = bar(X, 2); +//~^ ERROR any use of this value will cause an error + +const Z: usize = bar(double, 2); +//~^ ERROR any use of this value will cause an error + + +fn main() { + assert_eq!(Y, 4); + assert_eq!(Z, 4); +} diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr new file mode 100644 index 000000000000..020889c2ca1a --- /dev/null +++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr @@ -0,0 +1,28 @@ +error: any use of this value will cause an error + --> $DIR/const_fn_ptr_fail2.rs:8:5 + | +LL | x(y) + | ^^^^ + | | + | calling non-const function `double` + | inside call to `bar` at $DIR/const_fn_ptr_fail2.rs:11:18 +... +LL | const Y: usize = bar(X, 2); + | --------------------------- + | + = note: `#[deny(const_err)]` on by default + +error: any use of this value will cause an error + --> $DIR/const_fn_ptr_fail2.rs:8:5 + | +LL | x(y) + | ^^^^ + | | + | calling non-const function `double` + | inside call to `bar` at $DIR/const_fn_ptr_fail2.rs:14:18 +... +LL | const Z: usize = bar(double, 2); + | -------------------------------- + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.rs b/src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.rs new file mode 100644 index 000000000000..ea1ca05c31b8 --- /dev/null +++ b/src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.rs @@ -0,0 +1,11 @@ +#![feature(const_fn)] + +fn main() {} + +const fn foo() {} +const X: fn() = foo; + +const fn bar() { + X() + //~^ ERROR function pointers in const fn are unstable +} diff --git a/src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.stderr b/src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.stderr new file mode 100644 index 000000000000..fe5956d06f2a --- /dev/null +++ b/src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.stderr @@ -0,0 +1,12 @@ +error[E0658]: function pointers in const fn are unstable + --> $DIR/feature-gate-const_fn_ptr.rs:9:5 + | +LL | X() + | ^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/51909 + = help: add `#![feature(const_fn_ptr)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. From d4344969731e55bd0acaee4ad6962a85c8e0f27a Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Sat, 21 Sep 2019 16:09:38 +0200 Subject: [PATCH 07/11] remove feature --- src/librustc_mir/transform/qualify_consts.rs | 17 +- src/libsyntax/feature_gate/active.rs | 3 - src/libsyntax_pos/symbol.rs | 1 - src/test/ui/consts/const-eval/const_fn_ptr.rs | 24 ++- .../ui/consts/const-eval/const_fn_ptr.stderr | 152 ++++++++++++++++++ .../ui/consts/const-eval/const_fn_ptr_fail.rs | 8 +- .../const-eval/const_fn_ptr_fail.stderr | 20 --- .../consts/const-eval/const_fn_ptr_fail2.rs | 19 ++- .../const-eval/const_fn_ptr_fail2.stderr | 85 +++++++--- .../const-eval/feature-gate-const_fn_ptr.rs | 11 -- .../feature-gate-const_fn_ptr.stderr | 12 -- 11 files changed, 257 insertions(+), 95 deletions(-) create mode 100644 src/test/ui/consts/const-eval/const_fn_ptr.stderr delete mode 100644 src/test/ui/consts/const-eval/const_fn_ptr_fail.stderr delete mode 100644 src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.rs delete mode 100644 src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.stderr diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 3842942d97fb..60b88277715b 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1413,17 +1413,12 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { .opts .debugging_opts .unleash_the_miri_inside_of_you; - let const_fn_ptr = self.tcx.features().const_fn_ptr; - if self.mode.requires_const_checking() { - if !(unleash_miri || const_fn_ptr) { - emit_feature_err( - &self.tcx.sess.parse_sess, - sym::const_fn_ptr, - self.span, - GateIssue::Language, - "function pointers in const fn are unstable", - ); - } + if self.mode.requires_const_checking() && !unleash_miri { + let mut err = self.tcx.sess.struct_span_err( + self.span, + "function pointers in `const fn` are unstable", + ); + err.emit(); } } _ => { diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs index d1a17dc14bdf..dd78777b5698 100644 --- a/src/libsyntax/feature_gate/active.rs +++ b/src/libsyntax/feature_gate/active.rs @@ -405,9 +405,6 @@ declare_features! ( /// Allows macro invocations in `extern {}` blocks. (active, macros_in_extern, "1.27.0", Some(49476), None), - /// Allows calling function pointers inside `const` functions. - (active, const_fn_ptr, "1.27.0", Some(51909), None), - /// Allows accessing fields of unions inside `const` functions. (active, const_fn_union, "1.27.0", Some(51909), None), diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index e6be8a2cb874..597ae83572ce 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -198,7 +198,6 @@ symbols! { const_compare_raw_pointers, const_constructor, const_fn, - const_fn_ptr, const_fn_union, const_generics, const_indexing, diff --git a/src/test/ui/consts/const-eval/const_fn_ptr.rs b/src/test/ui/consts/const-eval/const_fn_ptr.rs index 1acb3d8ad106..498f801db81b 100644 --- a/src/test/ui/consts/const-eval/const_fn_ptr.rs +++ b/src/test/ui/consts/const-eval/const_fn_ptr.rs @@ -1,21 +1,37 @@ // run-pass +// compile-flags: -Zunleash-the-miri-inside-of-you #![feature(const_fn)] -#![feature(const_fn_ptr)] -const fn double(x: usize) -> usize { x * 2 } +fn double(x: usize) -> usize { x * 2 } +const fn double_const(x: usize) -> usize { x * 2 } + const X: fn(usize) -> usize = double; +const X_const: fn(usize) -> usize = double_const; const fn bar(x: usize) -> usize { X(x) } +const fn bar_const(x: usize) -> usize { + X_const(x) +} + const fn foo(x: fn(usize) -> usize, y: usize) -> usize { x(y) } fn main() { - const Y: usize = bar(2); + const Y: usize = bar_const(2); assert_eq!(Y, 4); - const Z: usize = foo(double, 2); + let y = bar_const(2); + assert_eq!(y, 4); + let y = bar(2); + assert_eq!(y, 4); + + const Z: usize = foo(double_const, 2); assert_eq!(Z, 4); + let z = foo(double_const, 2); + assert_eq!(z, 4); + let z = foo(double, 2); + assert_eq!(z, 4); } diff --git a/src/test/ui/consts/const-eval/const_fn_ptr.stderr b/src/test/ui/consts/const-eval/const_fn_ptr.stderr new file mode 100644 index 000000000000..41452ee59eb9 --- /dev/null +++ b/src/test/ui/consts/const-eval/const_fn_ptr.stderr @@ -0,0 +1,152 @@ +warning: skipping const checks + --> $DIR/const_fn_ptr.rs:25:5 + | +LL | assert_eq!(Y, 4); + | ^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/const_fn_ptr.rs:25:5 + | +LL | assert_eq!(Y, 4); + | ^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/const_fn_ptr.rs:25:5 + | +LL | assert_eq!(Y, 4); + | ^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/const_fn_ptr.rs:27:5 + | +LL | assert_eq!(y, 4); + | ^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/const_fn_ptr.rs:27:5 + | +LL | assert_eq!(y, 4); + | ^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/const_fn_ptr.rs:27:5 + | +LL | assert_eq!(y, 4); + | ^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/const_fn_ptr.rs:29:5 + | +LL | assert_eq!(y, 4); + | ^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/const_fn_ptr.rs:29:5 + | +LL | assert_eq!(y, 4); + | ^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/const_fn_ptr.rs:29:5 + | +LL | assert_eq!(y, 4); + | ^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/const_fn_ptr.rs:32:5 + | +LL | assert_eq!(Z, 4); + | ^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/const_fn_ptr.rs:32:5 + | +LL | assert_eq!(Z, 4); + | ^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/const_fn_ptr.rs:32:5 + | +LL | assert_eq!(Z, 4); + | ^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/const_fn_ptr.rs:34:5 + | +LL | assert_eq!(z, 4); + | ^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/const_fn_ptr.rs:34:5 + | +LL | assert_eq!(z, 4); + | ^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/const_fn_ptr.rs:34:5 + | +LL | assert_eq!(z, 4); + | ^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/const_fn_ptr.rs:36:5 + | +LL | assert_eq!(z, 4); + | ^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/const_fn_ptr.rs:36:5 + | +LL | assert_eq!(z, 4); + | ^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/const_fn_ptr.rs:36:5 + | +LL | assert_eq!(z, 4); + | ^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: constant `X_const` should have an upper case name + --> $DIR/const_fn_ptr.rs:9:7 + | +LL | const X_const: fn(usize) -> usize = double_const; + | ^^^^^^^ help: convert the identifier to upper case: `X_CONST` + | + = note: `#[warn(non_upper_case_globals)]` on by default + diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail.rs b/src/test/ui/consts/const-eval/const_fn_ptr_fail.rs index e8041e56c38f..14bd6558e7f8 100644 --- a/src/test/ui/consts/const-eval/const_fn_ptr_fail.rs +++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail.rs @@ -1,15 +1,13 @@ // run-pass - -// FIXME: this should not pass - +// compile-flags: -Zunleash-the-miri-inside-of-you #![feature(const_fn)] -#![feature(const_fn_ptr)] +#![allow(unused)] fn double(x: usize) -> usize { x * 2 } const X: fn(usize) -> usize = double; const fn bar(x: usize) -> usize { - X(x) + X(x) // FIXME: this should error someday } fn main() {} diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail.stderr b/src/test/ui/consts/const-eval/const_fn_ptr_fail.stderr deleted file mode 100644 index b7f3a74cc44c..000000000000 --- a/src/test/ui/consts/const-eval/const_fn_ptr_fail.stderr +++ /dev/null @@ -1,20 +0,0 @@ -warning: function is never used: `double` - --> $DIR/const_fn_ptr_fail.rs:8:1 - | -LL | fn double(x: usize) -> usize { x * 2 } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(dead_code)]` on by default - -warning: constant item is never used: `X` - --> $DIR/const_fn_ptr_fail.rs:9:1 - | -LL | const X: fn(usize) -> usize = double; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: function is never used: `bar` - --> $DIR/const_fn_ptr_fail.rs:11:1 - | -LL | const fn bar(x: usize) -> usize { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs index 66e01cae3145..74c60f9a2a58 100644 --- a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs +++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs @@ -1,5 +1,6 @@ +// compile-flags: -Zunleash-the-miri-inside-of-you #![feature(const_fn)] -#![feature(const_fn_ptr)] +#![allow(const_err)] fn double(x: usize) -> usize { x * 2 } const X: fn(usize) -> usize = double; @@ -8,14 +9,18 @@ const fn bar(x: fn(usize) -> usize, y: usize) -> usize { x(y) } -const Y: usize = bar(X, 2); -//~^ ERROR any use of this value will cause an error - -const Z: usize = bar(double, 2); -//~^ ERROR any use of this value will cause an error - +const Y: usize = bar(X, 2); // FIXME: should fail to typeck someday +const Z: usize = bar(double, 2); // FIXME: should fail to typeck someday fn main() { assert_eq!(Y, 4); + //~^ ERROR evaluation of constant expression failed + //~^^ WARN skipping const checks + //~^^^ WARN skipping const checks + //~^^^^ WARN skipping const checks assert_eq!(Z, 4); + //~^ ERROR evaluation of constant expression failed + //~^^ WARN skipping const checks + //~^^^ WARN skipping const checks + //~^^^^ WARN skipping const checks } diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr index 020889c2ca1a..611cc5313c05 100644 --- a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr +++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr @@ -1,28 +1,71 @@ -error: any use of this value will cause an error - --> $DIR/const_fn_ptr_fail2.rs:8:5 +warning: skipping const checks + --> $DIR/const_fn_ptr_fail2.rs:16:5 | -LL | x(y) - | ^^^^ - | | - | calling non-const function `double` - | inside call to `bar` at $DIR/const_fn_ptr_fail2.rs:11:18 -... -LL | const Y: usize = bar(X, 2); - | --------------------------- +LL | assert_eq!(Y, 4); + | ^^^^^^^^^^^^^^^^^ | - = note: `#[deny(const_err)]` on by default + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) -error: any use of this value will cause an error - --> $DIR/const_fn_ptr_fail2.rs:8:5 +warning: skipping const checks + --> $DIR/const_fn_ptr_fail2.rs:16:5 | -LL | x(y) - | ^^^^ - | | - | calling non-const function `double` - | inside call to `bar` at $DIR/const_fn_ptr_fail2.rs:14:18 -... -LL | const Z: usize = bar(double, 2); - | -------------------------------- +LL | assert_eq!(Y, 4); + | ^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/const_fn_ptr_fail2.rs:16:5 + | +LL | assert_eq!(Y, 4); + | ^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/const_fn_ptr_fail2.rs:21:5 + | +LL | assert_eq!(Z, 4); + | ^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/const_fn_ptr_fail2.rs:21:5 + | +LL | assert_eq!(Z, 4); + | ^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/const_fn_ptr_fail2.rs:21:5 + | +LL | assert_eq!(Z, 4); + | ^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +error[E0080]: evaluation of constant expression failed + --> $DIR/const_fn_ptr_fail2.rs:16:5 + | +LL | assert_eq!(Y, 4); + | ^^^^^^^^^^^-^^^^^ + | | + | referenced constant has errors + | + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +error[E0080]: evaluation of constant expression failed + --> $DIR/const_fn_ptr_fail2.rs:21:5 + | +LL | assert_eq!(Z, 4); + | ^^^^^^^^^^^-^^^^^ + | | + | referenced constant has errors + | + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.rs b/src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.rs deleted file mode 100644 index ea1ca05c31b8..000000000000 --- a/src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.rs +++ /dev/null @@ -1,11 +0,0 @@ -#![feature(const_fn)] - -fn main() {} - -const fn foo() {} -const X: fn() = foo; - -const fn bar() { - X() - //~^ ERROR function pointers in const fn are unstable -} diff --git a/src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.stderr b/src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.stderr deleted file mode 100644 index fe5956d06f2a..000000000000 --- a/src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0658]: function pointers in const fn are unstable - --> $DIR/feature-gate-const_fn_ptr.rs:9:5 - | -LL | X() - | ^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/51909 - = help: add `#![feature(const_fn_ptr)]` to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. From 9d4053f6921f3259076e2d88f983f9666a78ef4b Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Sat, 21 Sep 2019 17:24:42 +0200 Subject: [PATCH 08/11] revert error message changes --- src/librustc_mir/transform/qualify_consts.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 60b88277715b..795721f3b3f2 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1416,7 +1416,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { if self.mode.requires_const_checking() && !unleash_miri { let mut err = self.tcx.sess.struct_span_err( self.span, - "function pointers in `const fn` are unstable", + "function pointers are not allowed in const fn" ); err.emit(); } From e001c5f9d894a66722db061ecbbd224973dc0fb8 Mon Sep 17 00:00:00 2001 From: Guanqun Lu Date: Sat, 21 Sep 2019 23:36:12 +0800 Subject: [PATCH 09/11] unify errors for tuple/struct variants fix #63983 --- src/librustc_resolve/late/diagnostics.rs | 6 ++++++ src/test/ui/empty/empty-struct-tuple-pat.stderr | 7 ++++--- src/test/ui/issues/issue-32004.stderr | 5 +++-- src/test/ui/issues/issue-63983.rs | 15 +++++++++++++++ src/test/ui/issues/issue-63983.stderr | 15 +++++++++++++++ 5 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/issues/issue-63983.rs create mode 100644 src/test/ui/issues/issue-63983.stderr diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index 0c86d8494fde..1d4fa77adcc1 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -445,6 +445,12 @@ impl<'a> LateResolutionVisitor<'a, '_> { (Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _), _) if ns == ValueNS => { bad_struct_syntax_suggestion(); } + (Res::Def(DefKind::Ctor(_, CtorKind::Fn), _), _) if ns == ValueNS => { + err.span_label( + span, + format!("did you mean `{} ( /* fields */ )`?", path_str), + ); + } (Res::SelfTy(..), _) if ns == ValueNS => { err.span_label(span, fallback_label); err.note("can't use `Self` as a constructor, you must use the implemented struct"); diff --git a/src/test/ui/empty/empty-struct-tuple-pat.stderr b/src/test/ui/empty/empty-struct-tuple-pat.stderr index 777b9d4a4acd..6c15e7bf282c 100644 --- a/src/test/ui/empty/empty-struct-tuple-pat.stderr +++ b/src/test/ui/empty/empty-struct-tuple-pat.stderr @@ -20,15 +20,16 @@ error[E0532]: expected unit struct/variant or constant, found tuple variant `E:: --> $DIR/empty-struct-tuple-pat.rs:29:9 | LL | E::Empty4 => () - | ^^^^^^^^^ not a unit struct/variant or constant + | ^^^^^^^^^ did you mean `E::Empty4 ( /* fields */ )`? error[E0532]: expected unit struct/variant or constant, found tuple variant `XE::XEmpty5` --> $DIR/empty-struct-tuple-pat.rs:33:9 | LL | XE::XEmpty5 => (), | ^^^^------- - | | - | help: a unit variant with a similar name exists: `XEmpty4` + | | | + | | help: a unit variant with a similar name exists: `XEmpty4` + | did you mean `XE::XEmpty5 ( /* fields */ )`? error: aborting due to 4 previous errors diff --git a/src/test/ui/issues/issue-32004.stderr b/src/test/ui/issues/issue-32004.stderr index f8c418b25a0e..b56fa949acb7 100644 --- a/src/test/ui/issues/issue-32004.stderr +++ b/src/test/ui/issues/issue-32004.stderr @@ -3,8 +3,9 @@ error[E0532]: expected unit struct/variant or constant, found tuple variant `Foo | LL | Foo::Bar => {} | ^^^^^--- - | | - | help: a unit variant with a similar name exists: `Baz` + | | | + | | help: a unit variant with a similar name exists: `Baz` + | did you mean `Foo::Bar ( /* fields */ )`? error[E0532]: expected tuple struct/variant, found unit struct `S` --> $DIR/issue-32004.rs:16:9 diff --git a/src/test/ui/issues/issue-63983.rs b/src/test/ui/issues/issue-63983.rs new file mode 100644 index 000000000000..c1c79091fc80 --- /dev/null +++ b/src/test/ui/issues/issue-63983.rs @@ -0,0 +1,15 @@ +enum MyEnum { + Tuple(i32), + Struct{ s: i32 }, +} + +fn foo(en: MyEnum) { + match en { + MyEnum::Tuple => "", + //~^ ERROR expected unit struct/variant or constant, found tuple variant `MyEnum::Tuple` + MyEnum::Struct => "", + //~^ ERROR expected unit struct/variant or constant, found struct variant `MyEnum::Struct` + }; +} + +fn main() {} diff --git a/src/test/ui/issues/issue-63983.stderr b/src/test/ui/issues/issue-63983.stderr new file mode 100644 index 000000000000..67acd1d57c27 --- /dev/null +++ b/src/test/ui/issues/issue-63983.stderr @@ -0,0 +1,15 @@ +error[E0532]: expected unit struct/variant or constant, found tuple variant `MyEnum::Tuple` + --> $DIR/issue-63983.rs:8:9 + | +LL | MyEnum::Tuple => "", + | ^^^^^^^^^^^^^ did you mean `MyEnum::Tuple ( /* fields */ )`? + +error[E0532]: expected unit struct/variant or constant, found struct variant `MyEnum::Struct` + --> $DIR/issue-63983.rs:10:9 + | +LL | MyEnum::Struct => "", + | ^^^^^^^^^^^^^^ did you mean `MyEnum::Struct { /* fields */ }`? + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0532`. From a2a57bc6cf383fc113335148296c7965bb29e9a2 Mon Sep 17 00:00:00 2001 From: Sam Radhakrishan Date: Thu, 19 Sep 2019 22:12:05 +0530 Subject: [PATCH 10/11] Fixes #63962. Hint about missing tuple parentheses in patterns --- src/librustc_typeck/check/pat.rs | 41 +++++++++++++++++++++++----- src/test/ui/error-codes/E0023.rs | 2 ++ src/test/ui/error-codes/E0023.stderr | 21 +++++++++++--- 3 files changed, 53 insertions(+), 11 deletions(-) diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index d93a4052cd39..d687a5084e23 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -676,18 +676,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } else { // Pattern has wrong number of fields. - self.e0023(pat.span, res, &subpats, &variant.fields); + self.e0023(pat.span, res, &subpats, &variant.fields, expected); on_error(); return tcx.types.err; } pat_ty } - fn e0023(&self, pat_span: Span, res: Res, subpats: &'tcx [P], fields: &[ty::FieldDef]) { + fn e0023( + &self, + pat_span: Span, + res: Res, + subpats: &'tcx [P], + fields: &[ty::FieldDef], + expected: Ty<'tcx> + ) { let subpats_ending = pluralise!(subpats.len()); let fields_ending = pluralise!(fields.len()); + let missing_parenthesis = match expected.sty { + ty::Adt(_, substs) if fields.len() == 1 => { + let field_ty = fields[0].ty(self.tcx, substs); + match field_ty.sty { + ty::Tuple(_) => field_ty.tuple_fields().count() == subpats.len(), + _ => false, + } + } + _ => false, + }; let res_span = self.tcx.def_span(res.def_id()); - struct_span_err!( + let mut err = struct_span_err!( self.tcx.sess, pat_span, E0023, @@ -697,15 +714,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { res.descr(), fields.len(), fields_ending, - ) - .span_label(pat_span, format!( + ); + err.span_label(pat_span, format!( "expected {} field{}, found {}", fields.len(), fields_ending, subpats.len(), )) - .span_label(res_span, format!("{} defined here", res.descr())) - .emit(); + .span_label(res_span, format!("{} defined here", res.descr())); + + if missing_parenthesis { + err.multipart_suggestion( + "missing parenthesis", + vec![(subpats[0].span.shrink_to_lo(), "(".to_string()), + (subpats[subpats.len()-1].span.shrink_to_hi(), ")".to_string())], + Applicability::MachineApplicable, + ); + } + + err.emit(); } fn check_pat_tuple( diff --git a/src/test/ui/error-codes/E0023.rs b/src/test/ui/error-codes/E0023.rs index 2a97e9048a49..dc421e060e86 100644 --- a/src/test/ui/error-codes/E0023.rs +++ b/src/test/ui/error-codes/E0023.rs @@ -1,6 +1,7 @@ enum Fruit { Apple(String, String), Pear(u32), + Orange((String, String)), } @@ -10,5 +11,6 @@ fn main() { Fruit::Apple(a) => {}, //~ ERROR E0023 Fruit::Apple(a, b, c) => {}, //~ ERROR E0023 Fruit::Pear(1, 2) => {}, //~ ERROR E0023 + Fruit::Orange(a, b) => {}, //~ ERROR E0023 } } diff --git a/src/test/ui/error-codes/E0023.stderr b/src/test/ui/error-codes/E0023.stderr index d04e494c2585..8ae7d01ed5f7 100644 --- a/src/test/ui/error-codes/E0023.stderr +++ b/src/test/ui/error-codes/E0023.stderr @@ -1,5 +1,5 @@ error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields - --> $DIR/E0023.rs:10:9 + --> $DIR/E0023.rs:11:9 | LL | Apple(String, String), | --------------------- tuple variant defined here @@ -8,7 +8,7 @@ LL | Fruit::Apple(a) => {}, | ^^^^^^^^^^^^^^^ expected 2 fields, found 1 error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields - --> $DIR/E0023.rs:11:9 + --> $DIR/E0023.rs:12:9 | LL | Apple(String, String), | --------------------- tuple variant defined here @@ -17,7 +17,7 @@ LL | Fruit::Apple(a, b, c) => {}, | ^^^^^^^^^^^^^^^^^^^^^ expected 2 fields, found 3 error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field - --> $DIR/E0023.rs:12:9 + --> $DIR/E0023.rs:13:9 | LL | Pear(u32), | --------- tuple variant defined here @@ -25,6 +25,19 @@ LL | Pear(u32), LL | Fruit::Pear(1, 2) => {}, | ^^^^^^^^^^^^^^^^^ expected 1 field, found 2 -error: aborting due to 3 previous errors +error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field + --> $DIR/E0023.rs:14:9 + | +LL | Orange((String, String)), + | ------------------------ tuple variant defined here +... +LL | Fruit::Orange(a, b) => {}, + | ^^^^^^^^^^^^^^^^^^^ expected 1 field, found 2 +help: missing parenthesis + | +LL | Fruit::Orange((a, b)) => {}, + | ^ ^ + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0023`. From 53a6a2f3226652e212bba6fcf37166a2fe3ecfca Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 21 Sep 2019 21:33:37 +0300 Subject: [PATCH 11/11] fully remove AstBuilder The mentioned Cargo test is fixed in https://github.com/rust-lang/cargo/pull/7210 --- src/libsyntax/ext/build.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index f1d0e0b68f73..60560ae96deb 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -9,9 +9,6 @@ use crate::ThinVec; use rustc_target::spec::abi::Abi; use syntax_pos::{Pos, Span}; -// Left so that Cargo tests don't break, this can be removed once those no longer use it -pub trait AstBuilder {} - impl<'a> ExtCtxt<'a> { pub fn path(&self, span: Span, strs: Vec ) -> ast::Path { self.path_all(span, false, strs, vec![], vec![])