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 | 27 +++--- 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, 181 insertions(+), 23 deletions(-) diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index d2683090add40..7154962b59295 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 3d36790c94b8c..3e5520dd46557 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); - - generic_bounds.predicates.iter().map(|predicate| { - Obligation { cause: cause.clone(), - recursion_depth, - param_env, - predicate: predicate.clone() } +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(), }).collect() } diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 62910ec320494..993d627d6e176 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 eeee26a75671f..ca6118cb3ba98 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 0f8c5257d445f..c9d88b7af0753 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 7d6c025d69d55..e037bd851ca21 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 4a2a6d03c607f..d6328a64c7c74 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 a33908c01c842..8176e96d6de1f 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 c2d0e0c2a26bc..fd6fce938b2c7 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 2c4c61a0957f9..99c6a8cdd6daf 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 3e6181adec026..e30e2626e9f34 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 357e6b026e2a3..e4d0a731ebfe5 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 d223b9672cfdc..d92c3f034e5a2 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 145d6a8431bf4..98a70f268cf72 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 c57ca3e25d99f..3f2d0aa87adc1 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 5ab23cb55bcc4..4c464e6d4f685 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 eb9aada389f8f..9658f6980be2f 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 58e28c1a9dc83..a6ccc4835fa68 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 6256dc0c55022..9c11a02923c8c 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 f030670161343..4a9afb9d2494e 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 ab0bdc44cff1a..43cebd7f9c245 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 1192b0e5cfa53..932087421fbcb 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 72c6d7ae22b4b..b905cd1a294cc 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 ee73622cb7bd1..a0a617fdbbc35 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 9acae5c376d5b..3397eec9e050b 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 0448a28ea8e27..a10bf4e0b7787 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 e25f79947c732..9f0fa5a0ea1fe 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 c22d60b6c5df1..70648beac38b0 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 a471ccc6f5b48..a2e378f7b1db4 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 076bcd878df71..50b20763c43d2 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 f64e21c5af0e4..3ff5af78097fa 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 71fe7ec06b85f..8adf9bdccfefb 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 7cc1e634cf812..3842942d97fbb 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 dd78777b56986..d1a17dc14bdf7 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 597ae83572cee..e6be8a2cb874a 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 0000000000000..1acb3d8ad1065 --- /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 0000000000000..e8041e56c38fb --- /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 0000000000000..b7f3a74cc44c0 --- /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 0000000000000..66e01cae31452 --- /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 0000000000000..020889c2ca1a0 --- /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 0000000000000..ea1ca05c31b8f --- /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 0000000000000..fe5956d06f2a0 --- /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 | 93 ++++++++--- .../const-eval/feature-gate-const_fn_ptr.rs | 11 -- .../feature-gate-const_fn_ptr.stderr | 12 -- 11 files changed, 261 insertions(+), 99 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 3842942d97fbb..60b88277715bc 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 d1a17dc14bdf7..dd78777b56986 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 e6be8a2cb874a..597ae83572cee 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 1acb3d8ad1065..498f801db81b8 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 0000000000000..41452ee59eb94 --- /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 e8041e56c38fb..14bd6558e7f89 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 b7f3a74cc44c0..0000000000000 --- 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 66e01cae31452..74c60f9a2a58d 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 020889c2ca1a0..611cc5313c057 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 - | -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); - | -------------------------------- +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: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: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 ea1ca05c31b8f..0000000000000 --- 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 fe5956d06f2a0..0000000000000 --- 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 60b88277715bc..795721f3b3f28 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 0c86d8494fde8..1d4fa77adcc1c 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 777b9d4a4acd0..6c15e7bf282ce 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 f8c418b25a0e4..b56fa949acb7e 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 0000000000000..c1c79091fc802 --- /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 0000000000000..67acd1d57c27a --- /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 d93a4052cd393..d687a5084e231 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 2a97e9048a490..dc421e060e86f 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 d04e494c2585c..8ae7d01ed5f7e 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 f1d0e0b68f735..60560ae96deb5 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![])