diff --git a/src/bootstrap/step.rs b/src/bootstrap/step.rs index 9e8b08a23b7e9..8c3662002671b 100644 --- a/src/bootstrap/step.rs +++ b/src/bootstrap/step.rs @@ -463,7 +463,7 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { rules.test("check-linkchecker", "src/tools/linkchecker") .dep(|s| s.name("tool-linkchecker").stage(0)) .dep(|s| s.name("default:doc")) - .default(true) + .default(build.config.docs) .host(true) .run(move |s| check::linkcheck(build, s.target)); rules.test("check-cargotest", "src/tools/cargotest") @@ -1407,13 +1407,20 @@ mod tests { fn build(args: &[&str], extra_host: &[&str], extra_target: &[&str]) -> Build { + build_(args, extra_host, extra_target, true) + } + + fn build_(args: &[&str], + extra_host: &[&str], + extra_target: &[&str], + docs: bool) -> Build { let mut args = args.iter().map(|s| s.to_string()).collect::>(); args.push("--build".to_string()); args.push("A".to_string()); let flags = Flags::parse(&args); let mut config = Config::default(); - config.docs = true; + config.docs = docs; config.build = "A".to_string(); config.host = vec![config.build.clone()]; config.host.extend(extra_host.iter().map(|s| s.to_string())); @@ -1768,4 +1775,22 @@ mod tests { assert!(!plan.iter().any(|s| s.name.contains("tidy"))); assert!(plan.iter().any(|s| s.name.contains("valgrind"))); } + + #[test] + fn test_disable_docs() { + let build = build_(&["test"], &[], &[], false); + let rules = super::build_rules(&build); + let plan = rules.plan(); + println!("rules: {:#?}", plan); + assert!(!plan.iter().any(|s| { + s.name.contains("doc-") || s.name.contains("default:doc") + })); + // none of the dependencies should be a doc rule either + assert!(!plan.iter().any(|s| { + rules.rules[s.name].deps.iter().any(|dep| { + let dep = dep(&rules.sbuild.name(s.name)); + dep.name.contains("doc-") || dep.name.contains("default:doc") + }) + })); + } } diff --git a/src/doc/unstable-book/src/SUMMARY.md b/src/doc/unstable-book/src/SUMMARY.md index 64bbb104f68e4..d8f742735a8d5 100644 --- a/src/doc/unstable-book/src/SUMMARY.md +++ b/src/doc/unstable-book/src/SUMMARY.md @@ -87,7 +87,6 @@ - [start](language-features/start.md) - [static_nobundle](language-features/static-nobundle.md) - [stmt_expr_attributes](language-features/stmt-expr-attributes.md) - - [struct_field_attributes](language-features/struct-field-attributes.md) - [structural_match](language-features/structural-match.md) - [target_feature](language-features/target-feature.md) - [thread_local](language-features/thread-local.md) diff --git a/src/doc/unstable-book/src/language-features/struct-field-attributes.md b/src/doc/unstable-book/src/language-features/struct-field-attributes.md deleted file mode 100644 index 1a94562968d19..0000000000000 --- a/src/doc/unstable-book/src/language-features/struct-field-attributes.md +++ /dev/null @@ -1,10 +0,0 @@ -# `struct_field_attributes` - -The tracking issue for this feature is: [#38814] - -[#38814]: https://github.com/rust-lang/rust/issues/38814 - ------------------------- - - - diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 83cd5cef00cfe..cc0e5dec266db 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -36,11 +36,11 @@ #![feature(discriminant_value)] #![feature(specialization)] #![feature(manually_drop)] -#![feature(struct_field_attributes)] #![cfg_attr(stage0, unstable(feature = "rustc_private", issue = "27812"))] #![cfg_attr(stage0, feature(rustc_private))] #![cfg_attr(stage0, feature(staged_api))] +#![cfg_attr(stage0, feature(struct_field_attributes))] #![cfg_attr(unix, feature(libc))] #![cfg_attr(test, feature(test))] diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index f820ea4c5e178..aa0fae508fde1 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -445,8 +445,11 @@ impl EmitterWriter { && next.has_label()) // multiline start/end, move it to a new line || (annotation.has_label() // so as not to overlap the orizontal lines. && next.takes_space()) - || (annotation.takes_space() - && next.takes_space()) + || (annotation.takes_space() && next.takes_space()) + || (overlaps(next, annotation, l) + && next.end_col <= annotation.end_col + && next.has_label() + && p == 0) // Avoid #42595. { // This annotation needs a new line in the output. p += 1; diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index d5ee66a2f0a07..385ed7eb0e384 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -15,7 +15,7 @@ use super::method::MethodCallee; use hir::def::Def; use hir::def_id::{DefId, LOCAL_CRATE}; use rustc::{infer, traits}; -use rustc::ty::{self, TyCtxt, LvaluePreference, Ty}; +use rustc::ty::{self, TyCtxt, TypeFoldable, LvaluePreference, Ty}; use rustc::ty::subst::Subst; use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow}; use syntax::abi; @@ -209,17 +209,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } } - let mut err = if let Some(path) = unit_variant { - let mut err = self.type_error_struct(call_expr.span, |_| { - format!("`{}` is being called, but it is not a function", path) - }, callee_ty); + let mut err = type_error_struct!(self.tcx.sess, call_expr.span, callee_ty, E0618, + "expected function, found `{}`", + if let Some(ref path) = unit_variant { + path.to_string() + } else { + callee_ty.to_string() + }); + if let Some(path) = unit_variant { err.help(&format!("did you mean to write `{}`?", path)); - err - } else { - self.type_error_struct(call_expr.span, |actual| { - format!("expected function, found `{}`", actual) - }, callee_ty) - }; + } if let hir::ExprCall(ref expr, _) = call_expr.node { let def = if let hir::ExprPath(ref qpath) = expr.node { diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index df9356ea81148..f72af2084f022 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -4195,6 +4195,34 @@ as possible. For better explanations, see The Rust Book: https://doc.rust-lang.org/book/ "##, +E0618: r##" +Attempted to call something which isn't a function nor a method. + +Erroneous code examples: + +```compile_fail,E0618 +enum X { + Entry, +} + +X::Entry(); // error: expected function, found `X::Entry` + +// Or even simpler: +let x = 0i32; +x(); // error: expected function, found `i32` +``` + +Only functions and methods can be called using `()`. Example: + +``` +// We declare a function: +fn i_am_a_function() {} + +// And we call it: +i_am_a_function(); +``` +"##, + } register_diagnostics! { diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 061e807dace26..3f859c45c28cd 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -389,7 +389,7 @@ fn read_to_end(r: &mut R, buf: &mut Vec) -> Result /// The `Read` trait allows for reading bytes from a source. /// -/// Implementors of the `Read` trait are sometimes called 'readers'. +/// Implementors of the `Read` trait are called 'readers'. /// /// Readers are defined by one required method, `read()`. Each call to `read` /// will attempt to pull bytes from this source into a provided buffer. A diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index 2e98c7d962606..54e6dde41e6d4 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -223,7 +223,6 @@ impl<'a> StripUnconfigured<'a> { ast::ExprKind::Struct(path, fields, base) => { let fields = fields.into_iter() .filter_map(|field| { - self.visit_struct_field_attrs(field.attrs()); self.configure(field) }) .collect(); @@ -256,17 +255,6 @@ impl<'a> StripUnconfigured<'a> { } pub fn configure_struct_expr_field(&mut self, field: ast::Field) -> Option { - if !self.features.map(|features| features.struct_field_attributes).unwrap_or(true) { - if !field.attrs.is_empty() { - let mut err = feature_err(self.sess, - "struct_field_attributes", - field.span, - GateIssue::Language, - "attributes on struct literal fields are unstable"); - err.emit(); - } - } - self.configure(field) } @@ -275,7 +263,6 @@ impl<'a> StripUnconfigured<'a> { if let ast::PatKind::Struct(path, fields, etc) = pattern.node { let fields = fields.into_iter() .filter_map(|field| { - self.visit_struct_field_attrs(field.attrs()); self.configure(field) }) .collect(); @@ -284,21 +271,6 @@ impl<'a> StripUnconfigured<'a> { pattern }) } - - fn visit_struct_field_attrs(&mut self, attrs: &[ast::Attribute]) { - // flag the offending attributes - for attr in attrs.iter() { - if !self.features.map(|features| features.struct_field_attributes).unwrap_or(true) { - let mut err = feature_err( - self.sess, - "struct_field_attributes", - attr.span, - GateIssue::Language, - "attributes on struct pattern or literal fields are unstable"); - err.emit(); - } - } - } } impl<'a> fold::Folder for StripUnconfigured<'a> { diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 7ab0529f518ad..4543378789dfe 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -312,9 +312,6 @@ declare_features! ( // Declarative macros 2.0 (`macro`). (active, decl_macro, "1.17.0", Some(39412)), - // Allows attributes on struct literal fields. - (active, struct_field_attributes, "1.16.0", Some(38814)), - // Allows #[link(kind="static-nobundle"...] (active, static_nobundle, "1.16.0", Some(37403)), @@ -430,6 +427,8 @@ declare_features! ( (accepted, relaxed_adts, "1.19.0", Some(35626)), // Coerces non capturing closures to function pointers (accepted, closure_to_fn_coercion, "1.19.0", Some(39817)), + // Allows attributes on struct literal fields. + (accepted, struct_field_attributes, "1.20.0", Some(38814)), ); // If you change this, please modify src/doc/unstable-book as well. You must diff --git a/src/libsyntax/test_snippet.rs b/src/libsyntax/test_snippet.rs index b3fa1e97376d0..4fae2ff9814fd 100644 --- a/src/libsyntax/test_snippet.rs +++ b/src/libsyntax/test_snippet.rs @@ -735,6 +735,49 @@ error: foo "#); } +#[test] +fn multiple_labels_secondary_without_message_3() { + test_harness(r#" +fn foo() { + a bc d +} +"#, + vec![ + SpanLabel { + start: Position { + string: "a", + count: 1, + }, + end: Position { + string: "b", + count: 1, + }, + label: "`a` is a good letter", + }, + SpanLabel { + start: Position { + string: "c", + count: 1, + }, + end: Position { + string: "d", + count: 1, + }, + label: "", + }, + ], + r#" +error: foo + --> test.rs:3:3 + | +3 | a bc d + | ^^^^---- + | | + | `a` is a good letter + +"#); +} + #[test] fn multiple_labels_without_message() { test_harness(r#" diff --git a/src/test/compile-fail/struct-field-attr-feature-gate.rs b/src/test/compile-fail/E0618.rs similarity index 60% rename from src/test/compile-fail/struct-field-attr-feature-gate.rs rename to src/test/compile-fail/E0618.rs index 47495be4ad2c9..1ba2e8e2e5613 100644 --- a/src/test/compile-fail/struct-field-attr-feature-gate.rs +++ b/src/test/compile-fail/E0618.rs @@ -8,15 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// gate-test-struct_field_attributes - -struct Foo { - present: (), +enum X { + Entry, } fn main() { - let foo = Foo { #[cfg(all())] present: () }; - //~^ ERROR attributes on struct pattern or literal fields are unstable - let Foo { #[cfg(all())] present: () } = foo; - //~^ ERROR attributes on struct pattern or literal fields are unstable + X::Entry(); //~ ERROR expected function, found `X::Entry` [E0618] + //~| HELP did you mean to write `X::Entry`? + let x = 0i32; + x(); //~ ERROR expected function, found `i32` [E0618] } diff --git a/src/test/compile-fail/empty-struct-unit-expr.rs b/src/test/compile-fail/empty-struct-unit-expr.rs index 273ce91a7c5b8..9655007604de6 100644 --- a/src/test/compile-fail/empty-struct-unit-expr.rs +++ b/src/test/compile-fail/empty-struct-unit-expr.rs @@ -24,10 +24,10 @@ enum E { fn main() { let e2 = Empty2(); //~ ERROR expected function, found `Empty2` let e4 = E::Empty4(); - //~^ ERROR `E::Empty4` is being called, but it is not a function + //~^ ERROR expected function, found `E::Empty4` [E0618] //~| HELP did you mean to write `E::Empty4`? let xe2 = XEmpty2(); //~ ERROR expected function, found `empty_struct::XEmpty2` let xe4 = XE::XEmpty4(); - //~^ ERROR `XE::XEmpty4` is being called, but it is not a function + //~^ ERROR expected function, found `XE::XEmpty4` [E0618] //~| HELP did you mean to write `XE::XEmpty4`? } diff --git a/src/test/compile-fail/struct-field-cfg.rs b/src/test/compile-fail/struct-field-cfg.rs index 9fb130f4d54fe..974d500d9cbdb 100644 --- a/src/test/compile-fail/struct-field-cfg.rs +++ b/src/test/compile-fail/struct-field-cfg.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(struct_field_attributes)] - struct Foo { present: (), }