diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index a6e88f21ba74f..1868c739c34c1 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -192,11 +192,13 @@ impl<'a> AstValidator<'a> { self.disallow_tilde_const = old; } - fn check_type_alias_where_clause_location( + fn check_type_alias_where_clause_not_leading( &mut self, ty_alias: &TyAlias, ) -> Result<(), diagnostics::WhereClauseBeforeTypeAlias> { - if ty_alias.ty.is_none() || !ty_alias.generics.where_clause.has_where_token { + if !ty_alias.generics.where_clause.has_where_token + || ty_alias.ty.is_none() && !ty_alias.after_where_clause.has_where_token + { return Ok(()); } @@ -1722,7 +1724,7 @@ impl Visitor<'_> for AstValidator<'_> { self.check_type_no_bounds(bounds, "this context"); if self.features.checked_type_aliases() { - if let Err(err) = self.check_type_alias_where_clause_location(ty_alias) { + if let Err(err) = self.check_type_alias_where_clause_not_leading(ty_alias) { self.dcx().emit_err(err); } } else if after_where_clause.has_where_token { @@ -2106,7 +2108,7 @@ impl Visitor<'_> for AstValidator<'_> { } if let AssocItemKind::Type(ty_alias) = &item.kind - && let Err(err) = self.check_type_alias_where_clause_location(ty_alias) + && let Err(err) = self.check_type_alias_where_clause_not_leading(ty_alias) { let sugg = match err.sugg { diagnostics::WhereClauseBeforeTypeAliasSugg::Remove { .. } => None, diff --git a/compiler/rustc_parse/src/diagnostics.rs b/compiler/rustc_parse/src/diagnostics.rs index 72947b1c576c8..8bade53ef9ec2 100644 --- a/compiler/rustc_parse/src/diagnostics.rs +++ b/compiler/rustc_parse/src/diagnostics.rs @@ -2624,7 +2624,7 @@ pub(crate) struct MultipleWhereClauses { code = ",", applicability = "maybe-incorrect" )] - pub between: Span, + pub between: Option, } #[derive(Diagnostic)] @@ -4088,7 +4088,7 @@ pub(crate) struct StaticWithGenerics { #[derive(Diagnostic)] #[diag("where clauses are not allowed before const item bodies")] -pub(crate) struct WhereClauseBeforeConstBody { +pub(crate) struct WhereClauseBeforeConstItemBody { #[primary_span] #[label("unexpected where clause")] pub span: Span, diff --git a/compiler/rustc_parse/src/parser/function.rs b/compiler/rustc_parse/src/parser/function.rs index 443c7fae43a0a..c72ff5e5457b7 100644 --- a/compiler/rustc_parse/src/parser/function.rs +++ b/compiler/rustc_parse/src/parser/function.rs @@ -12,6 +12,7 @@ use thin_vec::ThinVec; use tracing::debug; use super::diagnostics::dummy_arg; +use super::generics::RecoverDupeWhereClause; use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign}; use super::{ ExpKeywordPair, FollowedByType, ForceCollect, Parser, Recovered, Trailing, UsePreAttrPos, @@ -123,8 +124,9 @@ impl<'a> Parser<'a> { fn_parse_mode: FnParseMode, sig_lo: Span, vis: &Visibility, + defaultness: Defaultness, case: Case, - ) -> PResult<'a, (Ident, FnSig, Generics, Option>, Option>)> { + ) -> PResult<'a, ItemKind> { let fn_span = self.token.span; let header = self.parse_fn_front_matter(vis, case, FrontMatterParsingMode::Function)?; // `const ... fn` let ident = self.parse_ident()?; // `foo` @@ -151,7 +153,7 @@ impl<'a> Parser<'a> { let contract = self.parse_contract()?; - generics.where_clause = self.parse_where_clause()?; // `where T: Ord` + generics.where_clause = self.parse_where_clause(RecoverDupeWhereClause::Yes)?; // `where T: Ord` // `fn_params_end` is needed only when it's followed by a where clause. let fn_params_end = @@ -161,8 +163,17 @@ impl<'a> Parser<'a> { // Either `;` or `{ ... }`. let body = self.parse_fn_body(attrs, &ident, &mut sig_hi, fn_parse_mode.req_body, fn_params_end)?; - let fn_sig_span = sig_lo.to(sig_hi); - Ok((ident, FnSig { header, decl, span: fn_sig_span }, generics, contract, body)) + + Ok(ItemKind::Fn(Box::new(Fn { + defaultness, + ident, + sig: FnSig { header, decl, span: sig_lo.to(sig_hi) }, + generics, + contract, + body, + define_opaque: None, + eii_impl: None, + }))) } /// Provide diagnostics when function body is not found diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index 8dc679c3e62ca..ce84446d986c1 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -14,6 +14,11 @@ use crate::diagnostics::{ }; use crate::exp; +pub(super) enum RecoverDupeWhereClause { + Yes, + No, +} + enum PredicateKindOrStructBody { PredicateKind(ast::WherePredicateKind), StructBody(ThinVec), @@ -395,8 +400,11 @@ impl<'a> Parser<'a> { /// ```ignore (only-for-syntax-highlight) /// where T : Trait + 'b, 'a : 'b /// ``` - pub(super) fn parse_where_clause(&mut self) -> PResult<'a, WhereClause> { - self.parse_where_clause_common(None).map(|(clause, _)| clause) + pub(super) fn parse_where_clause( + &mut self, + recover_dupe: RecoverDupeWhereClause, + ) -> PResult<'a, WhereClause> { + self.parse_where_clause_common(None, recover_dupe).map(|(clause, _)| clause) } pub(super) fn parse_struct_where_clause( @@ -404,12 +412,16 @@ impl<'a> Parser<'a> { struct_name: Ident, body_insertion_point: Span, ) -> PResult<'a, (WhereClause, Option>)> { - self.parse_where_clause_common(Some((struct_name, body_insertion_point))) + self.parse_where_clause_common( + Some((struct_name, body_insertion_point)), + RecoverDupeWhereClause::Yes, + ) } fn parse_where_clause_common( &mut self, struct_: Option<(Ident, Span)>, + recover_dupe: RecoverDupeWhereClause, ) -> PResult<'a, (WhereClause, Option>)> { if !self.eat_keyword(exp!(Where)) { return Ok(( @@ -446,7 +458,7 @@ impl<'a> Parser<'a> { } let (predicates, tuple_struct_body) = - self.parse_where_clause_predicates(struct_, where_lo)?; + self.parse_where_clause_predicates(struct_, where_lo, recover_dupe)?; let where_clause = WhereClause { has_where_token: true, predicates, @@ -459,6 +471,7 @@ impl<'a> Parser<'a> { &mut self, struct_: Option<(Ident, Span)>, where_lo: Span, + recover_dupe: RecoverDupeWhereClause, ) -> PResult<'a, (ThinVec, Option>)> { let mut predicates = ThinVec::new(); let mut tuple_struct_body = None; @@ -514,19 +527,23 @@ impl<'a> Parser<'a> { }); Ok((predicate, Trailing::No, UsePreAttrPos::No)) })?; - match predicate { - Some(predicate) => predicates.push(predicate), - None => break, + + let has_parsed_pred = predicate.is_some(); + if let Some(pred) = predicate { + predicates.push(pred); } - let prev_token = self.prev_token.span; - let ate_comma = self.eat(exp!(Comma)); + let pred_hi = self.prev_token.span; + let ate_comma = has_parsed_pred && self.eat(exp!(Comma)); - if self.eat_keyword_noexpect(kw::Where) { + if let RecoverDupeWhereClause::Yes = recover_dupe + && self.eat_keyword_noexpect(kw::Where) + { self.dcx().emit_err(MultipleWhereClauses { - span: self.token.span, - previous: pred_lo, - between: prev_token.shrink_to_hi().to(self.prev_token.span), + span: self.prev_token.span, + previous: where_sp, + between: has_parsed_pred + .then(|| pred_hi.shrink_to_hi().to(self.prev_token.span)), }); } else if !ate_comma { break; diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 27646bac1c21e..e525dfc3dc29e 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -17,6 +17,7 @@ use thin_vec::{ThinVec, thin_vec}; use tracing::debug; use super::diagnostics::ConsumeClosingDelim; +use super::generics::RecoverDupeWhereClause; use super::{ AllowConstBlockItems, AttrWrapper, ExpTokenPair, FnContext, FnParseMode, FollowedByType, ForceCollect, IsDotDotDot, Parser, PathStyle, Recovered, Trailing, UsePreAttrPos, @@ -277,18 +278,7 @@ impl<'a> Parser<'a> { self.psess.gated_spans.gate(sym::min_specialization, span); self.psess.gated_spans.ungate_last(sym::specialization, span); } - let (ident, sig, generics, contract, body) = - self.parse_fn(attrs, fn_parse_mode, lo, vis, case)?; - ItemKind::Fn(Box::new(Fn { - defaultness, - ident, - sig, - generics, - contract, - body, - define_opaque: None, - eii_impl: None, - })) + self.parse_fn(attrs, fn_parse_mode, lo, vis, defaultness, case)? } else if self.eat_keyword_case(exp!(Extern), case) { if self.eat_keyword_case(exp!(Crate), case) { // EXTERN CRATE @@ -325,15 +315,7 @@ impl<'a> Parser<'a> { // CONST ITEM self.recover_const_mut(const_span); self.recover_missing_kw_before_item()?; - let (ident, generics, ty, body) = self.parse_const_item(const_span)?; - ItemKind::Const(Box::new(ConstItem { - defaultness: def_(), - ident, - generics, - ty, - body, - define_opaque: None, - })) + self.parse_const_item(const_span, def_())? } else if let Some(kind) = self.is_reuse_item() { self.parse_item_delegation(attrs, def_(), kind)? } else if self.check_keyword_case(exp!(Mod), case) @@ -764,7 +746,7 @@ impl<'a> Parser<'a> { None }; - generics.where_clause = self.parse_where_clause()?; + generics.where_clause = self.parse_where_clause(RecoverDupeWhereClause::Yes)?; let impl_items = if is_reuse { Default::default() @@ -1192,7 +1174,7 @@ impl<'a> Parser<'a> { } let bounds = self.parse_generic_bounds()?; - generics.where_clause = self.parse_where_clause()?; + generics.where_clause = self.parse_where_clause(RecoverDupeWhereClause::Yes)?; self.expect_semi()?; let whole_span = lo.to(self.prev_token.span); @@ -1212,7 +1194,7 @@ impl<'a> Parser<'a> { Ok(ItemKind::TraitAlias(Box::new(TraitAlias { constness, ident, generics, bounds }))) } else { // It's a normal trait. - generics.where_clause = self.parse_where_clause()?; + generics.where_clause = self.parse_where_clause(RecoverDupeWhereClause::Yes)?; let items = self.parse_item_list(attrs, |p| p.parse_trait_item(ForceCollect::No))?; Ok(ItemKind::Trait(Box::new(Trait { impl_restriction, @@ -1305,14 +1287,16 @@ impl<'a> Parser<'a> { let ident = self.parse_ident()?; let mut generics = self.parse_generics()?; - // Parse optional colon and param bounds. let bounds = if self.eat(exp!(Colon)) { self.parse_generic_bounds()? } else { ThinVec::new() }; - generics.where_clause = self.parse_where_clause()?; + + // As a consequence of type aliases being allowed to have two where clauses & + // an optional body, we *must not* artificially reject duplicate where clauses! + generics.where_clause = self.parse_where_clause(RecoverDupeWhereClause::No)?; let ty = if self.eat(exp!(Eq)) { Some(self.parse_ty()?) } else { None }; - let after_where_clause = self.parse_where_clause()?; + let after_where_clause = self.parse_where_clause(RecoverDupeWhereClause::Yes)?; self.expect_semi()?; @@ -1766,20 +1750,17 @@ impl<'a> Parser<'a> { /// Parse a constant item with the prefix `"const"` already parsed. /// - /// If `const_arg` is true, any expression assigned to the const will be parsed - /// as a const_arg instead of a body expression. - /// /// ```ebnf /// Const = "const" ($ident | "_") Generics ":" $ty (= $expr)? WhereClause ";" ; /// ``` fn parse_const_item( &mut self, const_span: Span, - ) -> PResult<'a, (Ident, Generics, Box, Option>)> { + defaultness: Defaultness, + ) -> PResult<'a, ItemKind> { let ident = self.parse_ident_or_underscore()?; let mut generics = self.parse_generics()?; - // Check the span for emptiness instead of the list of parameters in order to correctly // recognize and subsequently flag empty parameter lists (`<>`) as unstable. if !generics.span.is_empty() { @@ -1787,7 +1768,6 @@ impl<'a> Parser<'a> { } // Parse the type of a constant item. That is, the `":" $ty` fragment. - // FIXME: This could maybe benefit from `.may_recover()`? let ty = match ( self.eat(exp!(Colon)), self.check(exp!(Eq)) | self.check(exp!(Semi)) | self.check_keyword(exp!(Where)), @@ -1798,71 +1778,69 @@ impl<'a> Parser<'a> { }; // Proactively parse a where-clause to be able to provide a good error message in case we - // encounter the item body following it. - let before_where_clause = - if self.may_recover() { self.parse_where_clause()? } else { WhereClause::default() }; + // encounter the item body following it. We rely on the "duplicate where clause" parse + // error recovery code to reject duplicate where clauses when there's no body. + let mut before_where_clause = self.parse_where_clause(RecoverDupeWhereClause::Yes)?; - let rhs = if self.eat(exp!(Eq)) { Some(self.parse_expr()?) } else { None }; + let body = if self.eat(exp!(Eq)) { Some(self.parse_expr()?) } else { None }; - let after_where_clause = self.parse_where_clause()?; + let after_where_clause = self.parse_where_clause(RecoverDupeWhereClause::Yes)?; // Provide a nice error message if the user placed a where-clause before the item body. // Users may be tempted to write such code if they are still used to the deprecated // where-clause location on type aliases and associated types. See also #89122. if before_where_clause.has_where_token - && let Some(rhs) = &rhs + && let Some(body) = &body { - self.dcx().emit_err(diagnostics::WhereClauseBeforeConstBody { + self.dcx().emit_err(diagnostics::WhereClauseBeforeConstItemBody { span: before_where_clause.span, name: ident.span, - body: rhs.span, + body: body.span, sugg: if !after_where_clause.has_where_token { - self.psess.source_map().span_to_snippet(rhs.span).ok().map(|body_s| { + self.psess.source_map().span_to_snippet(body.span).ok().map(|body_s| { diagnostics::WhereClauseBeforeConstBodySugg { left: before_where_clause.span.shrink_to_lo(), snippet: body_s, - right: before_where_clause.span.shrink_to_hi().to(rhs.span), + right: before_where_clause.span.shrink_to_hi().to(body.span), } }) } else { - // FIXME(generic_const_items): Provide a structured suggestion to merge the first - // where-clause into the second one. + // FIXME(generic_const_items): Provide a structured suggestion to merge the + // first where-clause into the second one. None }, }); } - // Merge the predicates of both where-clauses since either one can be relevant. - // If we didn't parse a body (which is valid for associated consts in traits) and we were - // allowed to recover, `before_where_clause` contains the predicates, otherwise they are - // in `after_where_clause`. Further, both of them might contain predicates iff two - // where-clauses were provided which is syntactically ill-formed but we want to recover from - // it and treat them as one large where-clause. - let mut predicates = before_where_clause.predicates; - predicates.extend(after_where_clause.predicates); - let where_clause = WhereClause { - has_where_token: before_where_clause.has_where_token - || after_where_clause.has_where_token, - predicates, - span: if after_where_clause.has_where_token { - after_where_clause.span - } else { - before_where_clause.span - }, - }; - - if where_clause.has_where_token { - self.psess.gated_spans.gate(sym::generic_const_items, where_clause.span); + // Merge the predicates of both where-clauses since either one can be relevant. If we didn't + // parse a body, `before_where_clause` will contain *the* predicates, otherwise they are in + // `after_where_clause`. + before_where_clause.has_where_token |= after_where_clause.has_where_token; + before_where_clause.predicates.extend(after_where_clause.predicates); + if after_where_clause.has_where_token { + before_where_clause.span = after_where_clause.span; } + generics.where_clause = before_where_clause; - generics.where_clause = where_clause; - - if let Some(rhs) = self.try_recover_const_missing_semi(&rhs, const_span) { - return Ok((ident, generics, ty, Some(rhs))); + if generics.where_clause.has_where_token { + self.psess.gated_spans.gate(sym::generic_const_items, generics.where_clause.span); } - self.expect_semi()?; - Ok((ident, generics, ty, rhs)) + let body = if let body @ Some(_) = self.try_recover_const_missing_semi(&body, const_span) { + body + } else { + self.expect_semi()?; + body + }; + + Ok(ItemKind::Const(Box::new(ConstItem { + defaultness, + ident, + generics, + ty, + body, + define_opaque: None, + }))) } /// We were supposed to parse `":" $ty` but the `:` or the type was missing. @@ -1910,7 +1888,7 @@ impl<'a> Parser<'a> { let prev_span = self.prev_token.span; let ident = self.parse_ident()?; let mut generics = self.parse_generics()?; - generics.where_clause = self.parse_where_clause()?; + generics.where_clause = self.parse_where_clause(RecoverDupeWhereClause::Yes)?; // Possibly recover `enum Foo;` instead of `enum Foo {}` let (variants, _) = if self.token == TokenKind::Semi { @@ -2103,7 +2081,7 @@ impl<'a> Parser<'a> { // Tuple-style struct definition with optional where-clause. } else if self.token == token::OpenParen { let body = VariantData::Tuple(self.parse_tuple_struct_body()?, DUMMY_NODE_ID); - generics.where_clause = self.parse_where_clause()?; + generics.where_clause = self.parse_where_clause(RecoverDupeWhereClause::Yes)?; self.expect_semi()?; body } else { @@ -2121,7 +2099,7 @@ impl<'a> Parser<'a> { let mut generics = self.parse_generics()?; let vdata = if self.token.is_keyword(kw::Where) { - generics.where_clause = self.parse_where_clause()?; + generics.where_clause = self.parse_where_clause(RecoverDupeWhereClause::Yes)?; let (fields, recovered) = self.parse_record_struct_body( "union", ident.span, @@ -2533,6 +2511,7 @@ impl<'a> Parser<'a> { fn_parse_mode, lo, &inherited_vis, + Defaultness::Implicit, Case::Insensitive, ) { Ok(_) => self @@ -2719,7 +2698,7 @@ impl<'a> Parser<'a> { pub fn parse_test_binder_constraints(&mut self) -> PResult<'a, Box> { self.expect_keyword(exp!(Impl))?; let mut generics = self.parse_generics()?; - generics.where_clause = self.parse_where_clause()?; + generics.where_clause = self.parse_where_clause(RecoverDupeWhereClause::Yes)?; let body = self.parse_test_binder_body()?; Ok(Box::new(TestBinderConstraints { generics, body: Box::new(body) })) } @@ -2732,12 +2711,9 @@ impl<'a> Parser<'a> { Some((Ident { name: sym::predicates, .. }, IdentKind::Normal)) => { let span = this.token.span; this.bump(); - items.extend( - this.parse_where_clause_predicates(None, span)? - .0 - .into_iter() - .map(TestBinderItem::Predicate), - ); + let (preds, _) = + this.parse_where_clause_predicates(None, span, RecoverDupeWhereClause::No)?; + items.extend(preds.into_iter().map(TestBinderItem::Predicate)); } Some((Ident { name: sym::forall, .. }, IdentKind::Normal)) => { items.push(TestBinderItem::Forall(this.parse_test_binder_forall()?)); @@ -2771,7 +2747,7 @@ impl<'a> Parser<'a> { self.bump(); let mut generics = self.parse_generics()?; - generics.where_clause = self.parse_where_clause()?; + generics.where_clause = self.parse_where_clause(RecoverDupeWhereClause::Yes)?; let body = self.parse_test_binder_body()?; diff --git a/tests/ui/generic-const-items/duplicate-where-clause.rs b/tests/ui/generic-const-items/duplicate-where-clause.rs index 68da4073fc1f0..96bf536f70e98 100644 --- a/tests/ui/generic-const-items/duplicate-where-clause.rs +++ b/tests/ui/generic-const-items/duplicate-where-clause.rs @@ -1,13 +1,11 @@ #![feature(generic_const_items)] -#![allow(incomplete_features)] trait Tr

{ const K: () where P: Copy - where + where //~ ERROR cannot define duplicate `where` clauses on an item P: Eq; - //~^ ERROR cannot define duplicate `where` clauses on an item } // Test that we error on the first where-clause but also that we don't suggest to swap it with the @@ -24,4 +22,8 @@ impl

Tr

for () { //~^^^^^ ERROR where clauses are not allowed before const item bodies } +// We once used to accidentally accept this: +#[cfg(false)] +const _: () where where; //~ ERROR cannot define duplicate `where` clauses on an item + fn main() {} diff --git a/tests/ui/generic-const-items/duplicate-where-clause.stderr b/tests/ui/generic-const-items/duplicate-where-clause.stderr index 6b742dfafedaa..76751a3ede14c 100644 --- a/tests/ui/generic-const-items/duplicate-where-clause.stderr +++ b/tests/ui/generic-const-items/duplicate-where-clause.stderr @@ -1,11 +1,11 @@ error: cannot define duplicate `where` clauses on an item - --> $DIR/duplicate-where-clause.rs:9:9 + --> $DIR/duplicate-where-clause.rs:7:5 | +LL | where + | ----- previous `where` clause starts here LL | P: Copy - | - previous `where` clause starts here LL | where -LL | P: Eq; - | ^ + | ^^^^^ | help: consider joining the two `where` clauses into one | @@ -15,7 +15,7 @@ LL + P: Copy, | error: where clauses are not allowed before const item bodies - --> $DIR/duplicate-where-clause.rs:19:5 + --> $DIR/duplicate-where-clause.rs:17:5 | LL | const K: () | - while parsing this const item @@ -25,5 +25,13 @@ LL | | P: Eq LL | = () | -- the item body -error: aborting due to 2 previous errors +error: cannot define duplicate `where` clauses on an item + --> $DIR/duplicate-where-clause.rs:27:19 + | +LL | const _: () where where; + | ----- ^^^^^ + | | + | previous `where` clause starts here + +error: aborting due to 3 previous errors diff --git a/tests/ui/parser/bounds-lifetime-where.rs b/tests/ui/parser/bounds-lifetime-where.rs deleted file mode 100644 index 730be7139bec8..0000000000000 --- a/tests/ui/parser/bounds-lifetime-where.rs +++ /dev/null @@ -1,10 +0,0 @@ -type A where 'a: 'b + 'c = u8; // OK -type A where 'a: 'b, = u8; // OK -type A where 'a: = u8; // OK -type A where 'a:, = u8; // OK -type A where 'a: 'b + 'c = u8; // OK -type A where = u8; // OK -type A where 'a: 'b + = u8; // OK -type A where , = u8; //~ ERROR expected one of `#`, `;`, `=`, `where`, lifetime, or type, found `,` - -fn main() {} diff --git a/tests/ui/parser/bounds-lifetime-where.stderr b/tests/ui/parser/bounds-lifetime-where.stderr deleted file mode 100644 index 5aadb5fff320b..0000000000000 --- a/tests/ui/parser/bounds-lifetime-where.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: expected one of `#`, `;`, `=`, `where`, lifetime, or type, found `,` - --> $DIR/bounds-lifetime-where.rs:8:14 - | -LL | type A where , = u8; - | ^ expected one of `#`, `;`, `=`, `where`, lifetime, or type - -error: aborting due to 1 previous error - diff --git a/tests/ui/parser/bounds-type-where.rs b/tests/ui/parser/bounds-type-where.rs deleted file mode 100644 index 2520ecb294c9a..0000000000000 --- a/tests/ui/parser/bounds-type-where.rs +++ /dev/null @@ -1,11 +0,0 @@ -type A where for<'a> for<'b> Trait1 + ?Trait2: 'a + Trait = u8; // OK -type A where T: Trait, = u8; // OK -type A where T: = u8; // OK -type A where T:, = u8; // OK -type A where T: Trait + Trait = u8; // OK -type A where = u8; // OK -type A where T: Trait + = u8; // OK -type A where T, = u8; -//~^ ERROR expected one of `!`, `(`, `+`, `::`, `:`, `<`, `==`, or `=`, found `,` - -fn main() {} diff --git a/tests/ui/parser/bounds-type-where.stderr b/tests/ui/parser/bounds-type-where.stderr deleted file mode 100644 index 709d31430984b..0000000000000 --- a/tests/ui/parser/bounds-type-where.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: expected one of `!`, `(`, `+`, `::`, `:`, `<`, `==`, or `=`, found `,` - --> $DIR/bounds-type-where.rs:8:15 - | -LL | type A where T, = u8; - | ^ expected one of 8 possible tokens - -error: aborting due to 1 previous error - diff --git a/tests/ui/parser/duplicate-where-clauses.rs b/tests/ui/parser/duplicate-where-clauses.rs index 9eb2ffb06f02d..695456fe52806 100644 --- a/tests/ui/parser/duplicate-where-clauses.rs +++ b/tests/ui/parser/duplicate-where-clauses.rs @@ -16,4 +16,11 @@ fn e() where (): Sized, where (): Sized {} enum F where (): Sized, where (): Sized {} //~^ ERROR cannot define duplicate `where` clauses on an item +// For type aliases, two are fine but >two are not. +#[cfg(false)] +type G +where (): Sized +where (): Sized // OK +where (): Sized; //~ ERROR cannot define duplicate `where` clauses on an item + fn main() {} diff --git a/tests/ui/parser/duplicate-where-clauses.stderr b/tests/ui/parser/duplicate-where-clauses.stderr index 298cdab0c68c3..26968ec9db593 100644 --- a/tests/ui/parser/duplicate-where-clauses.stderr +++ b/tests/ui/parser/duplicate-where-clauses.stderr @@ -1,10 +1,10 @@ error: cannot define duplicate `where` clauses on an item - --> $DIR/duplicate-where-clauses.rs:1:32 + --> $DIR/duplicate-where-clauses.rs:1:26 | LL | struct A where (): Sized where (): Sized {} - | - ^ - | | - | previous `where` clause starts here + | ----- ^^^^^ + | | + | previous `where` clause starts here | help: consider joining the two `where` clauses into one | @@ -13,12 +13,12 @@ LL + struct A where (): Sized, (): Sized {} | error: cannot define duplicate `where` clauses on an item - --> $DIR/duplicate-where-clauses.rs:4:30 + --> $DIR/duplicate-where-clauses.rs:4:24 | LL | fn b() where (): Sized where (): Sized {} - | - ^ - | | - | previous `where` clause starts here + | ----- ^^^^^ + | | + | previous `where` clause starts here | help: consider joining the two `where` clauses into one | @@ -27,12 +27,12 @@ LL + fn b() where (): Sized, (): Sized {} | error: cannot define duplicate `where` clauses on an item - --> $DIR/duplicate-where-clauses.rs:7:30 + --> $DIR/duplicate-where-clauses.rs:7:24 | LL | enum C where (): Sized where (): Sized {} - | - ^ - | | - | previous `where` clause starts here + | ----- ^^^^^ + | | + | previous `where` clause starts here | help: consider joining the two `where` clauses into one | @@ -41,12 +41,12 @@ LL + enum C where (): Sized, (): Sized {} | error: cannot define duplicate `where` clauses on an item - --> $DIR/duplicate-where-clauses.rs:10:33 + --> $DIR/duplicate-where-clauses.rs:10:27 | LL | struct D where (): Sized, where (): Sized {} - | - ^ - | | - | previous `where` clause starts here + | ----- ^^^^^ + | | + | previous `where` clause starts here | help: consider joining the two `where` clauses into one | @@ -55,12 +55,12 @@ LL + struct D where (): Sized, (): Sized {} | error: cannot define duplicate `where` clauses on an item - --> $DIR/duplicate-where-clauses.rs:13:31 + --> $DIR/duplicate-where-clauses.rs:13:25 | LL | fn e() where (): Sized, where (): Sized {} - | - ^ - | | - | previous `where` clause starts here + | ----- ^^^^^ + | | + | previous `where` clause starts here | help: consider joining the two `where` clauses into one | @@ -69,12 +69,12 @@ LL + fn e() where (): Sized, (): Sized {} | error: cannot define duplicate `where` clauses on an item - --> $DIR/duplicate-where-clauses.rs:16:31 + --> $DIR/duplicate-where-clauses.rs:16:25 | LL | enum F where (): Sized, where (): Sized {} - | - ^ - | | - | previous `where` clause starts here + | ----- ^^^^^ + | | + | previous `where` clause starts here | help: consider joining the two `where` clauses into one | @@ -82,5 +82,20 @@ LL - enum F where (): Sized, where (): Sized {} LL + enum F where (): Sized, (): Sized {} | -error: aborting due to 6 previous errors +error: cannot define duplicate `where` clauses on an item + --> $DIR/duplicate-where-clauses.rs:24:1 + | +LL | where (): Sized // OK + | ----- previous `where` clause starts here +LL | where (): Sized; + | ^^^^^ + | +help: consider joining the two `where` clauses into one + | +LL - where (): Sized // OK +LL - where (): Sized; +LL + where (): Sized, (): Sized; + | + +error: aborting due to 7 previous errors diff --git a/tests/ui/parser/where-clause-predicates.rs b/tests/ui/parser/where-clause-predicates.rs new file mode 100644 index 0000000000000..99234889dbd7f --- /dev/null +++ b/tests/ui/parser/where-clause-predicates.rs @@ -0,0 +1,26 @@ +// Exercise the parsing of the "bounds" (predicates) that are found in where clauses. +// +// Check that we allow zero bounds after `:`, zero predicates after `where`, +// trailing `,` in predicate lists & trailing `+` in bound lists. +// +//@ compile-flags: -Zparse-crate-root-only + +type A where for<'a> for<'b> Trait1 + ?Trait2: 'a + Trait = u8; // OK +type A where T: Trait, = u8; // OK +type A where T: = u8; // OK +type A where T:, = u8; // OK +type A where T: Trait + Trait = u8; // OK +type A where = u8; // OK +type A where T: Trait + = u8; // OK +fn barrier() { type A where T, = u8; } +//~^ ERROR expected one of `!`, `(`, `+`, `::`, `:`, `<`, `==`, or `=`, found `,` + +type A where 'a: 'b + 'c = u8; // OK +type A where 'a: 'b, = u8; // OK +type A where 'a: = u8; // OK +type A where 'a:, = u8; // OK +type A where 'a: 'b + 'c = u8; // OK +type A where = u8; // OK +type A where 'a: 'b + = u8; // OK +fn barrier() { type A where , = u8; } +//~^ ERROR expected one of `#`, `;`, `=`, `where`, lifetime, or type, found `,` diff --git a/tests/ui/parser/where-clause-predicates.stderr b/tests/ui/parser/where-clause-predicates.stderr new file mode 100644 index 0000000000000..039130a971167 --- /dev/null +++ b/tests/ui/parser/where-clause-predicates.stderr @@ -0,0 +1,14 @@ +error: expected one of `!`, `(`, `+`, `::`, `:`, `<`, `==`, or `=`, found `,` + --> $DIR/where-clause-predicates.rs:15:30 + | +LL | fn barrier() { type A where T, = u8; } + | ^ expected one of 8 possible tokens + +error: expected one of `#`, `;`, `=`, `where`, lifetime, or type, found `,` + --> $DIR/where-clause-predicates.rs:25:29 + | +LL | fn barrier() { type A where , = u8; } + | ^ expected one of `#`, `;`, `=`, `where`, lifetime, or type + +error: aborting due to 2 previous errors + diff --git a/tests/ui/type/type-alias-bounds.rs b/tests/ui/type/type-alias-bounds.rs index 37c073fe1f95d..d34422168e063 100644 --- a/tests/ui/type/type-alias-bounds.rs +++ b/tests/ui/type/type-alias-bounds.rs @@ -1,4 +1,4 @@ -// Test `ignored_generic_bounds` lint warning about bounds in type aliases. +// Test lint `type_alias_bounds` that's about bounds in type aliases. //@ check-pass #![allow(dead_code)] diff --git a/tests/ui/where-clauses/alias-type-where-suggest-issue-153567.fixed b/tests/ui/where-clauses/alias-type-where-suggest-issue-153567.fixed deleted file mode 100644 index 01da73716e884..0000000000000 --- a/tests/ui/where-clauses/alias-type-where-suggest-issue-153567.fixed +++ /dev/null @@ -1,17 +0,0 @@ -//@ check-pass -//@ run-rustfix -//@ compile-flags: --force-warn deprecated_where_clause_location - - -#![allow(dead_code)] - -trait Trait { - type Assoc; -} - -impl Trait for i32 { - type Assoc = () where i32: Copy; - //~^ WARNING where clause not allowed here -} - -fn main() {} diff --git a/tests/ui/where-clauses/alias-type-where-suggest-issue-153567.rs b/tests/ui/where-clauses/alias-type-where-suggest-issue-153567.rs deleted file mode 100644 index cdee4c753b87d..0000000000000 --- a/tests/ui/where-clauses/alias-type-where-suggest-issue-153567.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ check-pass -//@ run-rustfix -//@ compile-flags: --force-warn deprecated_where_clause_location - - -#![allow(dead_code)] - -trait Trait { - type Assoc; -} - -impl Trait for i32 { - type Assoc where i32: Copy = () where; - //~^ WARNING where clause not allowed here -} - -fn main() {} diff --git a/tests/ui/where-clauses/alias-type-where-suggest-issue-153567.stderr b/tests/ui/where-clauses/alias-type-where-suggest-issue-153567.stderr deleted file mode 100644 index d3421505bf5ca..0000000000000 --- a/tests/ui/where-clauses/alias-type-where-suggest-issue-153567.stderr +++ /dev/null @@ -1,16 +0,0 @@ -warning: where clause not allowed here - --> $DIR/alias-type-where-suggest-issue-153567.rs:13:16 - | -LL | type Assoc where i32: Copy = () where; - | ^^^^^^^^^^^^^^^ - | - = note: see issue #89122 for more information - = note: requested on the command line with `--force-warn deprecated-where-clause-location` -help: move it to the end of the type declaration - | -LL - type Assoc where i32: Copy = () where; -LL + type Assoc = () where i32: Copy; - | - -warning: 1 warning emitted - diff --git a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.fixed b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.fixed index 5f3882ccb412e..3671dd45b1c7b 100644 --- a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.fixed +++ b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.fixed @@ -1,3 +1,6 @@ +// Ensure that we permit leading where clauses on associated types in traits +// (for backward compatibility) and lint on them. + //@ check-pass //@ run-rustfix @@ -8,8 +11,8 @@ trait Trait { type Assoc where u32: Copy; // Fine. type Assoc2 where u32: Copy, i32: Copy; - // type Assoc3; + type Assoc4; } impl Trait for u32 { @@ -21,6 +24,9 @@ impl Trait for u32 { //~^ WARNING where clause not allowed here type Assoc3 = () where; //~^ WARNING where clause not allowed here + // issue: + type Assoc4 = () where i32: Copy; + //~^ WARNING where clause not allowed here } impl Trait for i32 { @@ -31,6 +37,7 @@ impl Trait for i32 { //~^ WARNING where clause not allowed here type Assoc3 = () where; //~^ WARNING where clause not allowed here + type Assoc4 = (); } fn main() {} diff --git a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.rs b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.rs index b7a8ab3d4f782..142eb01fe2d03 100644 --- a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.rs +++ b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.rs @@ -1,3 +1,6 @@ +// Ensure that we permit leading where clauses on associated types in traits +// (for backward compatibility) and lint on them. + //@ check-pass //@ run-rustfix @@ -8,8 +11,8 @@ trait Trait { type Assoc where u32: Copy; // Fine. type Assoc2 where u32: Copy, i32: Copy; - // type Assoc3; + type Assoc4; } impl Trait for u32 { @@ -21,6 +24,9 @@ impl Trait for u32 { //~^ WARNING where clause not allowed here type Assoc3 where = (); //~^ WARNING where clause not allowed here + // issue: + type Assoc4 where i32: Copy = () where; + //~^ WARNING where clause not allowed here } impl Trait for i32 { @@ -31,6 +37,7 @@ impl Trait for i32 { //~^ WARNING where clause not allowed here type Assoc3 where = () where; //~^ WARNING where clause not allowed here + type Assoc4 = (); } fn main() {} diff --git a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.stderr b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.stderr index f31c8b2dd8219..cb6ae3095c6c1 100644 --- a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.stderr +++ b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.stderr @@ -1,5 +1,5 @@ warning: where clause not allowed here - --> $DIR/where-clause-placement-assoc-type-in-impl.rs:17:16 + --> $DIR/where-clause-placement-assoc-type-in-impl.rs:20:16 | LL | type Assoc where u32: Copy = (); | ^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL + type Assoc = () where u32: Copy; | warning: where clause not allowed here - --> $DIR/where-clause-placement-assoc-type-in-impl.rs:20:17 + --> $DIR/where-clause-placement-assoc-type-in-impl.rs:23:17 | LL | type Assoc2 where u32: Copy = () where i32: Copy; | ^^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL + type Assoc2 = () where i32: Copy, u32: Copy; | warning: where clause not allowed here - --> $DIR/where-clause-placement-assoc-type-in-impl.rs:22:17 + --> $DIR/where-clause-placement-assoc-type-in-impl.rs:25:17 | LL | type Assoc3 where = (); | ^^^^^ @@ -39,7 +39,20 @@ LL + type Assoc3 = () where; | warning: where clause not allowed here - --> $DIR/where-clause-placement-assoc-type-in-impl.rs:30:17 + --> $DIR/where-clause-placement-assoc-type-in-impl.rs:28:17 + | +LL | type Assoc4 where i32: Copy = () where; + | ^^^^^^^^^^^^^^^ + | + = note: see issue #89122 for more information +help: move it to the end of the type declaration + | +LL - type Assoc4 where i32: Copy = () where; +LL + type Assoc4 = () where i32: Copy; + | + +warning: where clause not allowed here + --> $DIR/where-clause-placement-assoc-type-in-impl.rs:36:17 | LL | type Assoc2 where u32: Copy, i32: Copy = (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -52,12 +65,12 @@ LL + type Assoc2 = () where u32: Copy, i32: Copy; | warning: where clause not allowed here - --> $DIR/where-clause-placement-assoc-type-in-impl.rs:32:17 + --> $DIR/where-clause-placement-assoc-type-in-impl.rs:38:17 | LL | type Assoc3 where = () where; | ^^^^^ help: remove this `where` | = note: see issue #89122 for more information -warning: 5 warnings emitted +warning: 6 warnings emitted diff --git a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.fixed b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.fixed index 02dba8f946d6c..0a4155189fce2 100644 --- a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.fixed +++ b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.fixed @@ -1,14 +1,19 @@ +// Ensure that we permit leading where clauses on associated types in traits +// (for backward compatibility) and lint on them. + //@ check-pass //@ run-rustfix +#![feature(associated_type_defaults)] // only used for some test cases #![allow(dead_code)] -#![feature(associated_type_defaults)] trait Trait { - // Not fine, suggests moving. - type Assoc = () where u32: Copy; + type Assoc0 where T: Eq, T: Copy; + //~^ WARNING where clause not allowed here + + type Assoc1 = () where u32: Copy; //~^ WARNING where clause not allowed here - // Not fine, suggests moving `u32: Copy` + type Assoc2 = () where i32: Copy, u32: Copy; //~^ WARNING where clause not allowed here } diff --git a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.rs b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.rs index a76787413144c..df7140e0ef867 100644 --- a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.rs +++ b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.rs @@ -1,14 +1,19 @@ +// Ensure that we permit leading where clauses on associated types in traits +// (for backward compatibility) and lint on them. + //@ check-pass //@ run-rustfix +#![feature(associated_type_defaults)] // only used for some test cases #![allow(dead_code)] -#![feature(associated_type_defaults)] trait Trait { - // Not fine, suggests moving. - type Assoc where u32: Copy = (); + type Assoc0 where T: Copy where T: Eq; + //~^ WARNING where clause not allowed here + + type Assoc1 where u32: Copy = (); //~^ WARNING where clause not allowed here - // Not fine, suggests moving `u32: Copy` + type Assoc2 where u32: Copy = () where i32: Copy; //~^ WARNING where clause not allowed here } diff --git a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.stderr b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.stderr index 1b7c09897b7b8..415e4feb5c250 100644 --- a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.stderr +++ b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.stderr @@ -1,19 +1,32 @@ warning: where clause not allowed here - --> $DIR/where-clause-placement-assoc-type-in-trait.rs:9:16 + --> $DIR/where-clause-placement-assoc-type-in-trait.rs:11:20 | -LL | type Assoc where u32: Copy = (); - | ^^^^^^^^^^^^^^^ +LL | type Assoc0 where T: Copy where T: Eq; + | ^^^^^^^^^^^^^ | = note: see issue #89122 for more information = note: `#[warn(deprecated_where_clause_location)]` on by default help: move it to the end of the type declaration | -LL - type Assoc where u32: Copy = (); -LL + type Assoc = () where u32: Copy; +LL - type Assoc0 where T: Copy where T: Eq; +LL + type Assoc0 where T: Eq, T: Copy; | warning: where clause not allowed here - --> $DIR/where-clause-placement-assoc-type-in-trait.rs:12:17 + --> $DIR/where-clause-placement-assoc-type-in-trait.rs:14:17 + | +LL | type Assoc1 where u32: Copy = (); + | ^^^^^^^^^^^^^^^ + | + = note: see issue #89122 for more information +help: move it to the end of the type declaration + | +LL - type Assoc1 where u32: Copy = (); +LL + type Assoc1 = () where u32: Copy; + | + +warning: where clause not allowed here + --> $DIR/where-clause-placement-assoc-type-in-trait.rs:17:17 | LL | type Assoc2 where u32: Copy = () where i32: Copy; | ^^^^^^^^^^^^^^^ @@ -25,5 +38,5 @@ LL - type Assoc2 where u32: Copy = () where i32: Copy; LL + type Assoc2 = () where i32: Copy, u32: Copy; | -warning: 2 warnings emitted +warning: 3 warnings emitted diff --git a/tests/ui/where-clauses/where-clause-placement-type-alias.fail.stderr b/tests/ui/where-clauses/where-clause-placement-type-alias.fail.stderr new file mode 100644 index 0000000000000..715e2cfa3e747 --- /dev/null +++ b/tests/ui/where-clauses/where-clause-placement-type-alias.fail.stderr @@ -0,0 +1,38 @@ +error: where clauses are not allowed after the type for type aliases + --> $DIR/where-clause-placement-type-alias.rs:10:34 + | +LL | #[cfg(fail)] type Trailing0 = () where u32: Copy; + | ^^^^^^^^^^^^^^^ + | + = note: see issue #112792 for more information + = help: add `#![feature(checked_type_aliases)]` to the crate attributes to enable + +error: where clauses are not allowed after the type for type aliases + --> $DIR/where-clause-placement-type-alias.rs:12:34 + | +LL | #[cfg(fail)] type Trailing1 = () where; + | ^^^^^ + | + = note: see issue #112792 for more information + = help: add `#![feature(checked_type_aliases)]` to the crate attributes to enable + +error: where clauses are not allowed after the type for type aliases + --> $DIR/where-clause-placement-type-alias.rs:17:42 + | +LL | #[cfg(fail)] type Both0 where (): = bool where !: Sized; + | ^^^^^^^^^^^^^^ + | + = note: see issue #112792 for more information + = help: add `#![feature(checked_type_aliases)]` to the crate attributes to enable + +error: where clauses are not allowed after the type for type aliases + --> $DIR/where-clause-placement-type-alias.rs:19:38 + | +LL | #[cfg(fail)] type Both1 where = bool where; + | ^^^^^ + | + = note: see issue #112792 for more information + = help: add `#![feature(checked_type_aliases)]` to the crate attributes to enable + +error: aborting due to 4 previous errors + diff --git a/tests/ui/where-clauses/where-clause-placement-type-alias.pass.stderr b/tests/ui/where-clauses/where-clause-placement-type-alias.pass.stderr new file mode 100644 index 0000000000000..6044cc139db51 --- /dev/null +++ b/tests/ui/where-clauses/where-clause-placement-type-alias.pass.stderr @@ -0,0 +1,18 @@ +warning: where clauses on type aliases are not enforced + --> $DIR/where-clause-placement-type-alias.rs:5:21 + | +LL | type Leading0 where u32: Copy = (); + | ^^^^^^^^^ will not be checked at usage sites of the type alias + | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information + = help: add `#![feature(checked_type_aliases)]` to the crate attributes to enable the desired semantics + = note: `#[warn(type_alias_bounds)]` on by default +help: remove this where clause + | +LL - type Leading0 where u32: Copy = (); +LL + type Leading0 = (); + | + +warning: 1 warning emitted + diff --git a/tests/ui/where-clauses/where-clause-placement-type-alias.rs b/tests/ui/where-clauses/where-clause-placement-type-alias.rs index 1f3b044c8119b..bb8fbc53edad0 100644 --- a/tests/ui/where-clauses/where-clause-placement-type-alias.rs +++ b/tests/ui/where-clauses/where-clause-placement-type-alias.rs @@ -1,11 +1,26 @@ -//@ check-fail - -// Fine, but lints as unused -type Foo where u32: Copy = (); -// Not fine. -type Bar = () where u32: Copy; -//~^ ERROR where clauses are not allowed -type Baz = () where; -//~^ ERROR where clauses are not allowed +// Test the parsing & basic semantic validation of where clauses on (free) type aliases. +//@ revisions: pass fail +//@[pass] check-pass + +type Leading0 where u32: Copy = (); //[pass]~ WARN [type_alias_bounds] +type Leading1 where = (); + +// Syntactically valid, semantically invalid: + +#[cfg(fail)] type Trailing0 = () where u32: Copy; +//[fail]~^ ERROR where clauses are not allowed +#[cfg(fail)] type Trailing1 = () where; +//[fail]~^ ERROR where clauses are not allowed + +// Indeed, we intentionally allow two where-clauses *at once* for backward compatibility. + +#[cfg(fail)] type Both0 where (): = bool where !: Sized; +//[fail]~^ ERROR where clauses are not allowed +#[cfg(fail)] type Both1 where = bool where; +//[fail]~^ ERROR where clauses are not allowed + +// We once used to incorrectly reject `BodilessBoth0` due to overzealous parse error recovery code. +#[cfg(false)] type BodilessBoth0 where [(); 1]: Copy where String: Clone; +#[cfg(false)] type BodilessBoth1 where where; fn main() {} diff --git a/tests/ui/where-clauses/where-clause-placement-type-alias.stderr b/tests/ui/where-clauses/where-clause-placement-type-alias.stderr deleted file mode 100644 index 23798e5fa6124..0000000000000 --- a/tests/ui/where-clauses/where-clause-placement-type-alias.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: where clauses are not allowed after the type for type aliases - --> $DIR/where-clause-placement-type-alias.rs:6:15 - | -LL | type Bar = () where u32: Copy; - | ^^^^^^^^^^^^^^^ - | - = note: see issue #112792 for more information - = help: add `#![feature(checked_type_aliases)]` to the crate attributes to enable - -error: where clauses are not allowed after the type for type aliases - --> $DIR/where-clause-placement-type-alias.rs:8:15 - | -LL | type Baz = () where; - | ^^^^^ - | - = note: see issue #112792 for more information - = help: add `#![feature(checked_type_aliases)]` to the crate attributes to enable - -error: aborting due to 2 previous errors -