diff options
| author | bors <bors@rust-lang.org> | 2021-05-07 01:16:08 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-05-07 01:16:08 +0000 |
| commit | 1773f14a24c49356b384e45ebb45643bc9bef2c4 (patch) | |
| tree | e6ad409e4410a72f43101974b5a824e15fba28a5 /compiler/rustc_parse/src | |
| parent | 777bb2f6129e71a88ba030251eb370ef12fe28af (diff) | |
| parent | 01e9d09d3bbb35a1fbb0a2a353cfcf90a4feb050 (diff) | |
| download | rust-1773f14a24c49356b384e45ebb45643bc9bef2c4.tar.gz rust-1773f14a24c49356b384e45ebb45643bc9bef2c4.zip | |
Auto merge of #85014 - Dylan-DPC:rollup-jzpbkdu, r=Dylan-DPC
Rollup of 11 pull requests Successful merges: - #84409 (Ensure TLS destructors run before thread joins in SGX) - #84500 (Add --run flag to compiletest) - #84728 (Add test for suggestion to borrow unsized function parameters) - #84734 (Add `needs-unwind` and beginning of support for testing `panic=abort` std to compiletest) - #84755 (Allow using `core::` in intra-doc links within core itself) - #84871 (Disallows `#![feature(no_coverage)]` on stable and beta (using standard crate-level gating)) - #84872 (Wire up tidy dependency checks for cg_clif) - #84896 (Handle incorrect placement of parentheses in trait bounds more gracefully) - #84905 (CTFE engine: rename copy → copy_intrinsic, move to intrinsics.rs) - #84953 (Remove unneeded call to with_default_session_globals in rustdoc highlight) - #84987 (small nits) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_parse/src')
| -rw-r--r-- | compiler/rustc_parse/src/parser/ty.rs | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 0f7b8ebd376..d537741c749 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -470,7 +470,7 @@ impl<'a> Parser<'a> { /// Is a `dyn B0 + ... + Bn` type allowed here? fn is_explicit_dyn_type(&mut self) -> bool { self.check_keyword(kw::Dyn) - && (self.token.uninterpolated_span().rust_2018() + && (!self.token.uninterpolated_span().rust_2015() || self.look_ahead(1, |t| { t.can_begin_bound() && !can_continue_type_after_non_fn_ident(t) })) @@ -539,7 +539,21 @@ impl<'a> Parser<'a> { ) -> PResult<'a, GenericBounds> { let mut bounds = Vec::new(); let mut negative_bounds = Vec::new(); - while self.can_begin_bound() { + + while self.can_begin_bound() || self.token.is_keyword(kw::Dyn) { + if self.token.is_keyword(kw::Dyn) { + // Account for `&dyn Trait + dyn Other`. + self.struct_span_err(self.token.span, "invalid `dyn` keyword") + .help("`dyn` is only needed at the start of a trait `+`-separated list") + .span_suggestion( + self.token.span, + "remove this keyword", + String::new(), + Applicability::MachineApplicable, + ) + .emit(); + self.bump(); + } match self.parse_generic_bound()? { Ok(bound) => bounds.push(bound), Err(neg_sp) => negative_bounds.push(neg_sp), @@ -721,7 +735,26 @@ impl<'a> Parser<'a> { let lifetime_defs = self.parse_late_bound_lifetime_defs()?; let path = self.parse_path(PathStyle::Type)?; if has_parens { - self.expect(&token::CloseDelim(token::Paren))?; + if self.token.is_like_plus() { + // Someone has written something like `&dyn (Trait + Other)`. The correct code + // would be `&(dyn Trait + Other)`, but we don't have access to the appropriate + // span to suggest that. When written as `&dyn Trait + Other`, an appropriate + // suggestion is given. + let bounds = vec![]; + self.parse_remaining_bounds(bounds, true)?; + self.expect(&token::CloseDelim(token::Paren))?; + let sp = vec![lo, self.prev_token.span]; + let sugg: Vec<_> = sp.iter().map(|sp| (*sp, String::new())).collect(); + self.struct_span_err(sp, "incorrect braces around trait bounds") + .multipart_suggestion( + "remove the parentheses", + sugg, + Applicability::MachineApplicable, + ) + .emit(); + } else { + self.expect(&token::CloseDelim(token::Paren))?; + } } let modifier = modifiers.to_trait_bound_modifier(); |
