Auto merge of #90076 - jackh726:wherethewhere, r=nikomatsakis
Change location of where clause on GATs Closes #89122 ~Blocked on lang FCP~ r? `@nikomatsakis`
This commit is contained in:
commit
ad0d1d71d3
52 changed files with 552 additions and 283 deletions
|
@ -2662,10 +2662,37 @@ pub struct Trait {
|
||||||
pub items: Vec<P<AssocItem>>,
|
pub items: Vec<P<AssocItem>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The location of a where clause on a `TyAlias` (`Span`) and whether there was
|
||||||
|
/// a `where` keyword (`bool`). This is split out from `WhereClause`, since there
|
||||||
|
/// are two locations for where clause on type aliases, but their predicates
|
||||||
|
/// are concatenated together.
|
||||||
|
///
|
||||||
|
/// Take this example:
|
||||||
|
/// ```ignore (only-for-syntax-highlight)
|
||||||
|
/// trait Foo {
|
||||||
|
/// type Assoc<'a, 'b> where Self: 'a, Self: 'b;
|
||||||
|
/// }
|
||||||
|
/// impl Foo for () {
|
||||||
|
/// type Assoc<'a, 'b> where Self: 'a = () where Self: 'b;
|
||||||
|
/// // ^^^^^^^^^^^^^^ first where clause
|
||||||
|
/// // ^^^^^^^^^^^^^^ second where clause
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// If there is no where clause, then this is `false` with `DUMMY_SP`.
|
||||||
|
#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
|
||||||
|
pub struct TyAliasWhereClause(pub bool, pub Span);
|
||||||
|
|
||||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
pub struct TyAlias {
|
pub struct TyAlias {
|
||||||
pub defaultness: Defaultness,
|
pub defaultness: Defaultness,
|
||||||
pub generics: Generics,
|
pub generics: Generics,
|
||||||
|
/// The span information for the two where clauses (before equals, after equals)
|
||||||
|
pub where_clauses: (TyAliasWhereClause, TyAliasWhereClause),
|
||||||
|
/// The index in `generics.where_clause.predicates` that would split into
|
||||||
|
/// predicates from the where clause before the equals and the predicates
|
||||||
|
/// from the where clause after the equals
|
||||||
|
pub where_predicates_split: usize,
|
||||||
pub bounds: GenericBounds,
|
pub bounds: GenericBounds,
|
||||||
pub ty: Option<P<Ty>>,
|
pub ty: Option<P<Ty>>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1018,9 +1018,13 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
|
||||||
}
|
}
|
||||||
ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
|
ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
|
||||||
ItemKind::GlobalAsm(asm) => noop_visit_inline_asm(asm, vis),
|
ItemKind::GlobalAsm(asm) => noop_visit_inline_asm(asm, vis),
|
||||||
ItemKind::TyAlias(box TyAlias { defaultness, generics, bounds, ty }) => {
|
ItemKind::TyAlias(box TyAlias {
|
||||||
|
defaultness, generics, where_clauses, bounds, ty, ..
|
||||||
|
}) => {
|
||||||
visit_defaultness(defaultness, vis);
|
visit_defaultness(defaultness, vis);
|
||||||
vis.visit_generics(generics);
|
vis.visit_generics(generics);
|
||||||
|
vis.visit_span(&mut where_clauses.0.1);
|
||||||
|
vis.visit_span(&mut where_clauses.1.1);
|
||||||
visit_bounds(bounds, vis);
|
visit_bounds(bounds, vis);
|
||||||
visit_opt(ty, |ty| vis.visit_ty(ty));
|
visit_opt(ty, |ty| vis.visit_ty(ty));
|
||||||
}
|
}
|
||||||
|
@ -1087,9 +1091,18 @@ pub fn noop_flat_map_assoc_item<T: MutVisitor>(
|
||||||
visit_fn_sig(sig, visitor);
|
visit_fn_sig(sig, visitor);
|
||||||
visit_opt(body, |body| visitor.visit_block(body));
|
visit_opt(body, |body| visitor.visit_block(body));
|
||||||
}
|
}
|
||||||
AssocItemKind::TyAlias(box TyAlias { defaultness, generics, bounds, ty }) => {
|
AssocItemKind::TyAlias(box TyAlias {
|
||||||
|
defaultness,
|
||||||
|
generics,
|
||||||
|
where_clauses,
|
||||||
|
bounds,
|
||||||
|
ty,
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
visit_defaultness(defaultness, visitor);
|
visit_defaultness(defaultness, visitor);
|
||||||
visitor.visit_generics(generics);
|
visitor.visit_generics(generics);
|
||||||
|
visitor.visit_span(&mut where_clauses.0.1);
|
||||||
|
visitor.visit_span(&mut where_clauses.1.1);
|
||||||
visit_bounds(bounds, visitor);
|
visit_bounds(bounds, visitor);
|
||||||
visit_opt(ty, |ty| visitor.visit_ty(ty));
|
visit_opt(ty, |ty| visitor.visit_ty(ty));
|
||||||
}
|
}
|
||||||
|
@ -1152,9 +1165,18 @@ pub fn noop_flat_map_foreign_item<T: MutVisitor>(
|
||||||
visit_fn_sig(sig, visitor);
|
visit_fn_sig(sig, visitor);
|
||||||
visit_opt(body, |body| visitor.visit_block(body));
|
visit_opt(body, |body| visitor.visit_block(body));
|
||||||
}
|
}
|
||||||
ForeignItemKind::TyAlias(box TyAlias { defaultness, generics, bounds, ty }) => {
|
ForeignItemKind::TyAlias(box TyAlias {
|
||||||
|
defaultness,
|
||||||
|
generics,
|
||||||
|
where_clauses,
|
||||||
|
bounds,
|
||||||
|
ty,
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
visit_defaultness(defaultness, visitor);
|
visit_defaultness(defaultness, visitor);
|
||||||
visitor.visit_generics(generics);
|
visitor.visit_generics(generics);
|
||||||
|
visitor.visit_span(&mut where_clauses.0.1);
|
||||||
|
visitor.visit_span(&mut where_clauses.1.1);
|
||||||
visit_bounds(bounds, visitor);
|
visit_bounds(bounds, visitor);
|
||||||
visit_opt(ty, |ty| visitor.visit_ty(ty));
|
visit_opt(ty, |ty| visitor.visit_ty(ty));
|
||||||
}
|
}
|
||||||
|
|
|
@ -303,7 +303,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
|
||||||
walk_list!(visitor, visit_foreign_item, &foreign_module.items);
|
walk_list!(visitor, visit_foreign_item, &foreign_module.items);
|
||||||
}
|
}
|
||||||
ItemKind::GlobalAsm(ref asm) => walk_inline_asm(visitor, asm),
|
ItemKind::GlobalAsm(ref asm) => walk_inline_asm(visitor, asm),
|
||||||
ItemKind::TyAlias(box TyAlias { defaultness: _, ref generics, ref bounds, ref ty }) => {
|
ItemKind::TyAlias(box TyAlias { ref generics, ref bounds, ref ty, .. }) => {
|
||||||
visitor.visit_generics(generics);
|
visitor.visit_generics(generics);
|
||||||
walk_list!(visitor, visit_param_bound, bounds);
|
walk_list!(visitor, visit_param_bound, bounds);
|
||||||
walk_list!(visitor, visit_ty, ty);
|
walk_list!(visitor, visit_ty, ty);
|
||||||
|
@ -559,7 +559,7 @@ pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a ForeignI
|
||||||
let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, body.as_deref());
|
let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, body.as_deref());
|
||||||
visitor.visit_fn(kind, span, id);
|
visitor.visit_fn(kind, span, id);
|
||||||
}
|
}
|
||||||
ForeignItemKind::TyAlias(box TyAlias { defaultness: _, generics, bounds, ty }) => {
|
ForeignItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => {
|
||||||
visitor.visit_generics(generics);
|
visitor.visit_generics(generics);
|
||||||
walk_list!(visitor, visit_param_bound, bounds);
|
walk_list!(visitor, visit_param_bound, bounds);
|
||||||
walk_list!(visitor, visit_ty, ty);
|
walk_list!(visitor, visit_ty, ty);
|
||||||
|
@ -665,7 +665,7 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem,
|
||||||
let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, body.as_deref());
|
let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, body.as_deref());
|
||||||
visitor.visit_fn(kind, span, id);
|
visitor.visit_fn(kind, span, id);
|
||||||
}
|
}
|
||||||
AssocItemKind::TyAlias(box TyAlias { defaultness: _, generics, bounds, ty }) => {
|
AssocItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => {
|
||||||
visitor.visit_generics(generics);
|
visitor.visit_generics(generics);
|
||||||
walk_list!(visitor, visit_param_bound, bounds);
|
walk_list!(visitor, visit_param_bound, bounds);
|
||||||
walk_list!(visitor, visit_ty, ty);
|
walk_list!(visitor, visit_ty, ty);
|
||||||
|
|
|
@ -25,6 +25,26 @@ pub(super) struct ItemLowerer<'a, 'lowering, 'hir> {
|
||||||
pub(super) lctx: &'a mut LoweringContext<'lowering, 'hir>,
|
pub(super) lctx: &'a mut LoweringContext<'lowering, 'hir>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// When we have a ty alias we *may* have two where clauses. To give the best diagnostics, we set the span
|
||||||
|
/// to the where clause that is prefered, if it exists. Otherwise, it sets the span to the other where
|
||||||
|
/// clause if it exists.
|
||||||
|
fn add_ty_alias_where_clause(
|
||||||
|
generics: &mut ast::Generics,
|
||||||
|
mut where_clauses: (TyAliasWhereClause, TyAliasWhereClause),
|
||||||
|
prefer_first: bool,
|
||||||
|
) {
|
||||||
|
if !prefer_first {
|
||||||
|
where_clauses = (where_clauses.1, where_clauses.0);
|
||||||
|
}
|
||||||
|
if where_clauses.0.0 || !where_clauses.1.0 {
|
||||||
|
generics.where_clause.has_where_token = where_clauses.0.0;
|
||||||
|
generics.where_clause.span = where_clauses.0.1;
|
||||||
|
} else {
|
||||||
|
generics.where_clause.has_where_token = where_clauses.1.0;
|
||||||
|
generics.where_clause.span = where_clauses.1.1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ItemLowerer<'_, '_, '_> {
|
impl ItemLowerer<'_, '_, '_> {
|
||||||
fn with_trait_impl_ref<T>(
|
fn with_trait_impl_ref<T>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -277,7 +297,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
ItemKind::GlobalAsm(ref asm) => {
|
ItemKind::GlobalAsm(ref asm) => {
|
||||||
hir::ItemKind::GlobalAsm(self.lower_inline_asm(span, asm))
|
hir::ItemKind::GlobalAsm(self.lower_inline_asm(span, asm))
|
||||||
}
|
}
|
||||||
ItemKind::TyAlias(box TyAlias { ref generics, ty: Some(ref ty), .. }) => {
|
ItemKind::TyAlias(box TyAlias {
|
||||||
|
ref generics,
|
||||||
|
where_clauses,
|
||||||
|
ty: Some(ref ty),
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
// We lower
|
// We lower
|
||||||
//
|
//
|
||||||
// type Foo = impl Trait
|
// type Foo = impl Trait
|
||||||
|
@ -292,16 +317,22 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
capturable_lifetimes: &mut FxHashSet::default(),
|
capturable_lifetimes: &mut FxHashSet::default(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
let mut generics = generics.clone();
|
||||||
|
add_ty_alias_where_clause(&mut generics, where_clauses, true);
|
||||||
let generics = self.lower_generics(
|
let generics = self.lower_generics(
|
||||||
generics,
|
&generics,
|
||||||
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|
||||||
);
|
);
|
||||||
hir::ItemKind::TyAlias(ty, generics)
|
hir::ItemKind::TyAlias(ty, generics)
|
||||||
}
|
}
|
||||||
ItemKind::TyAlias(box TyAlias { ref generics, ty: None, .. }) => {
|
ItemKind::TyAlias(box TyAlias {
|
||||||
|
ref generics, ref where_clauses, ty: None, ..
|
||||||
|
}) => {
|
||||||
let ty = self.arena.alloc(self.ty(span, hir::TyKind::Err));
|
let ty = self.arena.alloc(self.ty(span, hir::TyKind::Err));
|
||||||
|
let mut generics = generics.clone();
|
||||||
|
add_ty_alias_where_clause(&mut generics, *where_clauses, true);
|
||||||
let generics = self.lower_generics(
|
let generics = self.lower_generics(
|
||||||
generics,
|
&generics,
|
||||||
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|
||||||
);
|
);
|
||||||
hir::ItemKind::TyAlias(ty, generics)
|
hir::ItemKind::TyAlias(ty, generics)
|
||||||
|
@ -832,18 +863,26 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
);
|
);
|
||||||
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)))
|
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)))
|
||||||
}
|
}
|
||||||
AssocItemKind::TyAlias(box TyAlias { ref generics, ref bounds, ref ty, .. }) => {
|
AssocItemKind::TyAlias(box TyAlias {
|
||||||
|
ref generics,
|
||||||
|
where_clauses,
|
||||||
|
ref bounds,
|
||||||
|
ref ty,
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
let ty = ty.as_ref().map(|x| {
|
let ty = ty.as_ref().map(|x| {
|
||||||
self.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Type))
|
self.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Type))
|
||||||
});
|
});
|
||||||
|
let mut generics = generics.clone();
|
||||||
|
add_ty_alias_where_clause(&mut generics, where_clauses, false);
|
||||||
let generics = self.lower_generics(
|
let generics = self.lower_generics(
|
||||||
generics,
|
&generics,
|
||||||
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|
||||||
);
|
);
|
||||||
let kind = hir::TraitItemKind::Type(
|
let kind = hir::TraitItemKind::Type(
|
||||||
self.lower_param_bounds(
|
self.lower_param_bounds(
|
||||||
bounds,
|
bounds,
|
||||||
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
|
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|
||||||
),
|
),
|
||||||
ty,
|
ty,
|
||||||
);
|
);
|
||||||
|
@ -917,9 +956,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
|
|
||||||
(generics, hir::ImplItemKind::Fn(sig, body_id))
|
(generics, hir::ImplItemKind::Fn(sig, body_id))
|
||||||
}
|
}
|
||||||
AssocItemKind::TyAlias(box TyAlias { generics, ty, .. }) => {
|
AssocItemKind::TyAlias(box TyAlias { generics, where_clauses, ty, .. }) => {
|
||||||
|
let mut generics = generics.clone();
|
||||||
|
add_ty_alias_where_clause(&mut generics, *where_clauses, false);
|
||||||
let generics = self.lower_generics(
|
let generics = self.lower_generics(
|
||||||
generics,
|
&generics,
|
||||||
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|
||||||
);
|
);
|
||||||
let kind = match ty {
|
let kind = match ty {
|
||||||
|
|
|
@ -11,11 +11,13 @@ use rustc_ast::ptr::P;
|
||||||
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
|
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
|
||||||
use rustc_ast::walk_list;
|
use rustc_ast::walk_list;
|
||||||
use rustc_ast::*;
|
use rustc_ast::*;
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust::{self, State};
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_errors::{error_code, pluralize, struct_span_err, Applicability};
|
use rustc_errors::{error_code, pluralize, struct_span_err, Applicability};
|
||||||
use rustc_parse::validate_attr;
|
use rustc_parse::validate_attr;
|
||||||
use rustc_session::lint::builtin::{MISSING_ABI, PATTERNS_IN_FNS_WITHOUT_BODY};
|
use rustc_session::lint::builtin::{
|
||||||
|
DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, PATTERNS_IN_FNS_WITHOUT_BODY,
|
||||||
|
};
|
||||||
use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
|
use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::source_map::Spanned;
|
use rustc_span::source_map::Spanned;
|
||||||
|
@ -122,6 +124,42 @@ impl<'a> AstValidator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_gat_where(
|
||||||
|
&mut self,
|
||||||
|
id: NodeId,
|
||||||
|
before_predicates: &[WherePredicate],
|
||||||
|
where_clauses: (ast::TyAliasWhereClause, ast::TyAliasWhereClause),
|
||||||
|
) {
|
||||||
|
if !before_predicates.is_empty() {
|
||||||
|
let mut state = State::new();
|
||||||
|
if !where_clauses.1.0 {
|
||||||
|
state.space();
|
||||||
|
state.word_space("where");
|
||||||
|
} else {
|
||||||
|
state.word_space(",");
|
||||||
|
}
|
||||||
|
let mut first = true;
|
||||||
|
for p in before_predicates.iter() {
|
||||||
|
if !first {
|
||||||
|
state.word_space(",");
|
||||||
|
}
|
||||||
|
first = false;
|
||||||
|
state.print_where_predicate(p);
|
||||||
|
}
|
||||||
|
let suggestion = state.s.eof();
|
||||||
|
self.lint_buffer.buffer_lint_with_diagnostic(
|
||||||
|
DEPRECATED_WHERE_CLAUSE_LOCATION,
|
||||||
|
id,
|
||||||
|
where_clauses.0.1,
|
||||||
|
"where clause not allowed here",
|
||||||
|
BuiltinLintDiagnostics::DeprecatedWhereclauseLocation(
|
||||||
|
where_clauses.1.1.shrink_to_hi(),
|
||||||
|
suggestion,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn with_banned_assoc_ty_bound(&mut self, f: impl FnOnce(&mut Self)) {
|
fn with_banned_assoc_ty_bound(&mut self, f: impl FnOnce(&mut Self)) {
|
||||||
let old = mem::replace(&mut self.is_assoc_ty_bound_banned, true);
|
let old = mem::replace(&mut self.is_assoc_ty_bound_banned, true);
|
||||||
f(self);
|
f(self);
|
||||||
|
@ -454,7 +492,7 @@ impl<'a> AstValidator<'a> {
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_foreign_ty_genericless(&self, generics: &Generics) {
|
fn check_foreign_ty_genericless(&self, generics: &Generics, where_span: Span) {
|
||||||
let cannot_have = |span, descr, remove_descr| {
|
let cannot_have = |span, descr, remove_descr| {
|
||||||
self.err_handler()
|
self.err_handler()
|
||||||
.struct_span_err(
|
.struct_span_err(
|
||||||
|
@ -477,7 +515,7 @@ impl<'a> AstValidator<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !generics.where_clause.predicates.is_empty() {
|
if !generics.where_clause.predicates.is_empty() {
|
||||||
cannot_have(generics.where_clause.span, "`where` clauses", "`where` clause");
|
cannot_have(where_span, "`where` clauses", "`where` clause");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1223,13 +1261,29 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
let msg = "free static item without body";
|
let msg = "free static item without body";
|
||||||
self.error_item_without_body(item.span, "static", msg, " = <expr>;");
|
self.error_item_without_body(item.span, "static", msg, " = <expr>;");
|
||||||
}
|
}
|
||||||
ItemKind::TyAlias(box TyAlias { defaultness, ref bounds, ref ty, .. }) => {
|
ItemKind::TyAlias(box TyAlias {
|
||||||
|
defaultness,
|
||||||
|
where_clauses,
|
||||||
|
ref bounds,
|
||||||
|
ref ty,
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
self.check_defaultness(item.span, defaultness);
|
self.check_defaultness(item.span, defaultness);
|
||||||
if ty.is_none() {
|
if ty.is_none() {
|
||||||
let msg = "free type alias without body";
|
let msg = "free type alias without body";
|
||||||
self.error_item_without_body(item.span, "type", msg, " = <type>;");
|
self.error_item_without_body(item.span, "type", msg, " = <type>;");
|
||||||
}
|
}
|
||||||
self.check_type_no_bounds(bounds, "this context");
|
self.check_type_no_bounds(bounds, "this context");
|
||||||
|
if where_clauses.1.0 {
|
||||||
|
let mut err = self.err_handler().struct_span_err(
|
||||||
|
where_clauses.1.1,
|
||||||
|
"where clauses are not allowed after the type for type aliases",
|
||||||
|
);
|
||||||
|
err.note(
|
||||||
|
"see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information",
|
||||||
|
);
|
||||||
|
err.emit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -1245,11 +1299,18 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
self.check_foreign_fn_headerless(fi.ident, fi.span, sig.header);
|
self.check_foreign_fn_headerless(fi.ident, fi.span, sig.header);
|
||||||
self.check_foreign_item_ascii_only(fi.ident);
|
self.check_foreign_item_ascii_only(fi.ident);
|
||||||
}
|
}
|
||||||
ForeignItemKind::TyAlias(box TyAlias { defaultness, generics, bounds, ty, .. }) => {
|
ForeignItemKind::TyAlias(box TyAlias {
|
||||||
|
defaultness,
|
||||||
|
generics,
|
||||||
|
where_clauses,
|
||||||
|
bounds,
|
||||||
|
ty,
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
self.check_defaultness(fi.span, *defaultness);
|
self.check_defaultness(fi.span, *defaultness);
|
||||||
self.check_foreign_kind_bodyless(fi.ident, "type", ty.as_ref().map(|b| b.span));
|
self.check_foreign_kind_bodyless(fi.ident, "type", ty.as_ref().map(|b| b.span));
|
||||||
self.check_type_no_bounds(bounds, "`extern` blocks");
|
self.check_type_no_bounds(bounds, "`extern` blocks");
|
||||||
self.check_foreign_ty_genericless(generics);
|
self.check_foreign_ty_genericless(generics, where_clauses.0.1);
|
||||||
self.check_foreign_item_ascii_only(fi.ident);
|
self.check_foreign_item_ascii_only(fi.ident);
|
||||||
}
|
}
|
||||||
ForeignItemKind::Static(_, _, body) => {
|
ForeignItemKind::Static(_, _, body) => {
|
||||||
|
@ -1503,9 +1564,23 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
AssocItemKind::Fn(box Fn { body, .. }) => {
|
AssocItemKind::Fn(box Fn { body, .. }) => {
|
||||||
self.check_impl_item_provided(item.span, body, "function", " { <body> }");
|
self.check_impl_item_provided(item.span, body, "function", " { <body> }");
|
||||||
}
|
}
|
||||||
AssocItemKind::TyAlias(box TyAlias { bounds, ty, .. }) => {
|
AssocItemKind::TyAlias(box TyAlias {
|
||||||
|
generics,
|
||||||
|
where_clauses,
|
||||||
|
where_predicates_split,
|
||||||
|
bounds,
|
||||||
|
ty,
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
self.check_impl_item_provided(item.span, ty, "type", " = <type>;");
|
self.check_impl_item_provided(item.span, ty, "type", " = <type>;");
|
||||||
self.check_type_no_bounds(bounds, "`impl`s");
|
self.check_type_no_bounds(bounds, "`impl`s");
|
||||||
|
if ty.is_some() {
|
||||||
|
self.check_gat_where(
|
||||||
|
item.id,
|
||||||
|
generics.where_clause.predicates.split_at(*where_predicates_split).0,
|
||||||
|
*where_clauses,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,12 +36,16 @@ impl<'a> State<'a> {
|
||||||
ast::ForeignItemKind::TyAlias(box ast::TyAlias {
|
ast::ForeignItemKind::TyAlias(box ast::TyAlias {
|
||||||
defaultness,
|
defaultness,
|
||||||
generics,
|
generics,
|
||||||
|
where_clauses,
|
||||||
|
where_predicates_split,
|
||||||
bounds,
|
bounds,
|
||||||
ty,
|
ty,
|
||||||
}) => {
|
}) => {
|
||||||
self.print_associated_type(
|
self.print_associated_type(
|
||||||
ident,
|
ident,
|
||||||
generics,
|
generics,
|
||||||
|
*where_clauses,
|
||||||
|
*where_predicates_split,
|
||||||
bounds,
|
bounds,
|
||||||
ty.as_deref(),
|
ty.as_deref(),
|
||||||
vis,
|
vis,
|
||||||
|
@ -95,11 +99,15 @@ impl<'a> State<'a> {
|
||||||
&mut self,
|
&mut self,
|
||||||
ident: Ident,
|
ident: Ident,
|
||||||
generics: &ast::Generics,
|
generics: &ast::Generics,
|
||||||
|
where_clauses: (ast::TyAliasWhereClause, ast::TyAliasWhereClause),
|
||||||
|
where_predicates_split: usize,
|
||||||
bounds: &ast::GenericBounds,
|
bounds: &ast::GenericBounds,
|
||||||
ty: Option<&ast::Ty>,
|
ty: Option<&ast::Ty>,
|
||||||
vis: &ast::Visibility,
|
vis: &ast::Visibility,
|
||||||
defaultness: ast::Defaultness,
|
defaultness: ast::Defaultness,
|
||||||
) {
|
) {
|
||||||
|
let (before_predicates, after_predicates) =
|
||||||
|
generics.where_clause.predicates.split_at(where_predicates_split);
|
||||||
self.head("");
|
self.head("");
|
||||||
self.print_visibility(vis);
|
self.print_visibility(vis);
|
||||||
self.print_defaultness(defaultness);
|
self.print_defaultness(defaultness);
|
||||||
|
@ -107,12 +115,13 @@ impl<'a> State<'a> {
|
||||||
self.print_ident(ident);
|
self.print_ident(ident);
|
||||||
self.print_generic_params(&generics.params);
|
self.print_generic_params(&generics.params);
|
||||||
self.print_type_bounds(":", bounds);
|
self.print_type_bounds(":", bounds);
|
||||||
self.print_where_clause(&generics.where_clause);
|
self.print_where_clause_parts(where_clauses.0.0, before_predicates);
|
||||||
if let Some(ty) = ty {
|
if let Some(ty) = ty {
|
||||||
self.space();
|
self.space();
|
||||||
self.word_space("=");
|
self.word_space("=");
|
||||||
self.print_type(ty);
|
self.print_type(ty);
|
||||||
}
|
}
|
||||||
|
self.print_where_clause_parts(where_clauses.1.0, after_predicates);
|
||||||
self.word(";");
|
self.word(";");
|
||||||
self.end(); // end inner head-block
|
self.end(); // end inner head-block
|
||||||
self.end(); // end outer head-block
|
self.end(); // end outer head-block
|
||||||
|
@ -211,6 +220,8 @@ impl<'a> State<'a> {
|
||||||
ast::ItemKind::TyAlias(box ast::TyAlias {
|
ast::ItemKind::TyAlias(box ast::TyAlias {
|
||||||
defaultness,
|
defaultness,
|
||||||
ref generics,
|
ref generics,
|
||||||
|
where_clauses,
|
||||||
|
where_predicates_split,
|
||||||
ref bounds,
|
ref bounds,
|
||||||
ref ty,
|
ref ty,
|
||||||
}) => {
|
}) => {
|
||||||
|
@ -218,6 +229,8 @@ impl<'a> State<'a> {
|
||||||
self.print_associated_type(
|
self.print_associated_type(
|
||||||
item.ident,
|
item.ident,
|
||||||
generics,
|
generics,
|
||||||
|
where_clauses,
|
||||||
|
where_predicates_split,
|
||||||
bounds,
|
bounds,
|
||||||
ty,
|
ty,
|
||||||
&item.vis,
|
&item.vis,
|
||||||
|
@ -496,10 +509,19 @@ impl<'a> State<'a> {
|
||||||
ast::AssocItemKind::Const(def, ty, body) => {
|
ast::AssocItemKind::Const(def, ty, body) => {
|
||||||
self.print_item_const(ident, None, ty, body.as_deref(), vis, *def);
|
self.print_item_const(ident, None, ty, body.as_deref(), vis, *def);
|
||||||
}
|
}
|
||||||
ast::AssocItemKind::TyAlias(box ast::TyAlias { defaultness, generics, bounds, ty }) => {
|
ast::AssocItemKind::TyAlias(box ast::TyAlias {
|
||||||
|
defaultness,
|
||||||
|
generics,
|
||||||
|
where_clauses,
|
||||||
|
where_predicates_split,
|
||||||
|
bounds,
|
||||||
|
ty,
|
||||||
|
}) => {
|
||||||
self.print_associated_type(
|
self.print_associated_type(
|
||||||
ident,
|
ident,
|
||||||
generics,
|
generics,
|
||||||
|
*where_clauses,
|
||||||
|
*where_predicates_split,
|
||||||
bounds,
|
bounds,
|
||||||
ty.as_deref(),
|
ty.as_deref(),
|
||||||
vis,
|
vis,
|
||||||
|
@ -566,14 +588,22 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_where_clause(&mut self, where_clause: &ast::WhereClause) {
|
fn print_where_clause(&mut self, where_clause: &ast::WhereClause) {
|
||||||
if where_clause.predicates.is_empty() && !where_clause.has_where_token {
|
self.print_where_clause_parts(where_clause.has_where_token, &where_clause.predicates);
|
||||||
|
}
|
||||||
|
|
||||||
|
crate fn print_where_clause_parts(
|
||||||
|
&mut self,
|
||||||
|
has_where_token: bool,
|
||||||
|
predicates: &[ast::WherePredicate],
|
||||||
|
) {
|
||||||
|
if predicates.is_empty() && !has_where_token {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.space();
|
self.space();
|
||||||
self.word_space("where");
|
self.word_space("where");
|
||||||
|
|
||||||
for (i, predicate) in where_clause.predicates.iter().enumerate() {
|
for (i, predicate) in predicates.iter().enumerate() {
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
self.word_space(",");
|
self.word_space(",");
|
||||||
}
|
}
|
||||||
|
|
|
@ -560,6 +560,11 @@ impl<'a> TraitDef<'a> {
|
||||||
kind: ast::AssocItemKind::TyAlias(Box::new(ast::TyAlias {
|
kind: ast::AssocItemKind::TyAlias(Box::new(ast::TyAlias {
|
||||||
defaultness: ast::Defaultness::Final,
|
defaultness: ast::Defaultness::Final,
|
||||||
generics: Generics::default(),
|
generics: Generics::default(),
|
||||||
|
where_clauses: (
|
||||||
|
ast::TyAliasWhereClause::default(),
|
||||||
|
ast::TyAliasWhereClause::default(),
|
||||||
|
),
|
||||||
|
where_predicates_split: 0,
|
||||||
bounds: Vec::new(),
|
bounds: Vec::new(),
|
||||||
ty: Some(type_def.to_ty(cx, self.span, type_ident, generics)),
|
ty: Some(type_def.to_ty(cx, self.span, type_ident, generics)),
|
||||||
})),
|
})),
|
||||||
|
|
|
@ -818,6 +818,16 @@ pub trait LintContext: Sized {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
BuiltinLintDiagnostics::DeprecatedWhereclauseLocation(new_span, suggestion) => {
|
||||||
|
db.multipart_suggestion(
|
||||||
|
"move it to the end of the type declaration",
|
||||||
|
vec![(db.span.primary_span().unwrap(), "".to_string()), (new_span, suggestion)],
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
db.note(
|
||||||
|
"see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information",
|
||||||
|
);
|
||||||
|
},
|
||||||
}
|
}
|
||||||
// Rewrap `db`, and pass control to the user.
|
// Rewrap `db`, and pass control to the user.
|
||||||
decorate(LintDiagnosticBuilder::new(db));
|
decorate(LintDiagnosticBuilder::new(db));
|
||||||
|
|
|
@ -3127,6 +3127,7 @@ declare_lint_pass! {
|
||||||
DUPLICATE_MACRO_ATTRIBUTES,
|
DUPLICATE_MACRO_ATTRIBUTES,
|
||||||
SUSPICIOUS_AUTO_TRAIT_IMPLS,
|
SUSPICIOUS_AUTO_TRAIT_IMPLS,
|
||||||
UNEXPECTED_CFGS,
|
UNEXPECTED_CFGS,
|
||||||
|
DEPRECATED_WHERE_CLAUSE_LOCATION,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3737,3 +3738,36 @@ declare_lint! {
|
||||||
reference: "issue #93367 <https://github.com/rust-lang/rust/issues/93367>",
|
reference: "issue #93367 <https://github.com/rust-lang/rust/issues/93367>",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare_lint! {
|
||||||
|
/// The `deprecated_where_clause_location` lint detects when a where clause in front of the equals
|
||||||
|
/// in an associated type.
|
||||||
|
///
|
||||||
|
/// ### Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// #![feature(generic_associated_types)]
|
||||||
|
///
|
||||||
|
/// trait Trait {
|
||||||
|
/// type Assoc<'a> where Self: 'a;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// impl Trait for () {
|
||||||
|
/// type Assoc<'a> where Self: 'a = ();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// {{produces}}
|
||||||
|
///
|
||||||
|
/// ### Explanation
|
||||||
|
///
|
||||||
|
/// The preferred location for where clauses on associated types in impls
|
||||||
|
/// is after the type. However, for most of generic associated types development,
|
||||||
|
/// it was only accepted before the equals. To provide a transition period and
|
||||||
|
/// further evaluate this change, both are currently accepted. At some point in
|
||||||
|
/// the future, this may be disallowed at an edition boundary; but, that is
|
||||||
|
/// undecided currently.
|
||||||
|
pub DEPRECATED_WHERE_CLAUSE_LOCATION,
|
||||||
|
Warn,
|
||||||
|
"deprecated where clause location"
|
||||||
|
}
|
||||||
|
|
|
@ -427,6 +427,7 @@ pub enum BuiltinLintDiagnostics {
|
||||||
NamedAsmLabel(String),
|
NamedAsmLabel(String),
|
||||||
UnicodeTextFlow(Span, String),
|
UnicodeTextFlow(Span, String),
|
||||||
UnexpectedCfg((Symbol, Span), Option<(Symbol, Span)>),
|
UnexpectedCfg((Symbol, Span), Option<(Symbol, Span)>),
|
||||||
|
DeprecatedWhereclauseLocation(Span, String),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Lints that are buffered up early on in the `Session` before the
|
/// Lints that are buffered up early on in the `Session` before the
|
||||||
|
|
|
@ -13,11 +13,12 @@ use rustc_ast::{EnumDef, FieldDef, Generics, TraitRef, Ty, TyKind, Variant, Vari
|
||||||
use rustc_ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, VisibilityKind};
|
use rustc_ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, VisibilityKind};
|
||||||
use rustc_ast::{MacArgs, MacCall, MacDelimiter};
|
use rustc_ast::{MacArgs, MacCall, MacDelimiter};
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_errors::{struct_span_err, Applicability, ErrorGuaranteed, PResult, StashKey};
|
use rustc_errors::{struct_span_err, Applicability, PResult, StashKey};
|
||||||
use rustc_span::edition::{Edition, LATEST_STABLE_EDITION};
|
use rustc_span::edition::{Edition, LATEST_STABLE_EDITION};
|
||||||
use rustc_span::lev_distance::lev_distance;
|
use rustc_span::lev_distance::lev_distance;
|
||||||
use rustc_span::source_map::{self, Span};
|
use rustc_span::source_map::{self, Span};
|
||||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||||
|
use rustc_span::DUMMY_SP;
|
||||||
|
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
@ -801,44 +802,6 @@ impl<'a> Parser<'a> {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Emits an error that the where clause at the end of a type alias is not
|
|
||||||
/// allowed and suggests moving it.
|
|
||||||
fn error_ty_alias_where(
|
|
||||||
&self,
|
|
||||||
before_where_clause_present: bool,
|
|
||||||
before_where_clause_span: Span,
|
|
||||||
after_predicates: &[WherePredicate],
|
|
||||||
after_where_clause_span: Span,
|
|
||||||
) -> ErrorGuaranteed {
|
|
||||||
let mut err =
|
|
||||||
self.struct_span_err(after_where_clause_span, "where clause not allowed here");
|
|
||||||
if !after_predicates.is_empty() {
|
|
||||||
let mut state = crate::pprust::State::new();
|
|
||||||
if !before_where_clause_present {
|
|
||||||
state.space();
|
|
||||||
state.word_space("where");
|
|
||||||
} else {
|
|
||||||
state.word_space(",");
|
|
||||||
}
|
|
||||||
let mut first = true;
|
|
||||||
for p in after_predicates.iter() {
|
|
||||||
if !first {
|
|
||||||
state.word_space(",");
|
|
||||||
}
|
|
||||||
first = false;
|
|
||||||
state.print_where_predicate(p);
|
|
||||||
}
|
|
||||||
let suggestion = state.s.eof();
|
|
||||||
err.span_suggestion(
|
|
||||||
before_where_clause_span.shrink_to_hi(),
|
|
||||||
"move it here",
|
|
||||||
suggestion,
|
|
||||||
Applicability::MachineApplicable,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
err.emit()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parses a `type` alias with the following grammar:
|
/// Parses a `type` alias with the following grammar:
|
||||||
/// ```
|
/// ```
|
||||||
/// TypeAlias = "type" Ident Generics {":" GenericBounds}? {"=" Ty}? ";" ;
|
/// TypeAlias = "type" Ident Generics {":" GenericBounds}? {"=" Ty}? ";" ;
|
||||||
|
@ -851,27 +814,40 @@ impl<'a> Parser<'a> {
|
||||||
// Parse optional colon and param bounds.
|
// Parse optional colon and param bounds.
|
||||||
let bounds =
|
let bounds =
|
||||||
if self.eat(&token::Colon) { self.parse_generic_bounds(None)? } else { Vec::new() };
|
if self.eat(&token::Colon) { self.parse_generic_bounds(None)? } else { Vec::new() };
|
||||||
|
let before_where_clause = self.parse_where_clause()?;
|
||||||
generics.where_clause = self.parse_where_clause()?;
|
|
||||||
|
|
||||||
let ty = if self.eat(&token::Eq) { Some(self.parse_ty()?) } else { None };
|
let ty = if self.eat(&token::Eq) { Some(self.parse_ty()?) } else { None };
|
||||||
|
|
||||||
if self.token.is_keyword(kw::Where) {
|
let after_where_clause = self.parse_where_clause()?;
|
||||||
let after_where_clause = self.parse_where_clause()?;
|
|
||||||
|
|
||||||
self.error_ty_alias_where(
|
let where_clauses = (
|
||||||
generics.where_clause.has_where_token,
|
TyAliasWhereClause(before_where_clause.has_where_token, before_where_clause.span),
|
||||||
generics.where_clause.span,
|
TyAliasWhereClause(after_where_clause.has_where_token, after_where_clause.span),
|
||||||
&after_where_clause.predicates,
|
);
|
||||||
after_where_clause.span,
|
let where_predicates_split = before_where_clause.predicates.len();
|
||||||
);
|
let mut predicates = before_where_clause.predicates;
|
||||||
|
predicates.extend(after_where_clause.predicates.into_iter());
|
||||||
generics.where_clause.predicates.extend(after_where_clause.predicates.into_iter());
|
let where_clause = WhereClause {
|
||||||
}
|
has_where_token: before_where_clause.has_where_token
|
||||||
|
|| after_where_clause.has_where_token,
|
||||||
|
predicates,
|
||||||
|
span: DUMMY_SP,
|
||||||
|
};
|
||||||
|
generics.where_clause = where_clause;
|
||||||
|
|
||||||
self.expect_semi()?;
|
self.expect_semi()?;
|
||||||
|
|
||||||
Ok((ident, ItemKind::TyAlias(Box::new(TyAlias { defaultness, generics, bounds, ty }))))
|
Ok((
|
||||||
|
ident,
|
||||||
|
ItemKind::TyAlias(Box::new(TyAlias {
|
||||||
|
defaultness,
|
||||||
|
generics,
|
||||||
|
where_clauses,
|
||||||
|
where_predicates_split,
|
||||||
|
bounds,
|
||||||
|
ty,
|
||||||
|
})),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a `UseTree`.
|
/// Parses a `UseTree`.
|
||||||
|
|
|
@ -24,7 +24,7 @@ trait Bar {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Bar for Foo {
|
impl Bar for Foo {
|
||||||
type Assoc where Self: Sized = Foo;
|
type Assoc = Foo where Self: Sized;
|
||||||
//~^ ERROR where clauses on associated types are unstable
|
//~^ ERROR where clauses on associated types are unstable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ LL | type Assoc where Self: Sized;
|
||||||
error[E0658]: where clauses on associated types are unstable
|
error[E0658]: where clauses on associated types are unstable
|
||||||
--> $DIR/feature-gate-generic_associated_types.rs:27:5
|
--> $DIR/feature-gate-generic_associated_types.rs:27:5
|
||||||
|
|
|
|
||||||
LL | type Assoc where Self: Sized = Foo;
|
LL | type Assoc = Foo where Self: Sized;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
|
= note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
|
||||||
|
|
|
@ -12,7 +12,7 @@ pub trait AsRef2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> AsRef2 for Vec<T> {
|
impl<T> AsRef2 for Vec<T> {
|
||||||
type Output<'a> where Self: 'a = &'a [T];
|
type Output<'a> = &'a [T] where Self: 'a;
|
||||||
|
|
||||||
fn as_ref2<'a>(&'a self) -> Self::Output<'a> {
|
fn as_ref2<'a>(&'a self) -> Self::Output<'a> {
|
||||||
&self[..]
|
&self[..]
|
||||||
|
@ -33,7 +33,7 @@ where
|
||||||
T: AsRef2<Output<'b> = &'b [U]>,
|
T: AsRef2<Output<'b> = &'b [U]>,
|
||||||
U: 'b
|
U: 'b
|
||||||
{
|
{
|
||||||
type Output<'a> where Self: 'a = FooRef<'a, U>;
|
type Output<'a> = FooRef<'a, U> where Self: 'a;
|
||||||
|
|
||||||
fn as_ref2<'a>(&'a self) -> Self::Output<'a> {
|
fn as_ref2<'a>(&'a self) -> Self::Output<'a> {
|
||||||
FooRef(self.0.as_ref2())
|
FooRef(self.0.as_ref2())
|
||||||
|
|
|
@ -13,7 +13,7 @@ trait MyTrait {
|
||||||
struct Foo;
|
struct Foo;
|
||||||
|
|
||||||
impl MyTrait for Foo {
|
impl MyTrait for Foo {
|
||||||
type Assoc<'a, 'b> where 'b: 'a = u32;
|
type Assoc<'a, 'b> = u32 where 'b: 'a;
|
||||||
|
|
||||||
fn do_sth(_: u32) {}
|
fn do_sth(_: u32) {}
|
||||||
// fn do_sth(_: Self::Assoc<'static, 'static>) {}
|
// fn do_sth(_: Self::Assoc<'static, 'static>) {}
|
||||||
|
|
|
@ -32,7 +32,7 @@ impl CollectionFamily for VecFamily {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Collection<T> for Vec<T> {
|
impl<T> Collection<T> for Vec<T> {
|
||||||
type Iter<'iter> where T: 'iter = std::slice::Iter<'iter, T>;
|
type Iter<'iter> = std::slice::Iter<'iter, T> where T: 'iter;
|
||||||
type Family = VecFamily;
|
type Family = VecFamily;
|
||||||
|
|
||||||
fn empty() -> Self {
|
fn empty() -> Self {
|
||||||
|
|
|
@ -32,7 +32,7 @@ impl CollectionFamily for VecFamily {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Collection<T> for Vec<T> {
|
impl<T> Collection<T> for Vec<T> {
|
||||||
type Iter<'iter> where T: 'iter = std::slice::Iter<'iter, T>;
|
type Iter<'iter> = std::slice::Iter<'iter, T> where T: 'iter;
|
||||||
type Family = VecFamily;
|
type Family = VecFamily;
|
||||||
|
|
||||||
fn empty() -> Self {
|
fn empty() -> Self {
|
||||||
|
|
|
@ -16,9 +16,9 @@ trait Baz {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Baz for T where T: Foo {
|
impl<T> Baz for T where T: Foo {
|
||||||
type Quux<'a> where T: 'a = T;
|
type Quux<'a> = T where T: 'a;
|
||||||
|
|
||||||
type Baa<'a> where T: 'a = &'a <T as Foo>::Bar<'a, 'static>;
|
type Baa<'a> = &'a <T as Foo>::Bar<'a, 'static> where T: 'a;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -15,7 +15,7 @@ impl Foo for Fooy {
|
||||||
struct Fooer<T>(T);
|
struct Fooer<T>(T);
|
||||||
|
|
||||||
impl<T> Foo for Fooer<T> {
|
impl<T> Foo for Fooer<T> {
|
||||||
type A<'x> where T: 'x = &'x ();
|
type A<'x> = &'x () where T: 'x;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn f(_arg : Box<dyn for<'a> Foo<A<'a> = &'a ()>>) {}
|
fn f(_arg : Box<dyn for<'a> Foo<A<'a> = &'a ()>>) {}
|
||||||
|
|
|
@ -19,7 +19,7 @@ impl Foo for Bar {
|
||||||
type Assoc = usize;
|
type Assoc = usize;
|
||||||
type Assoc2<T> = Vec<T>;
|
type Assoc2<T> = Vec<T>;
|
||||||
//~^ ERROR `T` doesn't implement `std::fmt::Display`
|
//~^ ERROR `T` doesn't implement `std::fmt::Display`
|
||||||
type Assoc3<T> where T: Iterator = Vec<T>;
|
type Assoc3<T> = Vec<T> where T: Iterator;
|
||||||
//~^ ERROR impl has stricter requirements than trait
|
//~^ ERROR impl has stricter requirements than trait
|
||||||
type WithDefault<'a, T: Debug + 'a> = &'a dyn Iterator<Item=T>;
|
type WithDefault<'a, T: Debug + 'a> = &'a dyn Iterator<Item=T>;
|
||||||
type NoGenerics = ::std::cell::Cell<i32>;
|
type NoGenerics = ::std::cell::Cell<i32>;
|
||||||
|
|
|
@ -16,7 +16,7 @@ error[E0276]: impl has stricter requirements than trait
|
||||||
LL | type Assoc3<T>;
|
LL | type Assoc3<T>;
|
||||||
| --------------- definition of `Assoc3` from trait
|
| --------------- definition of `Assoc3` from trait
|
||||||
...
|
...
|
||||||
LL | type Assoc3<T> where T: Iterator = Vec<T>;
|
LL | type Assoc3<T> = Vec<T> where T: Iterator;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: Iterator`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: Iterator`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
|
@ -12,12 +12,12 @@ trait Foo {
|
||||||
struct Fooy<T>(T);
|
struct Fooy<T>(T);
|
||||||
|
|
||||||
impl<T> Foo for Fooy<T> {
|
impl<T> Foo for Fooy<T> {
|
||||||
type A<'a> where Self: 'static = (&'a ());
|
type A<'a> = (&'a ()) where Self: 'static;
|
||||||
//~^ ERROR `impl` associated type
|
//~^ ERROR `impl` associated type
|
||||||
type B<'a, 'b> where 'b: 'a = (&'a(), &'b ());
|
type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
|
||||||
//~^ ERROR `impl` associated type
|
//~^ ERROR `impl` associated type
|
||||||
//~| ERROR lifetime bound not satisfied
|
//~| ERROR lifetime bound not satisfied
|
||||||
type C where Self: Copy = String;
|
type C = String where Self: Copy;
|
||||||
//~^ ERROR the trait bound `T: Copy` is not satisfied
|
//~^ ERROR the trait bound `T: Copy` is not satisfied
|
||||||
fn d() where Self: Copy {}
|
fn d() where Self: Copy {}
|
||||||
//~^ ERROR the trait bound `T: Copy` is not satisfied
|
//~^ ERROR the trait bound `T: Copy` is not satisfied
|
||||||
|
|
|
@ -4,7 +4,7 @@ error: `impl` associated type signature for `A` doesn't match `trait` associated
|
||||||
LL | type A<'a> where Self: 'a;
|
LL | type A<'a> where Self: 'a;
|
||||||
| -------------------------- expected
|
| -------------------------- expected
|
||||||
...
|
...
|
||||||
LL | type A<'a> where Self: 'static = (&'a ());
|
LL | type A<'a> = (&'a ()) where Self: 'static;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found
|
||||||
|
|
||||||
error: `impl` associated type signature for `B` doesn't match `trait` associated type signature
|
error: `impl` associated type signature for `B` doesn't match `trait` associated type signature
|
||||||
|
@ -13,35 +13,33 @@ error: `impl` associated type signature for `B` doesn't match `trait` associated
|
||||||
LL | type B<'a, 'b> where 'a: 'b;
|
LL | type B<'a, 'b> where 'a: 'b;
|
||||||
| ---------------------------- expected
|
| ---------------------------- expected
|
||||||
...
|
...
|
||||||
LL | type B<'a, 'b> where 'b: 'a = (&'a(), &'b ());
|
LL | type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found
|
||||||
|
|
||||||
error[E0478]: lifetime bound not satisfied
|
error[E0478]: lifetime bound not satisfied
|
||||||
--> $DIR/impl_bounds.rs:17:35
|
--> $DIR/impl_bounds.rs:17:22
|
||||||
|
|
|
|
||||||
LL | type B<'a, 'b> where 'a: 'b;
|
LL | type B<'a, 'b> where 'a: 'b;
|
||||||
| ---------------------------- definition of `B` from trait
|
| ---------------------------- definition of `B` from trait
|
||||||
...
|
...
|
||||||
LL | type B<'a, 'b> where 'b: 'a = (&'a(), &'b ());
|
LL | type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
|
||||||
| - ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^ - help: try copying this clause from the trait: `, 'a: 'b`
|
||||||
| |
|
|
||||||
| help: try copying this clause from the trait: `, 'a: 'b`
|
|
||||||
|
|
|
|
||||||
note: lifetime parameter instantiated with the lifetime `'a` as defined here
|
note: lifetime parameter instantiated with the lifetime `'a` as defined here
|
||||||
--> $DIR/impl_bounds.rs:17:12
|
--> $DIR/impl_bounds.rs:17:12
|
||||||
|
|
|
|
||||||
LL | type B<'a, 'b> where 'b: 'a = (&'a(), &'b ());
|
LL | type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
|
||||||
| ^^
|
| ^^
|
||||||
note: but lifetime parameter must outlive the lifetime `'b` as defined here
|
note: but lifetime parameter must outlive the lifetime `'b` as defined here
|
||||||
--> $DIR/impl_bounds.rs:17:16
|
--> $DIR/impl_bounds.rs:17:16
|
||||||
|
|
|
|
||||||
LL | type B<'a, 'b> where 'b: 'a = (&'a(), &'b ());
|
LL | type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
|
||||||
| ^^
|
| ^^
|
||||||
|
|
||||||
error[E0277]: the trait bound `T: Copy` is not satisfied
|
error[E0277]: the trait bound `T: Copy` is not satisfied
|
||||||
--> $DIR/impl_bounds.rs:20:5
|
--> $DIR/impl_bounds.rs:20:5
|
||||||
|
|
|
|
||||||
LL | type C where Self: Copy = String;
|
LL | type C = String where Self: Copy;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
|
||||||
|
|
|
|
||||||
note: required because of the requirements on the impl of `Copy` for `Fooy<T>`
|
note: required because of the requirements on the impl of `Copy` for `Fooy<T>`
|
||||||
|
|
|
@ -22,9 +22,9 @@ impl Foo for Fooy {
|
||||||
struct Fooer<T>(T);
|
struct Fooer<T>(T);
|
||||||
|
|
||||||
impl<T> Foo for Fooer<T> {
|
impl<T> Foo for Fooer<T> {
|
||||||
type A<'x> where T: 'x = (&'x ());
|
type A<'x> = (&'x ()) where T: 'x;
|
||||||
type B<'u, 'v> where 'u: 'v = (&'v &'u ());
|
type B<'u, 'v> = (&'v &'u ()) where 'u: 'v;
|
||||||
type C where Self: Clone + ToOwned = String;
|
type C = String where Self: Clone + ToOwned;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -9,7 +9,7 @@ trait Foo {
|
||||||
struct Bar;
|
struct Bar;
|
||||||
|
|
||||||
impl Foo for Bar {
|
impl Foo for Bar {
|
||||||
type Assoc3<T> where T: Iterator = Vec<T>;
|
type Assoc3<T> = Vec<T> where T: Iterator;
|
||||||
//~^ ERROR impl has stricter requirements than trait
|
//~^ ERROR impl has stricter requirements than trait
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ error[E0276]: impl has stricter requirements than trait
|
||||||
LL | type Assoc3<T>;
|
LL | type Assoc3<T>;
|
||||||
| --------------- definition of `Assoc3` from trait
|
| --------------- definition of `Assoc3` from trait
|
||||||
...
|
...
|
||||||
LL | type Assoc3<T> where T: Iterator = Vec<T>;
|
LL | type Assoc3<T> = Vec<T> where T: Iterator;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: Iterator`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: Iterator`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
|
@ -29,7 +29,7 @@ impl<T> Windows<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Iter for Windows<T> {
|
impl<T> Iter for Windows<T> {
|
||||||
type Item<'a> where T: 'a = &'a mut [T];
|
type Item<'a> = &'a mut [T] where T: 'a;
|
||||||
|
|
||||||
fn next<'a>(&'a mut self) -> Option<Self::Item<'a>> {
|
fn next<'a>(&'a mut self) -> Option<Self::Item<'a>> {
|
||||||
let slice = self.items.get_mut(self.start..self.start + self.len)?;
|
let slice = self.items.get_mut(self.start..self.start + self.len)?;
|
||||||
|
|
|
@ -22,7 +22,7 @@ trait MapLike<K, V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K: Ord, V: 'static> MapLike<K, V> for std::collections::BTreeMap<K, V> {
|
impl<K: Ord, V: 'static> MapLike<K, V> for std::collections::BTreeMap<K, V> {
|
||||||
type VRefCont<'a> where Self: 'a = &'a V;
|
type VRefCont<'a> = &'a V where Self: 'a;
|
||||||
fn get<'a>(&'a self, key: &K) -> Option<&'a V> {
|
fn get<'a>(&'a self, key: &K) -> Option<&'a V> {
|
||||||
std::collections::BTreeMap::get(self, key)
|
std::collections::BTreeMap::get(self, key)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,9 @@ error[E0309]: the parameter type `T` may not live long enough
|
||||||
--> $DIR/issue-84931.rs:15:21
|
--> $DIR/issue-84931.rs:15:21
|
||||||
|
|
|
|
||||||
LL | type Item<'a> = &'a mut T;
|
LL | type Item<'a> = &'a mut T;
|
||||||
| - ^^^^^^^^^ ...so that the reference type `&'a mut T` does not outlive the data it points at
|
| ^^^^^^^^^- help: consider adding a where clause: `where T: 'a`
|
||||||
| |
|
| |
|
||||||
| help: consider adding a where clause: `where T: 'a`
|
| ...so that the reference type `&'a mut T` does not outlive the data it points at
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -21,13 +21,10 @@ where
|
||||||
Right: HasChildrenOf,
|
Right: HasChildrenOf,
|
||||||
{
|
{
|
||||||
type T = Either<Left::T, Right::T>;
|
type T = Either<Left::T, Right::T>;
|
||||||
// We used to error below because the where clause doesn't match the trait.
|
type TRef<'a> = Either<&'a Left::T, &'a Right::T>
|
||||||
// Now, we error early on the trait itself.
|
|
||||||
type TRef<'a>
|
|
||||||
where
|
where
|
||||||
<Left as HasChildrenOf>::T: 'a,
|
<Left as HasChildrenOf>::T: 'a,
|
||||||
<Right as HasChildrenOf>::T: 'a
|
<Right as HasChildrenOf>::T: 'a;
|
||||||
= Either<&'a Left::T, &'a Right::T>;
|
|
||||||
|
|
||||||
fn ref_children<'a>(&'a self) -> Vec<Self::TRef<'a>> {
|
fn ref_children<'a>(&'a self) -> Vec<Self::TRef<'a>> {
|
||||||
todo!()
|
todo!()
|
||||||
|
|
|
@ -27,11 +27,10 @@ impl<T, Criteria> SearchableResourceExt<Criteria> for T
|
||||||
where
|
where
|
||||||
T: SearchableResource<Criteria>,
|
T: SearchableResource<Criteria>,
|
||||||
{
|
{
|
||||||
type Future<'f, A, B: 'f>
|
type Future<'f, A, B: 'f> = SearchFutureTy<'f, A, B>
|
||||||
where
|
where
|
||||||
A: SearchableResource<B> + ?Sized + 'f,
|
A: SearchableResource<B> + ?Sized + 'f,
|
||||||
Self: 'f,
|
Self: 'f;
|
||||||
= SearchFutureTy<'f, A, B>;
|
|
||||||
|
|
||||||
fn search<'c>(&'c self, _client: &'c ()) -> Self::Future<'c, Self, Criteria> {
|
fn search<'c>(&'c self, _client: &'c ()) -> Self::Future<'c, Self, Criteria> {
|
||||||
async move { todo!() }
|
async move { todo!() }
|
||||||
|
|
|
@ -5,9 +5,7 @@ LL | type Fut<'a> where Self: 'a;
|
||||||
| ---------------------------- definition of `Fut` from trait
|
| ---------------------------- definition of `Fut` from trait
|
||||||
...
|
...
|
||||||
LL | type Fut<'a> = impl Future<Output = ()>;
|
LL | type Fut<'a> = impl Future<Output = ()>;
|
||||||
| - ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^- help: try copying this clause from the trait: `where Self: 'a`
|
||||||
| |
|
|
||||||
| help: try copying this clause from the trait: `where Self: 'a`
|
|
||||||
|
|
|
|
||||||
note: type must outlive the lifetime `'a` as defined here
|
note: type must outlive the lifetime `'a` as defined here
|
||||||
--> $DIR/issue-90014.rs:14:14
|
--> $DIR/issue-90014.rs:14:14
|
||||||
|
|
|
@ -9,10 +9,9 @@ trait Foo<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Foo<T> for () {
|
impl<T> Foo<T> for () {
|
||||||
type Type<'a>
|
type Type<'a> = ()
|
||||||
where
|
where
|
||||||
T: 'a,
|
T: 'a;
|
||||||
= ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foo<T>() {
|
fn foo<T>() {
|
||||||
|
|
|
@ -7,9 +7,7 @@ LL | | Self: 'a;
|
||||||
| |_________________- definition of `TextureIter` from trait
|
| |_________________- definition of `TextureIter` from trait
|
||||||
...
|
...
|
||||||
LL | type TextureIter<'a> = std::option::IntoIter<&'a Texture>;
|
LL | type TextureIter<'a> = std::option::IntoIter<&'a Texture>;
|
||||||
| - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: try copying this clause from the trait: `where Self: 'a`
|
||||||
| |
|
|
||||||
| help: try copying this clause from the trait: `where Self: 'a`
|
|
||||||
|
|
|
|
||||||
note: type must outlive the lifetime `'a` as defined here
|
note: type must outlive the lifetime `'a` as defined here
|
||||||
--> $DIR/issue-92033.rs:22:22
|
--> $DIR/issue-92033.rs:22:22
|
||||||
|
|
|
@ -17,10 +17,9 @@ struct KeySegment_Broken<T> {
|
||||||
key: T,
|
key: T,
|
||||||
}
|
}
|
||||||
impl<S: HasAssoc> Iterate<S> for KeySegment_Broken<S::Assoc> {
|
impl<S: HasAssoc> Iterate<S> for KeySegment_Broken<S::Assoc> {
|
||||||
type Iter<'a>
|
type Iter<'a> = ()
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a;
|
||||||
= ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -11,8 +11,8 @@ trait Iterable {
|
||||||
|
|
||||||
// Impl for struct type
|
// Impl for struct type
|
||||||
impl<T> Iterable for Vec<T> {
|
impl<T> Iterable for Vec<T> {
|
||||||
type Item<'a> where T: 'a = <std::slice::Iter<'a, T> as Iterator>::Item;
|
type Item<'a> = <std::slice::Iter<'a, T> as Iterator>::Item where T: 'a;
|
||||||
type Iter<'a> where T: 'a = std::slice::Iter<'a, T>;
|
type Iter<'a> = std::slice::Iter<'a, T> where T: 'a;
|
||||||
|
|
||||||
fn iter<'a>(&'a self) -> Self::Iter<'a> {
|
fn iter<'a>(&'a self) -> Self::Iter<'a> {
|
||||||
self[..].iter()
|
self[..].iter()
|
||||||
|
@ -21,8 +21,8 @@ impl<T> Iterable for Vec<T> {
|
||||||
|
|
||||||
// Impl for a primitive type
|
// Impl for a primitive type
|
||||||
impl<T> Iterable for [T] {
|
impl<T> Iterable for [T] {
|
||||||
type Item<'a> where T: 'a = <std::slice::Iter<'a, T> as Iterator>::Item;
|
type Item<'a> = <std::slice::Iter<'a, T> as Iterator>::Item where T: 'a;
|
||||||
type Iter<'a> where T: 'a = std::slice::Iter<'a, T>;
|
type Iter<'a> = std::slice::Iter<'a, T> where T: 'a;
|
||||||
|
|
||||||
fn iter<'a>(&'a self) -> Self::Iter<'a> {
|
fn iter<'a>(&'a self) -> Self::Iter<'a> {
|
||||||
self.iter()
|
self.iter()
|
||||||
|
|
|
@ -6,7 +6,7 @@ trait Foo {
|
||||||
type Assoc<'a, 'b>;
|
type Assoc<'a, 'b>;
|
||||||
}
|
}
|
||||||
impl Foo for () {
|
impl Foo for () {
|
||||||
type Assoc<'a, 'b> where 'a: 'b = ();
|
type Assoc<'a, 'b> = () where 'a: 'b;
|
||||||
//~^ `impl` associated type
|
//~^ `impl` associated type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ error: `impl` associated type signature for `Assoc` doesn't match `trait` associ
|
||||||
LL | type Assoc<'a, 'b>;
|
LL | type Assoc<'a, 'b>;
|
||||||
| ------------------- expected
|
| ------------------- expected
|
||||||
...
|
...
|
||||||
LL | type Assoc<'a, 'b> where 'a: 'b = ();
|
LL | type Assoc<'a, 'b> = () where 'a: 'b;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
|
@ -22,7 +22,7 @@ impl<T> Foo for Number<T> {
|
||||||
// }
|
// }
|
||||||
// ```
|
// ```
|
||||||
// which it is :)
|
// which it is :)
|
||||||
type Item where [T]: Sized = [T];
|
type Item = [T] where [T]: Sized;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct OnlySized<T> where T: Sized { f: T }
|
struct OnlySized<T> where T: Sized { f: T }
|
||||||
|
|
|
@ -24,7 +24,7 @@ impl Foo for Number {
|
||||||
// }
|
// }
|
||||||
// ```
|
// ```
|
||||||
// which it is :)
|
// which it is :)
|
||||||
type Item where str: Sized = str;
|
type Item = str where str: Sized;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct OnlySized<T> where T: Sized { f: T }
|
struct OnlySized<T> where T: Sized { f: T }
|
||||||
|
|
|
@ -30,7 +30,7 @@ struct StreamEnumerate<I> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: StreamingIterator> StreamingIterator for StreamEnumerate<I> {
|
impl<I: StreamingIterator> StreamingIterator for StreamEnumerate<I> {
|
||||||
type Item<'a> where Self: 'a = (usize, I::Item<'a>);
|
type Item<'a> = (usize, I::Item<'a>) where Self: 'a;
|
||||||
fn next<'a>(&'a mut self) -> Option<Self::Item<'a>> {
|
fn next<'a>(&'a mut self) -> Option<Self::Item<'a>> {
|
||||||
match self.iter.next() {
|
match self.iter.next() {
|
||||||
None => None,
|
None => None,
|
||||||
|
@ -44,7 +44,7 @@ impl<I: StreamingIterator> StreamingIterator for StreamEnumerate<I> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: Iterator> StreamingIterator for I {
|
impl<I: Iterator> StreamingIterator for I {
|
||||||
type Item<'a> where Self: 'a = <I as Iterator>::Item;
|
type Item<'a> = <I as Iterator>::Item where Self: 'a;
|
||||||
fn next(&mut self) -> Option<<I as StreamingIterator>::Item<'_>> {
|
fn next(&mut self) -> Option<<I as StreamingIterator>::Item<'_>> {
|
||||||
Iterator::next(self)
|
Iterator::next(self)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,6 @@ type A where 'a:, = u8; // OK
|
||||||
type A where 'a: 'b + 'c = u8; // OK
|
type A where 'a: 'b + 'c = u8; // OK
|
||||||
type A where = u8; // OK
|
type A where = u8; // OK
|
||||||
type A where 'a: 'b + = u8; // OK
|
type A where 'a: 'b + = u8; // OK
|
||||||
type A where , = u8; //~ ERROR expected one of `;`, `=`, lifetime, or type, found `,`
|
type A where , = u8; //~ ERROR expected one of `;`, `=`, `where`, lifetime, or type, found `,`
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: expected one of `;`, `=`, lifetime, or type, found `,`
|
error: expected one of `;`, `=`, `where`, lifetime, or type, found `,`
|
||||||
--> $DIR/bounds-lifetime-where.rs:8:14
|
--> $DIR/bounds-lifetime-where.rs:8:14
|
||||||
|
|
|
|
||||||
LL | type A where , = u8;
|
LL | type A where , = u8;
|
||||||
| ^ expected one of `;`, `=`, lifetime, or type
|
| ^ expected one of `;`, `=`, `where`, lifetime, or type
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
type bptr = &lifetime/isize; //~ ERROR expected one of `!`, `(`, `::`, `;`, or `<`, found `/`
|
type bptr = &lifetime/isize; //~ ERROR expected one of `!`, `(`, `::`, `;`, `<`, or `where`, found `/`
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: expected one of `!`, `(`, `::`, `;`, or `<`, found `/`
|
error: expected one of `!`, `(`, `::`, `;`, `<`, or `where`, found `/`
|
||||||
--> $DIR/removed-syntax-ptr-lifetime.rs:1:22
|
--> $DIR/removed-syntax-ptr-lifetime.rs:1:22
|
||||||
|
|
|
|
||||||
LL | type bptr = &lifetime/isize;
|
LL | type bptr = &lifetime/isize;
|
||||||
| ^ expected one of `!`, `(`, `::`, `;`, or `<`
|
| ^ expected one of `!`, `(`, `::`, `;`, `<`, or `where`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
30
src/test/ui/parser/type-alias-where-fixable.fixed
Normal file
30
src/test/ui/parser/type-alias-where-fixable.fixed
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// check-pass
|
||||||
|
// run-rustfix
|
||||||
|
|
||||||
|
#![feature(generic_associated_types)]
|
||||||
|
|
||||||
|
trait Trait {
|
||||||
|
// Fine.
|
||||||
|
type Assoc where u32: Copy;
|
||||||
|
// Fine.
|
||||||
|
type Assoc2 where u32: Copy, i32: Copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trait for u32 {
|
||||||
|
// Not fine, suggests moving.
|
||||||
|
type Assoc = () 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
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trait for i32 {
|
||||||
|
// Fine.
|
||||||
|
type Assoc = () where u32: Copy;
|
||||||
|
// Not fine, suggests moving both.
|
||||||
|
type Assoc2 = () where u32: Copy, i32: Copy;
|
||||||
|
//~^ WARNING where clause not allowed here
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
30
src/test/ui/parser/type-alias-where-fixable.rs
Normal file
30
src/test/ui/parser/type-alias-where-fixable.rs
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// check-pass
|
||||||
|
// run-rustfix
|
||||||
|
|
||||||
|
#![feature(generic_associated_types)]
|
||||||
|
|
||||||
|
trait Trait {
|
||||||
|
// Fine.
|
||||||
|
type Assoc where u32: Copy;
|
||||||
|
// Fine.
|
||||||
|
type Assoc2 where u32: Copy, i32: Copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trait for u32 {
|
||||||
|
// Not fine, suggests moving.
|
||||||
|
type Assoc 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
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trait for i32 {
|
||||||
|
// Fine.
|
||||||
|
type Assoc = () where u32: Copy;
|
||||||
|
// Not fine, suggests moving both.
|
||||||
|
type Assoc2 where u32: Copy, i32: Copy = ();
|
||||||
|
//~^ WARNING where clause not allowed here
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
42
src/test/ui/parser/type-alias-where-fixable.stderr
Normal file
42
src/test/ui/parser/type-alias-where-fixable.stderr
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
warning: where clause not allowed here
|
||||||
|
--> $DIR/type-alias-where-fixable.rs:15:16
|
||||||
|
|
|
||||||
|
LL | type Assoc where u32: Copy = ();
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `#[warn(deprecated_where_clause_location)]` on by default
|
||||||
|
= note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
|
||||||
|
help: move it to the end of the type declaration
|
||||||
|
|
|
||||||
|
LL - type Assoc where u32: Copy = ();
|
||||||
|
LL + type Assoc = () where u32: Copy;
|
||||||
|
|
|
||||||
|
|
||||||
|
warning: where clause not allowed here
|
||||||
|
--> $DIR/type-alias-where-fixable.rs:18:17
|
||||||
|
|
|
||||||
|
LL | type Assoc2 where u32: Copy = () where i32: Copy;
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
|
||||||
|
help: move it to the end of the type declaration
|
||||||
|
|
|
||||||
|
LL - type Assoc2 where u32: Copy = () where i32: Copy;
|
||||||
|
LL + type Assoc2 = () where i32: Copy, u32: Copy;
|
||||||
|
|
|
||||||
|
|
||||||
|
warning: where clause not allowed here
|
||||||
|
--> $DIR/type-alias-where-fixable.rs:26:17
|
||||||
|
|
|
||||||
|
LL | type Assoc2 where u32: Copy, i32: Copy = ();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
|
||||||
|
help: move it to the end of the type declaration
|
||||||
|
|
|
||||||
|
LL - type Assoc2 where u32: Copy, i32: Copy = ();
|
||||||
|
LL + type Assoc2 = () where u32: Copy, i32: Copy;
|
||||||
|
|
|
||||||
|
|
||||||
|
warning: 3 warnings emitted
|
||||||
|
|
|
@ -6,32 +6,8 @@
|
||||||
type Foo where u32: Copy = ();
|
type Foo where u32: Copy = ();
|
||||||
// Not fine.
|
// Not fine.
|
||||||
type Bar = () where u32: Copy;
|
type Bar = () where u32: Copy;
|
||||||
//~^ ERROR where clause not allowed here
|
//~^ ERROR where clauses are not allowed
|
||||||
type Baz = () where;
|
type Baz = () where;
|
||||||
//~^ ERROR where clause not allowed here
|
//~^ ERROR where clauses are not allowed
|
||||||
|
|
||||||
trait Trait {
|
|
||||||
// Fine.
|
|
||||||
type Assoc where u32: Copy;
|
|
||||||
// Fine.
|
|
||||||
type Assoc2 where u32: Copy, i32: Copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Trait for u32 {
|
|
||||||
// Fine.
|
|
||||||
type Assoc where u32: Copy = ();
|
|
||||||
// Not fine, suggests moving `i32: Copy`
|
|
||||||
type Assoc2 where u32: Copy = () where i32: Copy;
|
|
||||||
//~^ ERROR where clause not allowed here
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Trait for i32 {
|
|
||||||
// Not fine, suggests moving `u32: Copy`
|
|
||||||
type Assoc = () where u32: Copy;
|
|
||||||
//~^ ERROR where clause not allowed here
|
|
||||||
// Not fine, suggests moving both.
|
|
||||||
type Assoc2 = () where u32: Copy, i32: Copy;
|
|
||||||
//~^ ERROR where clause not allowed here
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,40 +1,18 @@
|
||||||
error: where clause not allowed here
|
error: where clauses are not allowed after the type for type aliases
|
||||||
--> $DIR/type-alias-where.rs:8:15
|
--> $DIR/type-alias-where.rs:8:15
|
||||||
|
|
|
|
||||||
LL | type Bar = () where u32: Copy;
|
LL | type Bar = () where u32: Copy;
|
||||||
| - ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
| |
|
|
|
||||||
| help: move it here: `where u32: Copy`
|
= note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
|
||||||
|
|
||||||
error: where clause not allowed here
|
error: where clauses are not allowed after the type for type aliases
|
||||||
--> $DIR/type-alias-where.rs:10:15
|
--> $DIR/type-alias-where.rs:10:15
|
||||||
|
|
|
|
||||||
LL | type Baz = () where;
|
LL | type Baz = () where;
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
error: where clause not allowed here
|
|
||||||
--> $DIR/type-alias-where.rs:24:38
|
|
||||||
|
|
|
|
||||||
LL | type Assoc2 where u32: Copy = () where i32: Copy;
|
= note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
|
||||||
| - ^^^^^^^^^^^^^^^
|
|
||||||
| |
|
|
||||||
| help: move it here: `, i32: Copy`
|
|
||||||
|
|
||||||
error: where clause not allowed here
|
error: aborting due to 2 previous errors
|
||||||
--> $DIR/type-alias-where.rs:30:21
|
|
||||||
|
|
|
||||||
LL | type Assoc = () where u32: Copy;
|
|
||||||
| - ^^^^^^^^^^^^^^^
|
|
||||||
| |
|
|
||||||
| help: move it here: `where u32: Copy`
|
|
||||||
|
|
||||||
error: where clause not allowed here
|
|
||||||
--> $DIR/type-alias-where.rs:33:22
|
|
||||||
|
|
|
||||||
LL | type Assoc2 = () where u32: Copy, i32: Copy;
|
|
||||||
| - ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
| |
|
|
||||||
| help: move it here: `where u32: Copy, i32: Copy`
|
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
|
||||||
|
|
||||||
|
|
|
@ -279,20 +279,8 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
|
||||||
(ForeignMod(l), ForeignMod(r)) => {
|
(ForeignMod(l), ForeignMod(r)) => {
|
||||||
both(&l.abi, &r.abi, eq_str_lit) && over(&l.items, &r.items, |l, r| eq_item(l, r, eq_foreign_item_kind))
|
both(&l.abi, &r.abi, eq_str_lit) && over(&l.items, &r.items, |l, r| eq_item(l, r, eq_foreign_item_kind))
|
||||||
},
|
},
|
||||||
(
|
(TyAlias(box ast::TyAlias { defaultness: ld, generics: lg, bounds: lb, ty: lt, .. }),
|
||||||
TyAlias(box ast::TyAlias {
|
TyAlias(box ast::TyAlias { defaultness: rd, generics: rg, bounds: rb, ty: rt, .. })) => {
|
||||||
defaultness: ld,
|
|
||||||
generics: lg,
|
|
||||||
bounds: lb,
|
|
||||||
ty: lt,
|
|
||||||
}),
|
|
||||||
TyAlias(box ast::TyAlias {
|
|
||||||
defaultness: rd,
|
|
||||||
generics: rg,
|
|
||||||
bounds: rb,
|
|
||||||
ty: rt,
|
|
||||||
}),
|
|
||||||
) => {
|
|
||||||
eq_defaultness(*ld, *rd)
|
eq_defaultness(*ld, *rd)
|
||||||
&& eq_generics(lg, rg)
|
&& eq_generics(lg, rg)
|
||||||
&& over(lb, rb, eq_generic_bound)
|
&& over(lb, rb, eq_generic_bound)
|
||||||
|
@ -382,20 +370,8 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
|
||||||
) => {
|
) => {
|
||||||
eq_defaultness(*ld, *rd) && eq_fn_sig(lf, rf) && eq_generics(lg, rg) && both(lb, rb, |l, r| eq_block(l, r))
|
eq_defaultness(*ld, *rd) && eq_fn_sig(lf, rf) && eq_generics(lg, rg) && both(lb, rb, |l, r| eq_block(l, r))
|
||||||
},
|
},
|
||||||
(
|
(TyAlias(box ast::TyAlias { defaultness: ld, generics: lg, bounds: lb, ty: lt, .. }),
|
||||||
TyAlias(box ast::TyAlias {
|
TyAlias(box ast::TyAlias { defaultness: rd, generics: rg, bounds: rb, ty: rt, .. })) => {
|
||||||
defaultness: ld,
|
|
||||||
generics: lg,
|
|
||||||
bounds: lb,
|
|
||||||
ty: lt,
|
|
||||||
}),
|
|
||||||
TyAlias(box ast::TyAlias {
|
|
||||||
defaultness: rd,
|
|
||||||
generics: rg,
|
|
||||||
bounds: rb,
|
|
||||||
ty: rt,
|
|
||||||
}),
|
|
||||||
) => {
|
|
||||||
eq_defaultness(*ld, *rd)
|
eq_defaultness(*ld, *rd)
|
||||||
&& eq_generics(lg, rg)
|
&& eq_generics(lg, rg)
|
||||||
&& over(lb, rb, eq_generic_bound)
|
&& over(lb, rb, eq_generic_bound)
|
||||||
|
@ -426,20 +402,8 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
|
||||||
) => {
|
) => {
|
||||||
eq_defaultness(*ld, *rd) && eq_fn_sig(lf, rf) && eq_generics(lg, rg) && both(lb, rb, |l, r| eq_block(l, r))
|
eq_defaultness(*ld, *rd) && eq_fn_sig(lf, rf) && eq_generics(lg, rg) && both(lb, rb, |l, r| eq_block(l, r))
|
||||||
},
|
},
|
||||||
(
|
(TyAlias(box ast::TyAlias { defaultness: ld, generics: lg, bounds: lb, ty: lt, .. }),
|
||||||
TyAlias(box ast::TyAlias {
|
TyAlias(box ast::TyAlias { defaultness: rd, generics: rg, bounds: rb, ty: rt, .. })) => {
|
||||||
defaultness: ld,
|
|
||||||
generics: lg,
|
|
||||||
bounds: lb,
|
|
||||||
ty: lt,
|
|
||||||
}),
|
|
||||||
TyAlias(box ast::TyAlias {
|
|
||||||
defaultness: rd,
|
|
||||||
generics: rg,
|
|
||||||
bounds: rb,
|
|
||||||
ty: rt,
|
|
||||||
}),
|
|
||||||
) => {
|
|
||||||
eq_defaultness(*ld, *rd)
|
eq_defaultness(*ld, *rd)
|
||||||
&& eq_generics(lg, rg)
|
&& eq_generics(lg, rg)
|
||||||
&& over(lb, rb, eq_generic_bound)
|
&& over(lb, rb, eq_generic_bound)
|
||||||
|
|
|
@ -694,7 +694,8 @@ pub(crate) fn format_impl(
|
||||||
let where_span_end = context.snippet_provider.opt_span_before(missing_span, "{");
|
let where_span_end = context.snippet_provider.opt_span_before(missing_span, "{");
|
||||||
let where_clause_str = rewrite_where_clause(
|
let where_clause_str = rewrite_where_clause(
|
||||||
context,
|
context,
|
||||||
&generics.where_clause,
|
&generics.where_clause.predicates,
|
||||||
|
generics.where_clause.span,
|
||||||
context.config.brace_style(),
|
context.config.brace_style(),
|
||||||
Shape::legacy(where_budget, offset.block_only()),
|
Shape::legacy(where_budget, offset.block_only()),
|
||||||
false,
|
false,
|
||||||
|
@ -1059,7 +1060,8 @@ pub(crate) fn format_trait(
|
||||||
let option = WhereClauseOption::snuggled(&generics_str);
|
let option = WhereClauseOption::snuggled(&generics_str);
|
||||||
let where_clause_str = rewrite_where_clause(
|
let where_clause_str = rewrite_where_clause(
|
||||||
context,
|
context,
|
||||||
&generics.where_clause,
|
&generics.where_clause.predicates,
|
||||||
|
generics.where_clause.span,
|
||||||
context.config.brace_style(),
|
context.config.brace_style(),
|
||||||
Shape::legacy(where_budget, offset.block_only()),
|
Shape::legacy(where_budget, offset.block_only()),
|
||||||
where_on_new_line,
|
where_on_new_line,
|
||||||
|
@ -1178,7 +1180,8 @@ impl<'a> Rewrite for TraitAliasBounds<'a> {
|
||||||
|
|
||||||
let where_str = rewrite_where_clause(
|
let where_str = rewrite_where_clause(
|
||||||
context,
|
context,
|
||||||
&self.generics.where_clause,
|
&self.generics.where_clause.predicates,
|
||||||
|
self.generics.where_clause.span,
|
||||||
context.config.brace_style(),
|
context.config.brace_style(),
|
||||||
shape,
|
shape,
|
||||||
false,
|
false,
|
||||||
|
@ -1437,7 +1440,8 @@ fn format_tuple_struct(
|
||||||
let option = WhereClauseOption::new(true, WhereClauseSpace::Newline);
|
let option = WhereClauseOption::new(true, WhereClauseSpace::Newline);
|
||||||
rewrite_where_clause(
|
rewrite_where_clause(
|
||||||
context,
|
context,
|
||||||
&generics.where_clause,
|
&generics.where_clause.predicates,
|
||||||
|
generics.where_clause.span,
|
||||||
context.config.brace_style(),
|
context.config.brace_style(),
|
||||||
Shape::legacy(where_budget, offset.block_only()),
|
Shape::legacy(where_budget, offset.block_only()),
|
||||||
false,
|
false,
|
||||||
|
@ -1503,6 +1507,8 @@ struct TyAliasRewriteInfo<'c, 'g>(
|
||||||
&'c RewriteContext<'c>,
|
&'c RewriteContext<'c>,
|
||||||
Indent,
|
Indent,
|
||||||
&'g ast::Generics,
|
&'g ast::Generics,
|
||||||
|
(ast::TyAliasWhereClause, ast::TyAliasWhereClause),
|
||||||
|
usize,
|
||||||
symbol::Ident,
|
symbol::Ident,
|
||||||
Span,
|
Span,
|
||||||
);
|
);
|
||||||
|
@ -1521,6 +1527,8 @@ pub(crate) fn rewrite_type_alias<'a, 'b>(
|
||||||
ref generics,
|
ref generics,
|
||||||
ref bounds,
|
ref bounds,
|
||||||
ref ty,
|
ref ty,
|
||||||
|
where_clauses,
|
||||||
|
where_predicates_split,
|
||||||
} = *ty_alias_kind;
|
} = *ty_alias_kind;
|
||||||
let ty_opt = ty.as_ref();
|
let ty_opt = ty.as_ref();
|
||||||
let (ident, vis) = match visitor_kind {
|
let (ident, vis) = match visitor_kind {
|
||||||
|
@ -1528,7 +1536,15 @@ pub(crate) fn rewrite_type_alias<'a, 'b>(
|
||||||
AssocTraitItem(i) | AssocImplItem(i) => (i.ident, &i.vis),
|
AssocTraitItem(i) | AssocImplItem(i) => (i.ident, &i.vis),
|
||||||
ForeignItem(i) => (i.ident, &i.vis),
|
ForeignItem(i) => (i.ident, &i.vis),
|
||||||
};
|
};
|
||||||
let rw_info = &TyAliasRewriteInfo(context, indent, generics, ident, span);
|
let rw_info = &TyAliasRewriteInfo(
|
||||||
|
context,
|
||||||
|
indent,
|
||||||
|
generics,
|
||||||
|
where_clauses,
|
||||||
|
where_predicates_split,
|
||||||
|
ident,
|
||||||
|
span,
|
||||||
|
);
|
||||||
let op_ty = opaque_ty(ty);
|
let op_ty = opaque_ty(ty);
|
||||||
// Type Aliases are formatted slightly differently depending on the context
|
// Type Aliases are formatted slightly differently depending on the context
|
||||||
// in which they appear, whether they are opaque, and whether they are associated.
|
// in which they appear, whether they are opaque, and whether they are associated.
|
||||||
|
@ -1564,7 +1580,22 @@ fn rewrite_ty<R: Rewrite>(
|
||||||
vis: &ast::Visibility,
|
vis: &ast::Visibility,
|
||||||
) -> Option<String> {
|
) -> Option<String> {
|
||||||
let mut result = String::with_capacity(128);
|
let mut result = String::with_capacity(128);
|
||||||
let TyAliasRewriteInfo(context, indent, generics, ident, span) = *rw_info;
|
let TyAliasRewriteInfo(
|
||||||
|
context,
|
||||||
|
indent,
|
||||||
|
generics,
|
||||||
|
where_clauses,
|
||||||
|
where_predicates_split,
|
||||||
|
ident,
|
||||||
|
span,
|
||||||
|
) = *rw_info;
|
||||||
|
let (before_where_predicates, after_where_predicates) = generics
|
||||||
|
.where_clause
|
||||||
|
.predicates
|
||||||
|
.split_at(where_predicates_split);
|
||||||
|
if !after_where_predicates.is_empty() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
result.push_str(&format!("{}type ", format_visibility(context, vis)));
|
result.push_str(&format!("{}type ", format_visibility(context, vis)));
|
||||||
let ident_str = rewrite_ident(context, ident);
|
let ident_str = rewrite_ident(context, ident);
|
||||||
|
|
||||||
|
@ -1595,7 +1626,8 @@ fn rewrite_ty<R: Rewrite>(
|
||||||
}
|
}
|
||||||
let where_clause_str = rewrite_where_clause(
|
let where_clause_str = rewrite_where_clause(
|
||||||
context,
|
context,
|
||||||
&generics.where_clause,
|
before_where_predicates,
|
||||||
|
where_clauses.0.1,
|
||||||
context.config.brace_style(),
|
context.config.brace_style(),
|
||||||
Shape::legacy(where_budget, indent),
|
Shape::legacy(where_budget, indent),
|
||||||
false,
|
false,
|
||||||
|
@ -1609,7 +1641,7 @@ fn rewrite_ty<R: Rewrite>(
|
||||||
if let Some(ty) = rhs {
|
if let Some(ty) = rhs {
|
||||||
// If there's a where clause, add a newline before the assignment. Otherwise just add a
|
// If there's a where clause, add a newline before the assignment. Otherwise just add a
|
||||||
// space.
|
// space.
|
||||||
let has_where = !generics.where_clause.predicates.is_empty();
|
let has_where = !before_where_predicates.is_empty();
|
||||||
if has_where {
|
if has_where {
|
||||||
result.push_str(&indent.to_string_with_newline(context.config));
|
result.push_str(&indent.to_string_with_newline(context.config));
|
||||||
} else {
|
} else {
|
||||||
|
@ -1619,7 +1651,7 @@ fn rewrite_ty<R: Rewrite>(
|
||||||
let comment_span = context
|
let comment_span = context
|
||||||
.snippet_provider
|
.snippet_provider
|
||||||
.opt_span_before(span, "=")
|
.opt_span_before(span, "=")
|
||||||
.map(|op_lo| mk_sp(generics.where_clause.span.hi(), op_lo));
|
.map(|op_lo| mk_sp(where_clauses.0.1.hi(), op_lo));
|
||||||
|
|
||||||
let lhs = match comment_span {
|
let lhs = match comment_span {
|
||||||
Some(comment_span)
|
Some(comment_span)
|
||||||
|
@ -2176,7 +2208,7 @@ fn rewrite_fn_base(
|
||||||
let generics_str = rewrite_generics(
|
let generics_str = rewrite_generics(
|
||||||
context,
|
context,
|
||||||
rewrite_ident(context, ident),
|
rewrite_ident(context, ident),
|
||||||
fn_sig.generics,
|
&fn_sig.generics,
|
||||||
shape,
|
shape,
|
||||||
)?;
|
)?;
|
||||||
result.push_str(&generics_str);
|
result.push_str(&generics_str);
|
||||||
|
@ -2416,7 +2448,8 @@ fn rewrite_fn_base(
|
||||||
}
|
}
|
||||||
let where_clause_str = rewrite_where_clause(
|
let where_clause_str = rewrite_where_clause(
|
||||||
context,
|
context,
|
||||||
where_clause,
|
&where_clause.predicates,
|
||||||
|
where_clause.span,
|
||||||
context.config.brace_style(),
|
context.config.brace_style(),
|
||||||
Shape::indented(indent, context.config),
|
Shape::indented(indent, context.config),
|
||||||
true,
|
true,
|
||||||
|
@ -2692,7 +2725,8 @@ fn generics_shape_from_config(config: &Config, shape: Shape, offset: usize) -> O
|
||||||
|
|
||||||
fn rewrite_where_clause_rfc_style(
|
fn rewrite_where_clause_rfc_style(
|
||||||
context: &RewriteContext<'_>,
|
context: &RewriteContext<'_>,
|
||||||
where_clause: &ast::WhereClause,
|
predicates: &[ast::WherePredicate],
|
||||||
|
where_span: Span,
|
||||||
shape: Shape,
|
shape: Shape,
|
||||||
terminator: &str,
|
terminator: &str,
|
||||||
span_end: Option<BytePos>,
|
span_end: Option<BytePos>,
|
||||||
|
@ -2701,7 +2735,8 @@ fn rewrite_where_clause_rfc_style(
|
||||||
) -> Option<String> {
|
) -> Option<String> {
|
||||||
let (where_keyword, allow_single_line) = rewrite_where_keyword(
|
let (where_keyword, allow_single_line) = rewrite_where_keyword(
|
||||||
context,
|
context,
|
||||||
where_clause,
|
predicates,
|
||||||
|
where_span,
|
||||||
shape,
|
shape,
|
||||||
span_end_before_where,
|
span_end_before_where,
|
||||||
where_clause_option,
|
where_clause_option,
|
||||||
|
@ -2714,12 +2749,12 @@ fn rewrite_where_clause_rfc_style(
|
||||||
.block_left(context.config.tab_spaces())?
|
.block_left(context.config.tab_spaces())?
|
||||||
.sub_width(1)?;
|
.sub_width(1)?;
|
||||||
let force_single_line = context.config.where_single_line()
|
let force_single_line = context.config.where_single_line()
|
||||||
&& where_clause.predicates.len() == 1
|
&& predicates.len() == 1
|
||||||
&& !where_clause_option.veto_single_line;
|
&& !where_clause_option.veto_single_line;
|
||||||
|
|
||||||
let preds_str = rewrite_bounds_on_where_clause(
|
let preds_str = rewrite_bounds_on_where_clause(
|
||||||
context,
|
context,
|
||||||
where_clause,
|
predicates,
|
||||||
clause_shape,
|
clause_shape,
|
||||||
terminator,
|
terminator,
|
||||||
span_end,
|
span_end,
|
||||||
|
@ -2743,7 +2778,8 @@ fn rewrite_where_clause_rfc_style(
|
||||||
/// Rewrite `where` and comment around it.
|
/// Rewrite `where` and comment around it.
|
||||||
fn rewrite_where_keyword(
|
fn rewrite_where_keyword(
|
||||||
context: &RewriteContext<'_>,
|
context: &RewriteContext<'_>,
|
||||||
where_clause: &ast::WhereClause,
|
predicates: &[ast::WherePredicate],
|
||||||
|
where_span: Span,
|
||||||
shape: Shape,
|
shape: Shape,
|
||||||
span_end_before_where: BytePos,
|
span_end_before_where: BytePos,
|
||||||
where_clause_option: WhereClauseOption,
|
where_clause_option: WhereClauseOption,
|
||||||
|
@ -2763,7 +2799,7 @@ fn rewrite_where_keyword(
|
||||||
};
|
};
|
||||||
|
|
||||||
let (span_before, span_after) =
|
let (span_before, span_after) =
|
||||||
missing_span_before_after_where(span_end_before_where, where_clause);
|
missing_span_before_after_where(span_end_before_where, predicates, where_span);
|
||||||
let (comment_before, comment_after) =
|
let (comment_before, comment_after) =
|
||||||
rewrite_comments_before_after_where(context, span_before, span_after, shape)?;
|
rewrite_comments_before_after_where(context, span_before, span_after, shape)?;
|
||||||
|
|
||||||
|
@ -2789,22 +2825,22 @@ fn rewrite_where_keyword(
|
||||||
/// Rewrite bounds on a where clause.
|
/// Rewrite bounds on a where clause.
|
||||||
fn rewrite_bounds_on_where_clause(
|
fn rewrite_bounds_on_where_clause(
|
||||||
context: &RewriteContext<'_>,
|
context: &RewriteContext<'_>,
|
||||||
where_clause: &ast::WhereClause,
|
predicates: &[ast::WherePredicate],
|
||||||
shape: Shape,
|
shape: Shape,
|
||||||
terminator: &str,
|
terminator: &str,
|
||||||
span_end: Option<BytePos>,
|
span_end: Option<BytePos>,
|
||||||
where_clause_option: WhereClauseOption,
|
where_clause_option: WhereClauseOption,
|
||||||
force_single_line: bool,
|
force_single_line: bool,
|
||||||
) -> Option<String> {
|
) -> Option<String> {
|
||||||
let span_start = where_clause.predicates[0].span().lo();
|
let span_start = predicates[0].span().lo();
|
||||||
// If we don't have the start of the next span, then use the end of the
|
// If we don't have the start of the next span, then use the end of the
|
||||||
// predicates, but that means we miss comments.
|
// predicates, but that means we miss comments.
|
||||||
let len = where_clause.predicates.len();
|
let len = predicates.len();
|
||||||
let end_of_preds = where_clause.predicates[len - 1].span().hi();
|
let end_of_preds = predicates[len - 1].span().hi();
|
||||||
let span_end = span_end.unwrap_or(end_of_preds);
|
let span_end = span_end.unwrap_or(end_of_preds);
|
||||||
let items = itemize_list(
|
let items = itemize_list(
|
||||||
context.snippet_provider,
|
context.snippet_provider,
|
||||||
where_clause.predicates.iter(),
|
predicates.iter(),
|
||||||
terminator,
|
terminator,
|
||||||
",",
|
",",
|
||||||
|pred| pred.span().lo(),
|
|pred| pred.span().lo(),
|
||||||
|
@ -2837,7 +2873,8 @@ fn rewrite_bounds_on_where_clause(
|
||||||
|
|
||||||
fn rewrite_where_clause(
|
fn rewrite_where_clause(
|
||||||
context: &RewriteContext<'_>,
|
context: &RewriteContext<'_>,
|
||||||
where_clause: &ast::WhereClause,
|
predicates: &[ast::WherePredicate],
|
||||||
|
where_span: Span,
|
||||||
brace_style: BraceStyle,
|
brace_style: BraceStyle,
|
||||||
shape: Shape,
|
shape: Shape,
|
||||||
on_new_line: bool,
|
on_new_line: bool,
|
||||||
|
@ -2846,14 +2883,15 @@ fn rewrite_where_clause(
|
||||||
span_end_before_where: BytePos,
|
span_end_before_where: BytePos,
|
||||||
where_clause_option: WhereClauseOption,
|
where_clause_option: WhereClauseOption,
|
||||||
) -> Option<String> {
|
) -> Option<String> {
|
||||||
if where_clause.predicates.is_empty() {
|
if predicates.is_empty() {
|
||||||
return Some(String::new());
|
return Some(String::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
if context.config.indent_style() == IndentStyle::Block {
|
if context.config.indent_style() == IndentStyle::Block {
|
||||||
return rewrite_where_clause_rfc_style(
|
return rewrite_where_clause_rfc_style(
|
||||||
context,
|
context,
|
||||||
where_clause,
|
predicates,
|
||||||
|
where_span,
|
||||||
shape,
|
shape,
|
||||||
terminator,
|
terminator,
|
||||||
span_end,
|
span_end,
|
||||||
|
@ -2873,15 +2911,15 @@ fn rewrite_where_clause(
|
||||||
// be out by a char or two.
|
// be out by a char or two.
|
||||||
|
|
||||||
let budget = context.config.max_width() - offset.width();
|
let budget = context.config.max_width() - offset.width();
|
||||||
let span_start = where_clause.predicates[0].span().lo();
|
let span_start = predicates[0].span().lo();
|
||||||
// If we don't have the start of the next span, then use the end of the
|
// If we don't have the start of the next span, then use the end of the
|
||||||
// predicates, but that means we miss comments.
|
// predicates, but that means we miss comments.
|
||||||
let len = where_clause.predicates.len();
|
let len = predicates.len();
|
||||||
let end_of_preds = where_clause.predicates[len - 1].span().hi();
|
let end_of_preds = predicates[len - 1].span().hi();
|
||||||
let span_end = span_end.unwrap_or(end_of_preds);
|
let span_end = span_end.unwrap_or(end_of_preds);
|
||||||
let items = itemize_list(
|
let items = itemize_list(
|
||||||
context.snippet_provider,
|
context.snippet_provider,
|
||||||
where_clause.predicates.iter(),
|
predicates.iter(),
|
||||||
terminator,
|
terminator,
|
||||||
",",
|
",",
|
||||||
|pred| pred.span().lo(),
|
|pred| pred.span().lo(),
|
||||||
|
@ -2936,12 +2974,13 @@ fn rewrite_where_clause(
|
||||||
|
|
||||||
fn missing_span_before_after_where(
|
fn missing_span_before_after_where(
|
||||||
before_item_span_end: BytePos,
|
before_item_span_end: BytePos,
|
||||||
where_clause: &ast::WhereClause,
|
predicates: &[ast::WherePredicate],
|
||||||
|
where_span: Span,
|
||||||
) -> (Span, Span) {
|
) -> (Span, Span) {
|
||||||
let missing_span_before = mk_sp(before_item_span_end, where_clause.span.lo());
|
let missing_span_before = mk_sp(before_item_span_end, where_span.lo());
|
||||||
// 5 = `where`
|
// 5 = `where`
|
||||||
let pos_after_where = where_clause.span.lo() + BytePos(5);
|
let pos_after_where = where_span.lo() + BytePos(5);
|
||||||
let missing_span_after = mk_sp(pos_after_where, where_clause.predicates[0].span().lo());
|
let missing_span_after = mk_sp(pos_after_where, predicates[0].span().lo());
|
||||||
(missing_span_before, missing_span_after)
|
(missing_span_before, missing_span_after)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3030,7 +3069,8 @@ fn format_generics(
|
||||||
}
|
}
|
||||||
let where_clause_str = rewrite_where_clause(
|
let where_clause_str = rewrite_where_clause(
|
||||||
context,
|
context,
|
||||||
&generics.where_clause,
|
&generics.where_clause.predicates,
|
||||||
|
generics.where_clause.span,
|
||||||
brace_style,
|
brace_style,
|
||||||
Shape::legacy(budget, offset.block_only()),
|
Shape::legacy(budget, offset.block_only()),
|
||||||
true,
|
true,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue