mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-11-20 03:49:51 +00:00
Lower Return Type Notation (Type::method(..): Send)
We do it the way rustc does it, by only marking segments with it, and not the whole path. This will allow extending where it is allowed in the future.
This commit is contained in:
parent
3fc655b239
commit
eaa0a39831
5 changed files with 125 additions and 80 deletions
|
|
@ -872,7 +872,7 @@ fn copy_generic_args(
|
|||
args,
|
||||
has_self_type: generic_args.has_self_type,
|
||||
bindings,
|
||||
desugared_from_fn: generic_args.desugared_from_fn,
|
||||
parenthesized: generic_args.parenthesized,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,6 +79,19 @@ thin_vec_with_header_struct! {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum GenericArgsParentheses {
|
||||
No,
|
||||
/// Bounds of the form `Type::method(..): Send` or `impl Trait<method(..): Send>`,
|
||||
/// aka. Return Type Notation or RTN.
|
||||
ReturnTypeNotation,
|
||||
/// `Fn`-family parenthesized traits, e.g. `impl Fn(u32) -> String`.
|
||||
///
|
||||
/// This is desugared into one generic argument containing a tuple of all arguments,
|
||||
/// and an associated type binding for `Output` for the return type.
|
||||
ParenSugar,
|
||||
}
|
||||
|
||||
/// Generic arguments to a path segment (e.g. the `i32` in `Option<i32>`). This
|
||||
/// also includes bindings of associated types, like in `Iterator<Item = Foo>`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
|
|
@ -92,9 +105,8 @@ pub struct GenericArgs {
|
|||
pub has_self_type: bool,
|
||||
/// Associated type bindings like in `Iterator<Item = T>`.
|
||||
pub bindings: Box<[AssociatedTypeBinding]>,
|
||||
/// Whether these generic args were desugared from `Trait(Arg) -> Output`
|
||||
/// parenthesis notation typically used for the `Fn` traits.
|
||||
pub desugared_from_fn: bool,
|
||||
/// Whether these generic args were written with parentheses and how.
|
||||
pub parenthesized: GenericArgsParentheses,
|
||||
}
|
||||
|
||||
/// An associated type binding like in `Iterator<Item = T>`.
|
||||
|
|
@ -326,7 +338,16 @@ impl GenericArgs {
|
|||
args: Box::default(),
|
||||
has_self_type: false,
|
||||
bindings: Box::default(),
|
||||
desugared_from_fn: false,
|
||||
parenthesized: GenericArgsParentheses::No,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn return_type_notation() -> GenericArgs {
|
||||
GenericArgs {
|
||||
args: Box::default(),
|
||||
has_self_type: false,
|
||||
bindings: Box::default(),
|
||||
parenthesized: GenericArgsParentheses::ReturnTypeNotation,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,10 @@ use stdx::thin_vec::EmptyOptimizedThinVec;
|
|||
use syntax::ast::{self, AstNode, HasGenericArgs, HasTypeBounds};
|
||||
|
||||
use crate::{
|
||||
path::{AssociatedTypeBinding, GenericArg, GenericArgs, ModPath, Path, PathKind},
|
||||
path::{
|
||||
AssociatedTypeBinding, GenericArg, GenericArgs, GenericArgsParentheses, ModPath, Path,
|
||||
PathKind,
|
||||
},
|
||||
type_ref::{LifetimeRef, TypeBound, TypeRef},
|
||||
};
|
||||
|
||||
|
|
@ -73,6 +76,9 @@ pub(super) fn lower_path(ctx: &mut LowerCtx<'_>, mut path: ast::Path) -> Option<
|
|||
segment.parenthesized_arg_list(),
|
||||
segment.ret_type(),
|
||||
)
|
||||
})
|
||||
.or_else(|| {
|
||||
segment.return_type_syntax().map(|_| GenericArgs::return_type_notation())
|
||||
});
|
||||
if args.is_some() {
|
||||
generic_args.resize(segments.len(), None);
|
||||
|
|
@ -126,7 +132,7 @@ pub(super) fn lower_path(ctx: &mut LowerCtx<'_>, mut path: ast::Path) -> Option<
|
|||
|
||||
has_self_type: true,
|
||||
bindings: it.bindings.clone(),
|
||||
desugared_from_fn: it.desugared_from_fn,
|
||||
parenthesized: it.parenthesized,
|
||||
},
|
||||
None => GenericArgs {
|
||||
args: Box::new([self_type]),
|
||||
|
|
@ -281,7 +287,12 @@ pub(super) fn lower_generic_args(
|
|||
let name = name_ref.as_name();
|
||||
let args = assoc_type_arg
|
||||
.generic_arg_list()
|
||||
.and_then(|args| lower_generic_args(lower_ctx, args));
|
||||
.and_then(|args| lower_generic_args(lower_ctx, args))
|
||||
.or_else(|| {
|
||||
assoc_type_arg
|
||||
.return_type_syntax()
|
||||
.map(|_| GenericArgs::return_type_notation())
|
||||
});
|
||||
let type_ref =
|
||||
assoc_type_arg.ty().map(|it| TypeRef::from_ast(lower_ctx, it));
|
||||
let type_ref = type_ref
|
||||
|
|
@ -315,7 +326,7 @@ pub(super) fn lower_generic_args(
|
|||
args: args.into_boxed_slice(),
|
||||
has_self_type: false,
|
||||
bindings: bindings.into_boxed_slice(),
|
||||
desugared_from_fn: false,
|
||||
parenthesized: GenericArgsParentheses::No,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -353,5 +364,10 @@ fn lower_generic_args_from_fn_path(
|
|||
bounds: Box::default(),
|
||||
}])
|
||||
};
|
||||
Some(GenericArgs { args, has_self_type: false, bindings, desugared_from_fn: true })
|
||||
Some(GenericArgs {
|
||||
args,
|
||||
has_self_type: false,
|
||||
bindings,
|
||||
parenthesized: GenericArgsParentheses::ParenSugar,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue