Nest all the or-patterns!

This commit is contained in:
Lukas Wirth 2021-06-17 17:37:14 +02:00
parent c82a9141ab
commit 95c8c65139
26 changed files with 133 additions and 151 deletions

View file

@ -51,12 +51,14 @@ impl PathResolution {
PathResolution::Def(ModuleDef::BuiltinType(builtin)) => { PathResolution::Def(ModuleDef::BuiltinType(builtin)) => {
Some(TypeNs::BuiltinType((*builtin).into())) Some(TypeNs::BuiltinType((*builtin).into()))
} }
PathResolution::Def(ModuleDef::Const(_)) PathResolution::Def(
| PathResolution::Def(ModuleDef::Variant(_)) ModuleDef::Const(_)
| PathResolution::Def(ModuleDef::Function(_)) | ModuleDef::Variant(_)
| PathResolution::Def(ModuleDef::Module(_)) | ModuleDef::Function(_)
| PathResolution::Def(ModuleDef::Static(_)) | ModuleDef::Module(_)
| PathResolution::Def(ModuleDef::Trait(_)) => None, | ModuleDef::Static(_)
| ModuleDef::Trait(_),
) => None,
PathResolution::Def(ModuleDef::TypeAlias(alias)) => { PathResolution::Def(ModuleDef::TypeAlias(alias)) => {
Some(TypeNs::TypeAliasId((*alias).into())) Some(TypeNs::TypeAliasId((*alias).into()))
} }
@ -65,8 +67,7 @@ impl PathResolution {
} }
PathResolution::TypeParam(param) => Some(TypeNs::GenericParam((*param).into())), PathResolution::TypeParam(param) => Some(TypeNs::GenericParam((*param).into())),
PathResolution::SelfType(impl_def) => Some(TypeNs::SelfType((*impl_def).into())), PathResolution::SelfType(impl_def) => Some(TypeNs::SelfType((*impl_def).into())),
PathResolution::AssocItem(AssocItem::Const(_)) PathResolution::AssocItem(AssocItem::Const(_) | AssocItem::Function(_)) => None,
| PathResolution::AssocItem(AssocItem::Function(_)) => None,
PathResolution::AssocItem(AssocItem::TypeAlias(alias)) => { PathResolution::AssocItem(AssocItem::TypeAlias(alias)) => {
Some(TypeNs::TypeAliasId((*alias).into())) Some(TypeNs::TypeAliasId((*alias).into()))
} }

View file

@ -63,7 +63,7 @@ impl<'a> Printer<'a> {
fn blank(&mut self) { fn blank(&mut self) {
let mut iter = self.buf.chars().rev().fuse(); let mut iter = self.buf.chars().rev().fuse();
match (iter.next(), iter.next()) { match (iter.next(), iter.next()) {
(Some('\n'), Some('\n')) | (Some('\n'), None) | (None, None) => {} (Some('\n'), Some('\n') | None) | (None, None) => {}
(Some('\n'), Some(_)) => { (Some('\n'), Some(_)) => {
self.buf.push('\n'); self.buf.push('\n');
} }
@ -77,7 +77,7 @@ impl<'a> Printer<'a> {
fn whitespace(&mut self) { fn whitespace(&mut self) {
match self.buf.chars().next_back() { match self.buf.chars().next_back() {
None | Some('\n') | Some(' ') => {} None | Some('\n' | ' ') => {}
_ => self.buf.push(' '), _ => self.buf.push(' '),
} }
} }

View file

@ -1260,7 +1260,7 @@ impl DefCollector<'_> {
for directive in &self.unresolved_imports { for directive in &self.unresolved_imports {
if let ImportSource::Import { id: import, use_tree } = &directive.import.source { if let ImportSource::Import { id: import, use_tree } = &directive.import.source {
match (directive.import.path.segments().first(), &directive.import.path.kind) { match (directive.import.path.segments().first(), &directive.import.path.kind) {
(Some(krate), PathKind::Plain) | (Some(krate), PathKind::Abs) => { (Some(krate), PathKind::Plain | PathKind::Abs) => {
if diagnosed_extern_crates.contains(krate) { if diagnosed_extern_crates.contains(krate) {
continue; continue;
} }

View file

@ -605,8 +605,7 @@ fn to_value_ns(per_ns: PerNs) -> Option<ValueNs> {
ModuleDefId::ConstId(it) => ValueNs::ConstId(it), ModuleDefId::ConstId(it) => ValueNs::ConstId(it),
ModuleDefId::StaticId(it) => ValueNs::StaticId(it), ModuleDefId::StaticId(it) => ValueNs::StaticId(it),
ModuleDefId::AdtId(AdtId::EnumId(_)) ModuleDefId::AdtId(AdtId::EnumId(_) | AdtId::UnionId(_))
| ModuleDefId::AdtId(AdtId::UnionId(_))
| ModuleDefId::TraitId(_) | ModuleDefId::TraitId(_)
| ModuleDefId::TypeAliasId(_) | ModuleDefId::TypeAliasId(_)
| ModuleDefId::BuiltinType(_) | ModuleDefId::BuiltinType(_)

View file

@ -172,9 +172,8 @@ impl Visibility {
/// visible in unrelated modules). /// visible in unrelated modules).
pub(crate) fn max(self, other: Visibility, def_map: &DefMap) -> Option<Visibility> { pub(crate) fn max(self, other: Visibility, def_map: &DefMap) -> Option<Visibility> {
match (self, other) { match (self, other) {
(Visibility::Module(_), Visibility::Public) (Visibility::Module(_) | Visibility::Public, Visibility::Public)
| (Visibility::Public, Visibility::Module(_)) | (Visibility::Public, Visibility::Module(_)) => Some(Visibility::Public),
| (Visibility::Public, Visibility::Public) => Some(Visibility::Public),
(Visibility::Module(mod_a), Visibility::Module(mod_b)) => { (Visibility::Module(mod_a), Visibility::Module(mod_b)) => {
if mod_a.krate != mod_b.krate { if mod_a.krate != mod_b.krate {
return None; return None;

View file

@ -146,10 +146,11 @@ impl HygieneInfo {
(&self.macro_arg.1, InFile::new(loc.kind.file_id(), arg_start)) (&self.macro_arg.1, InFile::new(loc.kind.file_id(), arg_start))
} }
mbe::Origin::Def => match (&*self.macro_def, self.def_start) { mbe::Origin::Def => match (&*self.macro_def, self.def_start) {
(TokenExpander::MacroDef { def_site_token_map, .. }, Some(tt)) (
| (TokenExpander::MacroRules { def_site_token_map, .. }, Some(tt)) => { TokenExpander::MacroDef { def_site_token_map, .. }
(def_site_token_map, tt) | TokenExpander::MacroRules { def_site_token_map, .. },
} Some(tt),
) => (def_site_token_map, tt),
_ => panic!("`Origin::Def` used with non-`macro_rules!` macro"), _ => panic!("`Origin::Def` used with non-`macro_rules!` macro"),
}, },
}; };

View file

@ -368,10 +368,11 @@ impl ExpansionInfo {
let (token_map, tt) = match origin { let (token_map, tt) = match origin {
mbe::Origin::Call => (&self.macro_arg.1, self.arg.clone()), mbe::Origin::Call => (&self.macro_arg.1, self.arg.clone()),
mbe::Origin::Def => match (&*self.macro_def, self.def.as_ref()) { mbe::Origin::Def => match (&*self.macro_def, self.def.as_ref()) {
(db::TokenExpander::MacroRules { def_site_token_map, .. }, Some(tt)) (
| (db::TokenExpander::MacroDef { def_site_token_map, .. }, Some(tt)) => { db::TokenExpander::MacroRules { def_site_token_map, .. }
(def_site_token_map, tt.as_ref().map(|tt| tt.syntax().clone())) | db::TokenExpander::MacroDef { def_site_token_map, .. },
} Some(tt),
) => (def_site_token_map, tt.as_ref().map(|tt| tt.syntax().clone())),
_ => panic!("`Origin::Def` used with non-`macro_rules!` macro"), _ => panic!("`Origin::Def` used with non-`macro_rules!` macro"),
}, },
}; };

View file

@ -38,8 +38,7 @@ impl ConstExt for Const {
// FIXME: support more than just evaluating literals // FIXME: support more than just evaluating literals
pub fn eval_usize(expr: &Expr) -> Option<u64> { pub fn eval_usize(expr: &Expr) -> Option<u64> {
match expr { match expr {
Expr::Literal(Literal::Uint(v, None)) Expr::Literal(Literal::Uint(v, None | Some(BuiltinUint::Usize))) => (*v).try_into().ok(),
| Expr::Literal(Literal::Uint(v, Some(BuiltinUint::Usize))) => (*v).try_into().ok(),
_ => None, _ => None,
} }
} }

View file

@ -84,10 +84,7 @@ impl IntRange {
#[inline] #[inline]
fn is_integral(ty: &Ty) -> bool { fn is_integral(ty: &Ty) -> bool {
match ty.kind(&Interner) { match ty.kind(&Interner) {
TyKind::Scalar(Scalar::Char) TyKind::Scalar(Scalar::Char | Scalar::Int(_) | Scalar::Uint(_) | Scalar::Bool) => true,
| TyKind::Scalar(Scalar::Int(_))
| TyKind::Scalar(Scalar::Uint(_))
| TyKind::Scalar(Scalar::Bool) => true,
_ => false, _ => false,
} }
} }
@ -381,7 +378,7 @@ impl Constructor {
// Wildcards cover anything // Wildcards cover anything
(_, Wildcard) => true, (_, Wildcard) => true,
// The missing ctors are not covered by anything in the matrix except wildcards. // The missing ctors are not covered by anything in the matrix except wildcards.
(Missing, _) | (Wildcard, _) => false, (Missing | Wildcard, _) => false,
(Single, Single) => true, (Single, Single) => true,
(Variant(self_id), Variant(other_id)) => self_id == other_id, (Variant(self_id), Variant(other_id)) => self_id == other_id,
@ -523,7 +520,7 @@ impl SplitWildcard {
} }
} }
TyKind::Scalar(Scalar::Char) => unhandled(), TyKind::Scalar(Scalar::Char) => unhandled(),
TyKind::Scalar(Scalar::Int(..)) | TyKind::Scalar(Scalar::Uint(..)) => unhandled(), TyKind::Scalar(Scalar::Int(..) | Scalar::Uint(..)) => unhandled(),
TyKind::Never if !cx.feature_exhaustive_patterns() && !pcx.is_top_level => { TyKind::Never if !cx.feature_exhaustive_patterns() && !pcx.is_top_level => {
smallvec![NonExhaustive] smallvec![NonExhaustive]
} }

View file

@ -47,10 +47,7 @@ impl<'a> InferenceContext<'a> {
// pointers to have a chance at getting a match. See // pointers to have a chance at getting a match. See
// https://github.com/rust-lang/rust/blob/7b805396bf46dce972692a6846ce2ad8481c5f85/src/librustc_typeck/check/coercion.rs#L877-L916 // https://github.com/rust-lang/rust/blob/7b805396bf46dce972692a6846ce2ad8481c5f85/src/librustc_typeck/check/coercion.rs#L877-L916
let sig = match (ty1.kind(&Interner), ty2.kind(&Interner)) { let sig = match (ty1.kind(&Interner), ty2.kind(&Interner)) {
(TyKind::FnDef(..), TyKind::FnDef(..)) (TyKind::FnDef(..) | TyKind::Closure(..), TyKind::FnDef(..) | TyKind::Closure(..)) => {
| (TyKind::Closure(..), TyKind::FnDef(..))
| (TyKind::FnDef(..), TyKind::Closure(..))
| (TyKind::Closure(..), TyKind::Closure(..)) => {
// FIXME: we're ignoring safety here. To be more correct, if we have one FnDef and one Closure, // FIXME: we're ignoring safety here. To be more correct, if we have one FnDef and one Closure,
// we should be coercing the closure to a fn pointer of the safety of the FnDef // we should be coercing the closure to a fn pointer of the safety of the FnDef
cov_mark::hit!(coerce_fn_reification); cov_mark::hit!(coerce_fn_reification);
@ -448,8 +445,7 @@ fn safe_to_unsafe_fn_ty(fn_ty: FnPointer) -> FnPointer {
fn coerce_mutabilities(from: Mutability, to: Mutability) -> Result<(), TypeError> { fn coerce_mutabilities(from: Mutability, to: Mutability) -> Result<(), TypeError> {
match (from, to) { match (from, to) {
(Mutability::Mut, Mutability::Mut) (Mutability::Mut, Mutability::Mut | Mutability::Not)
| (Mutability::Mut, Mutability::Not)
| (Mutability::Not, Mutability::Not) => Ok(()), | (Mutability::Not, Mutability::Not) => Ok(()),
(Mutability::Not, Mutability::Mut) => Err(TypeError), (Mutability::Not, Mutability::Mut) => Err(TypeError),
} }

View file

@ -593,11 +593,11 @@ impl<'a> InferenceContext<'a> {
UnaryOp::Neg => { UnaryOp::Neg => {
match inner_ty.kind(&Interner) { match inner_ty.kind(&Interner) {
// Fast path for builtins // Fast path for builtins
TyKind::Scalar(Scalar::Int(_)) TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_) | Scalar::Float(_))
| TyKind::Scalar(Scalar::Uint(_)) | TyKind::InferenceVar(
| TyKind::Scalar(Scalar::Float(_)) _,
| TyKind::InferenceVar(_, TyVariableKind::Integer) TyVariableKind::Integer | TyVariableKind::Float,
| TyKind::InferenceVar(_, TyVariableKind::Float) => inner_ty, ) => inner_ty,
// Otherwise we resolve via the std::ops::Neg trait // Otherwise we resolve via the std::ops::Neg trait
_ => self _ => self
.resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()),
@ -606,9 +606,7 @@ impl<'a> InferenceContext<'a> {
UnaryOp::Not => { UnaryOp::Not => {
match inner_ty.kind(&Interner) { match inner_ty.kind(&Interner) {
// Fast path for builtins // Fast path for builtins
TyKind::Scalar(Scalar::Bool) TyKind::Scalar(Scalar::Bool | Scalar::Int(_) | Scalar::Uint(_))
| TyKind::Scalar(Scalar::Int(_))
| TyKind::Scalar(Scalar::Uint(_))
| TyKind::InferenceVar(_, TyVariableKind::Integer) => inner_ty, | TyKind::InferenceVar(_, TyVariableKind::Integer) => inner_ty,
// Otherwise we resolve via the std::ops::Not trait // Otherwise we resolve via the std::ops::Not trait
_ => self _ => self
@ -735,7 +733,7 @@ impl<'a> InferenceContext<'a> {
Expr::Array(array) => { Expr::Array(array) => {
let elem_ty = let elem_ty =
match expected.to_option(&mut self.table).as_ref().map(|t| t.kind(&Interner)) { match expected.to_option(&mut self.table).as_ref().map(|t| t.kind(&Interner)) {
Some(TyKind::Array(st, _)) | Some(TyKind::Slice(st)) => st.clone(), Some(TyKind::Array(st, _) | TyKind::Slice(st)) => st.clone(),
_ => self.table.new_type_var(), _ => self.table.new_type_var(),
}; };

View file

@ -297,10 +297,11 @@ fn is_non_ref_pat(body: &hir_def::body::Body, pat: PatId) -> bool {
Expr::Literal(Literal::String(..)) => false, Expr::Literal(Literal::String(..)) => false,
_ => true, _ => true,
}, },
Pat::Bind { mode: BindingAnnotation::Mutable, subpat: Some(subpat), .. } Pat::Bind {
| Pat::Bind { mode: BindingAnnotation::Unannotated, subpat: Some(subpat), .. } => { mode: BindingAnnotation::Mutable | BindingAnnotation::Unannotated,
is_non_ref_pat(body, *subpat) subpat: Some(subpat),
} ..
} => is_non_ref_pat(body, *subpat),
Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Box { .. } | Pat::Missing => false, Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Box { .. } | Pat::Missing => false,
} }
} }

View file

@ -8,17 +8,15 @@ pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty {
match op { match op {
BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => TyKind::Scalar(Scalar::Bool).intern(&Interner), BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
BinaryOp::Assignment { .. } => TyBuilder::unit(), BinaryOp::Assignment { .. } => TyBuilder::unit(),
BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => { BinaryOp::ArithOp(ArithOp::Shl | ArithOp::Shr) => {
// all integer combinations are valid here // all integer combinations are valid here
if matches!( if matches!(
lhs_ty.kind(&Interner), lhs_ty.kind(&Interner),
TyKind::Scalar(Scalar::Int(_)) TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_))
| TyKind::Scalar(Scalar::Uint(_))
| TyKind::InferenceVar(_, TyVariableKind::Integer) | TyKind::InferenceVar(_, TyVariableKind::Integer)
) && matches!( ) && matches!(
rhs_ty.kind(&Interner), rhs_ty.kind(&Interner),
TyKind::Scalar(Scalar::Int(_)) TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_))
| TyKind::Scalar(Scalar::Uint(_))
| TyKind::InferenceVar(_, TyVariableKind::Integer) | TyKind::InferenceVar(_, TyVariableKind::Integer)
) { ) {
lhs_ty lhs_ty
@ -32,15 +30,15 @@ pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty {
| (TyKind::Scalar(Scalar::Uint(_)), TyKind::Scalar(Scalar::Uint(_))) | (TyKind::Scalar(Scalar::Uint(_)), TyKind::Scalar(Scalar::Uint(_)))
| (TyKind::Scalar(Scalar::Float(_)), TyKind::Scalar(Scalar::Float(_))) => rhs_ty, | (TyKind::Scalar(Scalar::Float(_)), TyKind::Scalar(Scalar::Float(_))) => rhs_ty,
// ({int}, int) | ({int}, uint) // ({int}, int) | ({int}, uint)
(TyKind::InferenceVar(_, TyVariableKind::Integer), TyKind::Scalar(Scalar::Int(_))) (
| (TyKind::InferenceVar(_, TyVariableKind::Integer), TyKind::Scalar(Scalar::Uint(_))) => { TyKind::InferenceVar(_, TyVariableKind::Integer),
rhs_ty TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_)),
} ) => rhs_ty,
// (int, {int}) | (uint, {int}) // (int, {int}) | (uint, {int})
(TyKind::Scalar(Scalar::Int(_)), TyKind::InferenceVar(_, TyVariableKind::Integer)) (
| (TyKind::Scalar(Scalar::Uint(_)), TyKind::InferenceVar(_, TyVariableKind::Integer)) => { TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_)),
lhs_ty TyKind::InferenceVar(_, TyVariableKind::Integer),
} ) => lhs_ty,
// ({float} | float) // ({float} | float)
(TyKind::InferenceVar(_, TyVariableKind::Float), TyKind::Scalar(Scalar::Float(_))) => { (TyKind::InferenceVar(_, TyVariableKind::Float), TyKind::Scalar(Scalar::Float(_))) => {
rhs_ty rhs_ty
@ -69,21 +67,15 @@ pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
BinaryOp::Assignment { op: None } => lhs_ty, BinaryOp::Assignment { op: None } => lhs_ty,
BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty.kind(&Interner) { BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty.kind(&Interner) {
TyKind::Scalar(_) | TyKind::Str => lhs_ty, TyKind::Scalar(_) | TyKind::Str => lhs_ty,
TyKind::InferenceVar(_, TyVariableKind::Integer) TyKind::InferenceVar(_, TyVariableKind::Integer | TyVariableKind::Float) => lhs_ty,
| TyKind::InferenceVar(_, TyVariableKind::Float) => lhs_ty,
_ => TyKind::Error.intern(&Interner), _ => TyKind::Error.intern(&Interner),
}, },
BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => { BinaryOp::ArithOp(ArithOp::Shl | ArithOp::Shr) => TyKind::Error.intern(&Interner),
TyKind::Error.intern(&Interner)
}
BinaryOp::CmpOp(CmpOp::Ord { .. }) BinaryOp::CmpOp(CmpOp::Ord { .. })
| BinaryOp::Assignment { op: Some(_) } | BinaryOp::Assignment { op: Some(_) }
| BinaryOp::ArithOp(_) => match lhs_ty.kind(&Interner) { | BinaryOp::ArithOp(_) => match lhs_ty.kind(&Interner) {
TyKind::Scalar(Scalar::Int(_)) TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_) | Scalar::Float(_)) => lhs_ty,
| TyKind::Scalar(Scalar::Uint(_)) TyKind::InferenceVar(_, TyVariableKind::Integer | TyVariableKind::Float) => lhs_ty,
| TyKind::Scalar(Scalar::Float(_)) => lhs_ty,
TyKind::InferenceVar(_, TyVariableKind::Integer)
| TyKind::InferenceVar(_, TyVariableKind::Float) => lhs_ty,
_ => TyKind::Error.intern(&Interner), _ => TyKind::Error.intern(&Interner),
}, },
} }

View file

@ -197,7 +197,7 @@ fn join_single_use_tree(edit: &mut TextEditBuilder, token: &SyntaxToken) -> Opti
} }
fn is_trailing_comma(left: SyntaxKind, right: SyntaxKind) -> bool { fn is_trailing_comma(left: SyntaxKind, right: SyntaxKind) -> bool {
matches!((left, right), (T![,], T![')']) | (T![,], T![']'])) matches!((left, right), (T![,], T![')'] | T![']']))
} }
fn compute_ws(left: SyntaxKind, right: SyntaxKind) -> &'static str { fn compute_ws(left: SyntaxKind, right: SyntaxKind) -> &'static str {

View file

@ -79,8 +79,7 @@ pub(crate) fn find_all_refs(
}); });
usages.references.retain(|_, it| !it.is_empty()); usages.references.retain(|_, it| !it.is_empty());
} }
Definition::ModuleDef(hir::ModuleDef::Adt(_)) Definition::ModuleDef(hir::ModuleDef::Adt(_) | hir::ModuleDef::Variant(_)) => {
| Definition::ModuleDef(hir::ModuleDef::Variant(_)) => {
refs.for_each(|it| { refs.for_each(|it| {
it.retain(|reference| { it.retain(|reference| {
reference.name.as_name_ref().map_or(false, is_lit_name_ref) reference.name.as_name_ref().map_or(false, is_lit_name_ref)

View file

@ -294,7 +294,7 @@ fn traverse(
Some(parent) => { Some(parent) => {
// We only care Name and Name_ref // We only care Name and Name_ref
match (token.kind(), parent.kind()) { match (token.kind(), parent.kind()) {
(IDENT, NAME) | (IDENT, NAME_REF) => parent.into(), (IDENT, NAME | NAME_REF) => parent.into(),
_ => token.into(), _ => token.into(),
} }
} }
@ -310,7 +310,7 @@ fn traverse(
Some(parent) => { Some(parent) => {
// We only care Name and Name_ref // We only care Name and Name_ref
match (token.kind(), parent.kind()) { match (token.kind(), parent.kind()) {
(IDENT, NAME) | (IDENT, NAME_REF) => parent.into(), (IDENT, NAME | NAME_REF) => parent.into(),
_ => token.into(), _ => token.into(),
} }
} }

View file

@ -1384,7 +1384,7 @@ fn fix_param_usages(ctx: &AssistContext, params: &[Param], syntax: &SyntaxNode)
for (param, usages) in usages_for_param { for (param, usages) in usages_for_param {
for usage in usages { for usage in usages {
match usage.syntax().ancestors().skip(1).find_map(ast::Expr::cast) { match usage.syntax().ancestors().skip(1).find_map(ast::Expr::cast) {
Some(ast::Expr::MethodCallExpr(_)) | Some(ast::Expr::FieldExpr(_)) => { Some(ast::Expr::MethodCallExpr(_) | ast::Expr::FieldExpr(_)) => {
// do nothing // do nothing
} }
Some(ast::Expr::RefExpr(node)) Some(ast::Expr::RefExpr(node))

View file

@ -68,28 +68,33 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext) -> O
Some(!matches!( Some(!matches!(
(&initializer_expr, usage_parent), (&initializer_expr, usage_parent),
(ast::Expr::CallExpr(_), _) (
| (ast::Expr::IndexExpr(_), _) ast::Expr::CallExpr(_)
| (ast::Expr::MethodCallExpr(_), _) | ast::Expr::IndexExpr(_)
| (ast::Expr::FieldExpr(_), _) | ast::Expr::MethodCallExpr(_)
| (ast::Expr::TryExpr(_), _) | ast::Expr::FieldExpr(_)
| (ast::Expr::RefExpr(_), _) | ast::Expr::TryExpr(_)
| (ast::Expr::Literal(_), _) | ast::Expr::RefExpr(_)
| (ast::Expr::TupleExpr(_), _) | ast::Expr::Literal(_)
| (ast::Expr::ArrayExpr(_), _) | ast::Expr::TupleExpr(_)
| (ast::Expr::ParenExpr(_), _) | ast::Expr::ArrayExpr(_)
| (ast::Expr::PathExpr(_), _) | ast::Expr::ParenExpr(_)
| (ast::Expr::BlockExpr(_), _) | ast::Expr::PathExpr(_)
| (ast::Expr::EffectExpr(_), _) | ast::Expr::BlockExpr(_)
| (_, ast::Expr::CallExpr(_)) | ast::Expr::EffectExpr(_),
| (_, ast::Expr::TupleExpr(_)) _
| (_, ast::Expr::ArrayExpr(_)) ) | (
| (_, ast::Expr::ParenExpr(_)) _,
| (_, ast::Expr::ForExpr(_)) ast::Expr::CallExpr(_)
| (_, ast::Expr::WhileExpr(_)) | ast::Expr::TupleExpr(_)
| (_, ast::Expr::BreakExpr(_)) | ast::Expr::ArrayExpr(_)
| (_, ast::Expr::ReturnExpr(_)) | ast::Expr::ParenExpr(_)
| (_, ast::Expr::MatchExpr(_)) | ast::Expr::ForExpr(_)
| ast::Expr::WhileExpr(_)
| ast::Expr::BreakExpr(_)
| ast::Expr::ReturnExpr(_)
| ast::Expr::MatchExpr(_)
)
)) ))
}) })
.collect::<Option<_>>() .collect::<Option<_>>()

View file

@ -179,9 +179,10 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult, assist_label:
"unresolved assist should not contain source changes" "unresolved assist should not contain source changes"
), ),
(Some(_), ExpectedResult::NotApplicable) => panic!("assist should not be applicable!"), (Some(_), ExpectedResult::NotApplicable) => panic!("assist should not be applicable!"),
(None, ExpectedResult::After(_)) (
| (None, ExpectedResult::Target(_)) None,
| (None, ExpectedResult::Unresolved) => { ExpectedResult::After(_) | ExpectedResult::Target(_) | ExpectedResult::Unresolved,
) => {
panic!("code action is not applicable") panic!("code action is not applicable")
} }
(None, ExpectedResult::NotApplicable) => (), (None, ExpectedResult::NotApplicable) => (),

View file

@ -65,9 +65,11 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
// Don't suggest attribute macros and derives. // Don't suggest attribute macros and derives.
hir::ScopeDef::MacroDef(mac) => mac.is_fn_like(), hir::ScopeDef::MacroDef(mac) => mac.is_fn_like(),
// no values in type places // no values in type places
hir::ScopeDef::ModuleDef(hir::ModuleDef::Function(_)) hir::ScopeDef::ModuleDef(
| hir::ScopeDef::ModuleDef(hir::ModuleDef::Variant(_)) hir::ModuleDef::Function(_)
| hir::ScopeDef::ModuleDef(hir::ModuleDef::Static(_)) | hir::ModuleDef::Variant(_)
| hir::ModuleDef::Static(_),
)
| hir::ScopeDef::Local(_) => !ctx.expects_type(), | hir::ScopeDef::Local(_) => !ctx.expects_type(),
// unless its a constant in a generic arg list position // unless its a constant in a generic arg list position
hir::ScopeDef::ModuleDef(hir::ModuleDef::Const(_)) => { hir::ScopeDef::ModuleDef(hir::ModuleDef::Const(_)) => {
@ -81,9 +83,13 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
} }
} }
} }
hir::PathResolution::Def(def @ hir::ModuleDef::Adt(_)) hir::PathResolution::Def(
| hir::PathResolution::Def(def @ hir::ModuleDef::TypeAlias(_)) def
| hir::PathResolution::Def(def @ hir::ModuleDef::BuiltinType(_)) => { @
(hir::ModuleDef::Adt(_)
| hir::ModuleDef::TypeAlias(_)
| hir::ModuleDef::BuiltinType(_)),
) => {
if let hir::ModuleDef::Adt(hir::Adt::Enum(e)) = def { if let hir::ModuleDef::Adt(hir::Adt::Enum(e)) = def {
add_enum_variants(acc, ctx, e); add_enum_variants(acc, ctx, e);
} }

View file

@ -71,9 +71,11 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
// Don't suggest attribute macros and derives. // Don't suggest attribute macros and derives.
ScopeDef::MacroDef(mac) => mac.is_fn_like(), ScopeDef::MacroDef(mac) => mac.is_fn_like(),
// no values in type places // no values in type places
ScopeDef::ModuleDef(hir::ModuleDef::Function(_)) ScopeDef::ModuleDef(
| ScopeDef::ModuleDef(hir::ModuleDef::Variant(_)) hir::ModuleDef::Function(_)
| ScopeDef::ModuleDef(hir::ModuleDef::Static(_)) | hir::ModuleDef::Variant(_)
| hir::ModuleDef::Static(_),
)
| ScopeDef::Local(_) => !ctx.expects_type(), | ScopeDef::Local(_) => !ctx.expects_type(),
// unless its a constant in a generic arg list position // unless its a constant in a generic arg list position
ScopeDef::ModuleDef(hir::ModuleDef::Const(_)) ScopeDef::ModuleDef(hir::ModuleDef::Const(_))

View file

@ -242,24 +242,23 @@ impl<'a> CompletionContext<'a> {
} }
pub(crate) fn expects_assoc_item(&self) -> bool { pub(crate) fn expects_assoc_item(&self) -> bool {
matches!( matches!(self.completion_location, Some(ImmediateLocation::Trait | ImmediateLocation::Impl))
self.completion_location,
Some(ImmediateLocation::Trait) | Some(ImmediateLocation::Impl)
)
} }
pub(crate) fn has_dot_receiver(&self) -> bool { pub(crate) fn has_dot_receiver(&self) -> bool {
matches!( matches!(
&self.completion_location, &self.completion_location,
Some(ImmediateLocation::FieldAccess { receiver, .. }) | Some(ImmediateLocation::MethodCall { receiver,.. }) Some(ImmediateLocation::FieldAccess { receiver, .. } | ImmediateLocation::MethodCall { receiver,.. })
if receiver.is_some() if receiver.is_some()
) )
} }
pub(crate) fn dot_receiver(&self) -> Option<&ast::Expr> { pub(crate) fn dot_receiver(&self) -> Option<&ast::Expr> {
match &self.completion_location { match &self.completion_location {
Some(ImmediateLocation::MethodCall { receiver, .. }) Some(
| Some(ImmediateLocation::FieldAccess { receiver, .. }) => receiver.as_ref(), ImmediateLocation::MethodCall { receiver, .. }
| ImmediateLocation::FieldAccess { receiver, .. },
) => receiver.as_ref(),
_ => None, _ => None,
} }
} }
@ -283,7 +282,7 @@ impl<'a> CompletionContext<'a> {
pub(crate) fn expects_ident_pat_or_ref_expr(&self) -> bool { pub(crate) fn expects_ident_pat_or_ref_expr(&self) -> bool {
matches!( matches!(
self.completion_location, self.completion_location,
Some(ImmediateLocation::IdentPat) | Some(ImmediateLocation::RefExpr) Some(ImmediateLocation::IdentPat | ImmediateLocation::RefExpr)
) )
} }
@ -294,14 +293,14 @@ impl<'a> CompletionContext<'a> {
pub(crate) fn in_use_tree(&self) -> bool { pub(crate) fn in_use_tree(&self) -> bool {
matches!( matches!(
self.completion_location, self.completion_location,
Some(ImmediateLocation::Use) | Some(ImmediateLocation::UseTree) Some(ImmediateLocation::Use | ImmediateLocation::UseTree)
) )
} }
pub(crate) fn has_impl_or_trait_prev_sibling(&self) -> bool { pub(crate) fn has_impl_or_trait_prev_sibling(&self) -> bool {
matches!( matches!(
self.prev_sibling, self.prev_sibling,
Some(ImmediatePrevSibling::ImplDefType) | Some(ImmediatePrevSibling::TraitDefName) Some(ImmediatePrevSibling::ImplDefType | ImmediatePrevSibling::TraitDefName)
) )
} }
@ -318,14 +317,16 @@ impl<'a> CompletionContext<'a> {
|| self.previous_token_is(T![unsafe]) || self.previous_token_is(T![unsafe])
|| matches!( || matches!(
self.prev_sibling, self.prev_sibling,
Some(ImmediatePrevSibling::Attribute) | Some(ImmediatePrevSibling::Visibility) Some(ImmediatePrevSibling::Attribute | ImmediatePrevSibling::Visibility)
) )
|| matches!( || matches!(
self.completion_location, self.completion_location,
Some(ImmediateLocation::Attribute(_)) Some(
| Some(ImmediateLocation::ModDeclaration(_)) ImmediateLocation::Attribute(_)
| Some(ImmediateLocation::RecordPat(_)) | ImmediateLocation::ModDeclaration(_)
| Some(ImmediateLocation::RecordExpr(_)) | ImmediateLocation::RecordPat(_)
| ImmediateLocation::RecordExpr(_)
)
) )
} }

View file

@ -32,7 +32,7 @@ impl Builder {
cov_mark::hit!(no_parens_in_use_item); cov_mark::hit!(no_parens_in_use_item);
return false; return false;
} }
if matches!(ctx.path_call_kind(), Some(CallKind::Expr) | Some(CallKind::Pat)) if matches!(ctx.path_call_kind(), Some(CallKind::Expr | CallKind::Pat))
| matches!( | matches!(
ctx.completion_location, ctx.completion_location,
Some(ImmediateLocation::MethodCall { has_parens: true, .. }) Some(ImmediateLocation::MethodCall { has_parens: true, .. })

View file

@ -804,33 +804,17 @@ impl<'a> TtIter<'a> {
}; };
match (punct.char, second, third) { match (punct.char, second, third) {
('.', '.', Some('.')) ('.', '.', Some('.' | '=')) | ('<', '<', Some('=')) | ('>', '>', Some('=')) => {
| ('.', '.', Some('='))
| ('<', '<', Some('='))
| ('>', '>', Some('=')) => {
let tt2 = self.next().unwrap().clone(); let tt2 = self.next().unwrap().clone();
let tt3 = self.next().unwrap().clone(); let tt3 = self.next().unwrap().clone();
Ok(tt::Subtree { delimiter: None, token_trees: vec![tt, tt2, tt3] }.into()) Ok(tt::Subtree { delimiter: None, token_trees: vec![tt, tt2, tt3] }.into())
} }
('-', '=', _) ('-' | '!' | '*' | '/' | '&' | '%' | '^' | '+' | '<' | '=' | '>' | '|', '=', _)
| ('-', '>', _) | ('-' | '=' | '>', '>', _)
| (':', ':', _) | (':', ':', _)
| ('!', '=', _)
| ('.', '.', _) | ('.', '.', _)
| ('*', '=', _)
| ('/', '=', _)
| ('&', '&', _) | ('&', '&', _)
| ('&', '=', _)
| ('%', '=', _)
| ('^', '=', _)
| ('+', '=', _)
| ('<', '<', _) | ('<', '<', _)
| ('<', '=', _)
| ('=', '=', _)
| ('=', '>', _)
| ('>', '=', _)
| ('>', '>', _)
| ('|', '=', _)
| ('|', '|', _) => { | ('|', '|', _) => {
let tt2 = self.next().unwrap().clone(); let tt2 = self.next().unwrap().clone();
Ok(tt::Subtree { delimiter: None, token_trees: vec![tt, tt2] }.into()) Ok(tt::Subtree { delimiter: None, token_trees: vec![tt, tt2] }.into())

View file

@ -389,7 +389,7 @@ impl VirtualPath {
match (file_stem, extension) { match (file_stem, extension) {
(None, None) => None, (None, None) => None,
(None, Some(_)) | (Some(""), Some(_)) => Some((file_name, None)), (None | Some(""), Some(_)) => Some((file_name, None)),
(Some(file_stem), extension) => Some((file_stem, extension)), (Some(file_stem), extension) => Some((file_stem, extension)),
} }
} }

View file

@ -8,7 +8,7 @@ use xshell::{cmd, pushd};
use crate::flags; use crate::flags;
// Latest stable, feel free to send a PR if this lags behind. // Latest stable, feel free to send a PR if this lags behind.
const REQUIRED_RUST_VERSION: u32 = 52; const REQUIRED_RUST_VERSION: u32 = 53;
impl flags::Install { impl flags::Install {
pub(crate) fn run(self) -> Result<()> { pub(crate) fn run(self) -> Result<()> {