diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 553ffda814fe9..b2b578f1ed44a 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1399,6 +1399,37 @@ impl<'a> Parser<'a> { Ok(a_var) } + fn expect_field_ty_separator(&mut self) -> PResult<'a, ()> { + if let Err(mut err) = self.expect(&token::Colon) { + let sm = self.sess.source_map(); + let eq_typo = self.token.kind == token::Eq && self.look_ahead(1, |t| t.is_path_start()); + let semi_typo = self.token.kind == token::Semi + && self.look_ahead(1, |t| { + t.is_path_start() + // We check that we are in a situation like `foo; bar` to avoid bad suggestions + // when there's no type and `;` was used instead of a comma. + && match (sm.lookup_line(self.token.span.hi()), sm.lookup_line(t.span.lo())) { + (Ok(l), Ok(r)) => l.line == r.line, + _ => true, + } + }); + if eq_typo || semi_typo { + self.bump(); + // Gracefully handle small typos. + err.span_suggestion_short( + self.prev_token.span, + "field names and their types are separated with `:`", + ":".to_string(), + Applicability::MachineApplicable, + ); + err.emit(); + } else { + return Err(err); + } + } + Ok(()) + } + /// Parses a structure field. fn parse_name_and_ty( &mut self, @@ -1408,8 +1439,21 @@ impl<'a> Parser<'a> { attrs: Vec, ) -> PResult<'a, FieldDef> { let name = self.parse_field_ident(adt_ty, lo)?; - self.expect(&token::Colon)?; + self.expect_field_ty_separator()?; let ty = self.parse_ty()?; + if self.token.kind == token::Eq { + self.bump(); + let const_expr = self.parse_anon_const_expr()?; + let sp = ty.span.shrink_to_hi().to(const_expr.value.span); + self.struct_span_err(sp, "default values on `struct` fields aren't supported") + .span_suggestion( + sp, + "remove this unsupported default value", + String::new(), + Applicability::MachineApplicable, + ) + .emit(); + } Ok(FieldDef { span: lo.to(self.prev_token.span), ident: Some(name), diff --git a/src/doc/book b/src/doc/book index 50dd06cb71beb..55a26488ddefc 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 50dd06cb71beb27fdc0eebade5509cdcc1f821ed +Subproject commit 55a26488ddefc8433e73a2e8352d70f7a5c7fc2b diff --git a/src/doc/nomicon b/src/doc/nomicon index 8551afbb2ca6f..55de6fa3c1f33 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 8551afbb2ca6f5ea37fe58380318b209785e4e02 +Subproject commit 55de6fa3c1f331774da19472c9ee57d2ae9eb039 diff --git a/src/doc/reference b/src/doc/reference index d23f9da846961..5aa457bf1b54b 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit d23f9da8469617e6c81121d9fd123443df70595d +Subproject commit 5aa457bf1b54bd2cd5d4cf49797f29299bdf89a7 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index e0a721f5202e6..5f8c6da200ada 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit e0a721f5202e6d9bec0aff99f10e44480c0da9e7 +Subproject commit 5f8c6da200ada77760a2fe1096938ef58151c9a6 diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide index e72b43a64925c..1e6c7fbda4c45 160000 --- a/src/doc/rustc-dev-guide +++ b/src/doc/rustc-dev-guide @@ -1 +1 @@ -Subproject commit e72b43a64925ce053dc7830e21c1a57ba00499bd +Subproject commit 1e6c7fbda4c45e85adf63ff3f82fa9c870b1447f diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 99e96fdcf1eb4..ec04c94dc11f9 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -105,7 +105,7 @@ crate fn render( placeholder=\"Click or press ‘S’ to search, ‘?’ for more options…\" \ type=\"search\">\ \ - + \ FxHashMap { map.insert("theme-picker".to_owned(), 1); map.insert("theme-choices".to_owned(), 1); map.insert("settings-menu".to_owned(), 1); + map.insert("help-button".to_owned(), 1); map.insert("main".to_owned(), 1); map.insert("search".to_owned(), 1); map.insert("crate-search".to_owned(), 1); diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 8fd5d8b6b85b8..8676efd9fa8b2 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -137,8 +137,8 @@ impl SharedContext<'_> { Ok(()) } - /// Based on whether the `collapse-docs` pass was run, return either the `doc_value` or the - /// `collapsed_doc_value` of the given item. + /// Returns the `collapsed_doc_value` of the given item if this is the main crate, otherwise + /// returns the `doc_value`. crate fn maybe_collapsed_doc_value<'a>(&self, item: &'a clean::Item) -> Option { if self.collapsed { item.collapsed_doc_value() } else { item.doc_value() } } diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 04dc25341f4d3..8be08623b731a 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -381,56 +381,9 @@ function hideThemeButtonState() { } } - function highlightSourceLines(match, ev) { - if (typeof match === "undefined") { - // If we're in mobile mode, we should hide the sidebar in any case. - hideSidebar(); - match = window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/); - } - if (!match) { - return; - } - var from = parseInt(match[1], 10); - var to = from; - if (typeof match[2] !== "undefined") { - to = parseInt(match[2], 10); - } - if (to < from) { - var tmp = to; - to = from; - from = tmp; - } - var elem = document.getElementById(from); - if (!elem) { - return; - } - if (!ev) { - var x = document.getElementById(from); - if (x) { - x.scrollIntoView(); - } - } - onEachLazy(document.getElementsByClassName("line-numbers"), function(e) { - onEachLazy(e.getElementsByTagName("span"), function(i_e) { - removeClass(i_e, "line-highlighted"); - }); - }); - for (var i = from; i <= to; ++i) { - elem = document.getElementById(i); - if (!elem) { - break; - } - addClass(elem, "line-highlighted"); - } - } - function onHashChange(ev) { // If we're in mobile mode, we should hide the sidebar in any case. hideSidebar(); - var match = window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/); - if (match) { - return highlightSourceLines(match, ev); - } handleHashes(ev); } @@ -585,78 +538,9 @@ function hideThemeButtonState() { } } - function findParentElement(elem, tagName) { - do { - if (elem && elem.tagName === tagName) { - return elem; - } - elem = elem.parentNode; - } while (elem); - return null; - } - document.addEventListener("keypress", handleShortcut); document.addEventListener("keydown", handleShortcut); - var handleSourceHighlight = (function() { - var prev_line_id = 0; - - var set_fragment = function(name) { - var x = window.scrollX, - y = window.scrollY; - if (searchState.browserSupportsHistoryApi()) { - history.replaceState(null, null, "#" + name); - highlightSourceLines(); - } else { - location.replace("#" + name); - } - // Prevent jumps when selecting one or many lines - window.scrollTo(x, y); - }; - - return function(ev) { - var cur_line_id = parseInt(ev.target.id, 10); - ev.preventDefault(); - - if (ev.shiftKey && prev_line_id) { - // Swap selection if needed - if (prev_line_id > cur_line_id) { - var tmp = prev_line_id; - prev_line_id = cur_line_id; - cur_line_id = tmp; - } - - set_fragment(prev_line_id + "-" + cur_line_id); - } else { - prev_line_id = cur_line_id; - - set_fragment(cur_line_id); - } - }; - }()); - - document.addEventListener("click", function(ev) { - var helpElem = getHelpElement(false); - if (hasClass(ev.target, "help-button")) { - displayHelp(true, ev); - } else if (ev.target.tagName === "SPAN" && hasClass(ev.target.parentNode, "line-numbers")) { - handleSourceHighlight(ev); - } else if (helpElem && hasClass(helpElem, "hidden") === false) { - var is_inside_help_popup = ev.target !== helpElem && helpElem.contains(ev.target); - if (is_inside_help_popup === false) { - addClass(helpElem, "hidden"); - removeClass(document.body, "blur"); - } - } else { - // Making a collapsed element visible on onhashchange seems - // too late - var a = findParentElement(ev.target, "A"); - if (a && a.hash) { - expandSection(a.hash.replace(/^#/, "")); - } - } - }); - (function() { var x = document.getElementsByClassName("version-selector"); if (x.length > 0) { @@ -1121,6 +1005,27 @@ function hideThemeButtonState() { }); }()); + function handleClick(id, f) { + var elem = document.getElementById(id); + if (elem) { + elem.addEventListener("click", f); + } + } + handleClick("help-button", function(ev) { + displayHelp(true, ev); + }); + + onEachLazy(document.getElementsByTagName("a"), function(el) { + // For clicks on internal links ( tags with a hash property), we expand the section we're + // jumping to *before* jumping there. We can't do this in onHashChange, because it changes + // the height of the document so we wind up scrolled to the wrong place. + if (el.hash) { + el.addEventListener("click", function() { + expandSection(el.hash.slice(1)); + }); + } + }); + onEachLazy(document.getElementsByClassName("notable-traits"), function(e) { e.onclick = function() { this.getElementsByClassName('notable-traits-tooltiptext')[0] @@ -1165,6 +1070,13 @@ function hideThemeButtonState() { addClass(popup, "hidden"); popup.id = "help"; + popup.addEventListener("click", function(ev) { + if (ev.target === popup) { + // Clicked the blurred zone outside the help popup; dismiss help. + displayHelp(false, ev); + } + }); + var book_info = document.createElement("span"); book_info.innerHTML = "You can find more information in \ the rustdoc book."; @@ -1223,7 +1135,7 @@ function hideThemeButtonState() { } onHashChange(null); - window.onhashchange = onHashChange; + window.addEventListener("hashchange", onHashChange); searchState.setup(); }()); diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index aaa2525644f11..38afebc8d114b 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -371,6 +371,8 @@ nav.sub { border: 1px solid; padding: 13px 8px; text-align: right; + border-top-left-radius: 5px; + border-bottom-left-radius: 5px; } .rustdoc:not(.source) .example-wrap > pre.rust { @@ -398,8 +400,6 @@ nav.sub { -moz-user-select: none; -ms-user-select: none; user-select: none; - border-top-left-radius: 5px; - border-bottom-left-radius: 5px; } .line-numbers span { cursor: pointer; @@ -1289,7 +1289,7 @@ h4 > .notable-traits { outline: none; } -#settings-menu, .help-button { +#settings-menu, #help-button { position: absolute; top: 10px; } @@ -1299,7 +1299,7 @@ h4 > .notable-traits { outline: none; } -#theme-picker, #settings-menu, .help-button, #copy-path { +#theme-picker, #settings-menu, #help-button, #copy-path { padding: 4px; width: 27px; height: 29px; @@ -1308,7 +1308,7 @@ h4 > .notable-traits { cursor: pointer; } -.help-button { +#help-button { right: 30px; font-family: "Fira Sans", Arial, sans-serif; text-align: center; @@ -1593,7 +1593,7 @@ h4 > .notable-traits { } /* We don't display the help button on mobile devices. */ - .help-button { + #help-button { display: none; } .search-container > div { diff --git a/src/librustdoc/html/static/source-script.js b/src/librustdoc/html/static/source-script.js index 81df541189681..81cf437c7dbb0 100644 --- a/src/librustdoc/html/static/source-script.js +++ b/src/librustdoc/html/static/source-script.js @@ -3,6 +3,7 @@ // Local js definitions: /* global addClass, getCurrentValue, hasClass, removeClass, updateLocalStorage */ +(function() { function getCurrentFilePath() { var parts = window.location.pathname.split("/"); @@ -149,3 +150,99 @@ function createSourceSidebar() { selected_elem.focus(); } } + +var lineNumbersRegex = /^#?(\d+)(?:-(\d+))?$/; + +function highlightSourceLines(match, ev) { + if (typeof match === "undefined") { + match = window.location.hash.match(lineNumbersRegex); + } + if (!match) { + return; + } + var from = parseInt(match[1], 10); + var to = from; + if (typeof match[2] !== "undefined") { + to = parseInt(match[2], 10); + } + if (to < from) { + var tmp = to; + to = from; + from = tmp; + } + var elem = document.getElementById(from); + if (!elem) { + return; + } + if (!ev) { + var x = document.getElementById(from); + if (x) { + x.scrollIntoView(); + } + } + onEachLazy(document.getElementsByClassName("line-numbers"), function(e) { + onEachLazy(e.getElementsByTagName("span"), function(i_e) { + removeClass(i_e, "line-highlighted"); + }); + }); + for (var i = from; i <= to; ++i) { + elem = document.getElementById(i); + if (!elem) { + break; + } + addClass(elem, "line-highlighted"); + } +} + +var handleSourceHighlight = (function() { + var prev_line_id = 0; + + var set_fragment = function(name) { + var x = window.scrollX, + y = window.scrollY; + if (searchState.browserSupportsHistoryApi()) { + history.replaceState(null, null, "#" + name); + highlightSourceLines(); + } else { + location.replace("#" + name); + } + // Prevent jumps when selecting one or many lines + window.scrollTo(x, y); + }; + + return function(ev) { + var cur_line_id = parseInt(ev.target.id, 10); + ev.preventDefault(); + + if (ev.shiftKey && prev_line_id) { + // Swap selection if needed + if (prev_line_id > cur_line_id) { + var tmp = prev_line_id; + prev_line_id = cur_line_id; + cur_line_id = tmp; + } + + set_fragment(prev_line_id + "-" + cur_line_id); + } else { + prev_line_id = cur_line_id; + + set_fragment(cur_line_id); + } + }; +}()); + +window.addEventListener("hashchange", function() { + var match = window.location.hash.match(lineNumbersRegex); + if (match) { + return highlightSourceLines(match, ev); + } +}); + +onEachLazy(document.getElementsByClassName("line-numbers"), function(el) { + el.addEventListener("click", handleSourceHighlight); +}); + +highlightSourceLines(); + +window.createSourceSidebar = createSourceSidebar; +})(); diff --git a/src/librustdoc/html/static/themes/ayu.css b/src/librustdoc/html/static/themes/ayu.css index aafb7f6300ea4..08148fdcf9597 100644 --- a/src/librustdoc/html/static/themes/ayu.css +++ b/src/librustdoc/html/static/themes/ayu.css @@ -503,7 +503,7 @@ kbd { box-shadow-color: #c6cbd1; } -#theme-picker, #settings-menu, .help-button, #copy-path { +#theme-picker, #settings-menu, #help-button, #copy-path { border-color: #5c6773; background-color: #0f1419; color: #fff; @@ -515,7 +515,7 @@ kbd { #theme-picker:hover, #theme-picker:focus, #settings-menu:hover, #settings-menu:focus, -.help-button:hover, .help-button:focus, +#help-button:hover, #help-button:focus, #copy-path:hover, #copy-path:focus { border-color: #e0e0e0; } diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index 715605d7b3785..8ee51d39c9214 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -393,7 +393,7 @@ kbd { box-shadow-color: #c6cbd1; } -#theme-picker, #settings-menu, .help-button, #copy-path { +#theme-picker, #settings-menu, #help-button, #copy-path { border-color: #e0e0e0; background: #f0f0f0; color: #000; @@ -401,7 +401,7 @@ kbd { #theme-picker:hover, #theme-picker:focus, #settings-menu:hover, #settings-menu:focus, -.help-button:hover, .help-button:focus, +#help-button:hover, #help-button:focus, #copy-path:hover, #copy-path:focus { border-color: #ffb900; } diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index 60ed889879387..e0efcfe2249af 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -385,14 +385,14 @@ kbd { box-shadow-color: #c6cbd1; } -#theme-picker, #settings-menu, .help-button, #copy-path { +#theme-picker, #settings-menu, #help-button, #copy-path { border-color: #e0e0e0; background-color: #fff; } #theme-picker:hover, #theme-picker:focus, #settings-menu:hover, #settings-menu:focus, -.help-button:hover, .help-button:focus, +#help-button:hover, #help-button:focus, #copy-path:hover, #copy-path:focus { border-color: #717171; } diff --git a/src/test/ui/parser/struct-default-values-and-missing-field-separator.fixed b/src/test/ui/parser/struct-default-values-and-missing-field-separator.fixed new file mode 100644 index 0000000000000..28191b82621fd --- /dev/null +++ b/src/test/ui/parser/struct-default-values-and-missing-field-separator.fixed @@ -0,0 +1,35 @@ +// run-rustfix +#![allow(dead_code)] + +enum E { + A, +} + +struct S { + field1: i32, //~ ERROR default values on `struct` fields aren't supported + field2: E, //~ ERROR default values on `struct` fields aren't supported + field3: i32, //~ ERROR default values on `struct` fields aren't supported + field4: i32, //~ ERROR default values on `struct` fields aren't supported + field5: E, //~ ERROR default values on `struct` fields aren't supported + field6: E, //~ ERROR default values on `struct` fields aren't supported +} + +struct S1 { + field1: i32, //~ ERROR expected `,`, or `}`, found `field2` + field2: E, //~ ERROR expected `,`, or `}`, found `field3` + field3: i32, //~ ERROR default values on `struct` fields aren't supported + field4: i32, //~ ERROR default values on `struct` fields aren't supported + field5: E, //~ ERROR default values on `struct` fields aren't supported + field6: E, //~ ERROR default values on `struct` fields aren't supported +} + +struct S2 { + field1 : i32, //~ ERROR expected `:`, found `=` + field2: E, //~ ERROR expected `:`, found `;` +} + +const fn foo(_: i32) -> E { + E::A +} + +fn main() {} diff --git a/src/test/ui/parser/struct-default-values-and-missing-field-separator.rs b/src/test/ui/parser/struct-default-values-and-missing-field-separator.rs new file mode 100644 index 0000000000000..924cb08a990a5 --- /dev/null +++ b/src/test/ui/parser/struct-default-values-and-missing-field-separator.rs @@ -0,0 +1,35 @@ +// run-rustfix +#![allow(dead_code)] + +enum E { + A, +} + +struct S { + field1: i32 = 42, //~ ERROR default values on `struct` fields aren't supported + field2: E = E::A, //~ ERROR default values on `struct` fields aren't supported + field3: i32 = 1 + 2, //~ ERROR default values on `struct` fields aren't supported + field4: i32 = { 1 + 2 }, //~ ERROR default values on `struct` fields aren't supported + field5: E = foo(42), //~ ERROR default values on `struct` fields aren't supported + field6: E = { foo(42) }, //~ ERROR default values on `struct` fields aren't supported +} + +struct S1 { + field1: i32 //~ ERROR expected `,`, or `}`, found `field2` + field2: E //~ ERROR expected `,`, or `}`, found `field3` + field3: i32 = 1 + 2, //~ ERROR default values on `struct` fields aren't supported + field4: i32 = { 1 + 2 }, //~ ERROR default values on `struct` fields aren't supported + field5: E = foo(42), //~ ERROR default values on `struct` fields aren't supported + field6: E = { foo(42) }, //~ ERROR default values on `struct` fields aren't supported +} + +struct S2 { + field1 = i32, //~ ERROR expected `:`, found `=` + field2; E, //~ ERROR expected `:`, found `;` +} + +const fn foo(_: i32) -> E { + E::A +} + +fn main() {} diff --git a/src/test/ui/parser/struct-default-values-and-missing-field-separator.stderr b/src/test/ui/parser/struct-default-values-and-missing-field-separator.stderr new file mode 100644 index 0000000000000..7f16ebcfc3ace --- /dev/null +++ b/src/test/ui/parser/struct-default-values-and-missing-field-separator.stderr @@ -0,0 +1,92 @@ +error: default values on `struct` fields aren't supported + --> $DIR/struct-default-values-and-missing-field-separator.rs:9:16 + | +LL | field1: i32 = 42, + | ^^^^^ help: remove this unsupported default value + +error: default values on `struct` fields aren't supported + --> $DIR/struct-default-values-and-missing-field-separator.rs:10:14 + | +LL | field2: E = E::A, + | ^^^^^^^ help: remove this unsupported default value + +error: default values on `struct` fields aren't supported + --> $DIR/struct-default-values-and-missing-field-separator.rs:11:16 + | +LL | field3: i32 = 1 + 2, + | ^^^^^^^^ help: remove this unsupported default value + +error: default values on `struct` fields aren't supported + --> $DIR/struct-default-values-and-missing-field-separator.rs:12:16 + | +LL | field4: i32 = { 1 + 2 }, + | ^^^^^^^^^^^^ help: remove this unsupported default value + +error: default values on `struct` fields aren't supported + --> $DIR/struct-default-values-and-missing-field-separator.rs:13:14 + | +LL | field5: E = foo(42), + | ^^^^^^^^^^ help: remove this unsupported default value + +error: default values on `struct` fields aren't supported + --> $DIR/struct-default-values-and-missing-field-separator.rs:14:14 + | +LL | field6: E = { foo(42) }, + | ^^^^^^^^^^^^^^ help: remove this unsupported default value + +error: expected `,`, or `}`, found `field2` + --> $DIR/struct-default-values-and-missing-field-separator.rs:18:16 + | +LL | field1: i32 + | ^ help: try adding a comma: `,` + +error: expected `,`, or `}`, found `field3` + --> $DIR/struct-default-values-and-missing-field-separator.rs:19:14 + | +LL | field2: E + | ^ help: try adding a comma: `,` + +error: default values on `struct` fields aren't supported + --> $DIR/struct-default-values-and-missing-field-separator.rs:20:16 + | +LL | field3: i32 = 1 + 2, + | ^^^^^^^^ help: remove this unsupported default value + +error: default values on `struct` fields aren't supported + --> $DIR/struct-default-values-and-missing-field-separator.rs:21:16 + | +LL | field4: i32 = { 1 + 2 }, + | ^^^^^^^^^^^^ help: remove this unsupported default value + +error: default values on `struct` fields aren't supported + --> $DIR/struct-default-values-and-missing-field-separator.rs:22:14 + | +LL | field5: E = foo(42), + | ^^^^^^^^^^ help: remove this unsupported default value + +error: default values on `struct` fields aren't supported + --> $DIR/struct-default-values-and-missing-field-separator.rs:23:14 + | +LL | field6: E = { foo(42) }, + | ^^^^^^^^^^^^^^ help: remove this unsupported default value + +error: expected `:`, found `=` + --> $DIR/struct-default-values-and-missing-field-separator.rs:27:12 + | +LL | field1 = i32, + | ^ + | | + | expected `:` + | help: field names and their types are separated with `:` + +error: expected `:`, found `;` + --> $DIR/struct-default-values-and-missing-field-separator.rs:28:11 + | +LL | field2; E, + | ^ + | | + | expected `:` + | help: field names and their types are separated with `:` + +error: aborting due to 14 previous errors +