Simplify
This commit is contained in:
parent
284c1741d6
commit
8ea1afce28
@ -151,7 +151,7 @@ pub(super) fn coerce(
|
|||||||
if let Some(id) = expr {
|
if let Some(id) = expr {
|
||||||
ctx.result.type_mismatches.insert(
|
ctx.result.type_mismatches.insert(
|
||||||
id.into(),
|
id.into(),
|
||||||
TypeMismatch { expected: self.merged_ty().clone(), actual: expr_ty.clone() },
|
TypeMismatch { expected: self.merged_ty(), actual: expr_ty.clone() },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
cov_mark::hit!(coerce_merge_fail_fallback);
|
cov_mark::hit!(coerce_merge_fail_fallback);
|
||||||
|
@ -331,7 +331,7 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
|||||||
let prev_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
|
let prev_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
|
||||||
let prev_ret_ty = mem::replace(&mut self.return_ty, ret_ty.clone());
|
let prev_ret_ty = mem::replace(&mut self.return_ty, ret_ty.clone());
|
||||||
let prev_ret_coercion =
|
let prev_ret_coercion =
|
||||||
mem::replace(&mut self.return_coercion, Some(CoerceMany::new(ret_ty.clone())));
|
mem::replace(&mut self.return_coercion, Some(CoerceMany::new(ret_ty)));
|
||||||
let prev_resume_yield_tys =
|
let prev_resume_yield_tys =
|
||||||
mem::replace(&mut self.resume_yield_tys, resume_yield_tys);
|
mem::replace(&mut self.resume_yield_tys, resume_yield_tys);
|
||||||
|
|
||||||
@ -402,7 +402,7 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
|||||||
.push(callee_ty.clone())
|
.push(callee_ty.clone())
|
||||||
.push(TyBuilder::tuple_with(params.iter().cloned()))
|
.push(TyBuilder::tuple_with(params.iter().cloned()))
|
||||||
.build();
|
.build();
|
||||||
self.write_method_resolution(tgt_expr, func, subst.clone());
|
self.write_method_resolution(tgt_expr, func, subst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.write_expr_adj(*callee, adjustments);
|
self.write_expr_adj(*callee, adjustments);
|
||||||
@ -803,7 +803,7 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
|||||||
.push(self_ty.clone())
|
.push(self_ty.clone())
|
||||||
.push(index_ty.clone())
|
.push(index_ty.clone())
|
||||||
.build();
|
.build();
|
||||||
self.write_method_resolution(tgt_expr, func, substs.clone());
|
self.write_method_resolution(tgt_expr, func, substs);
|
||||||
}
|
}
|
||||||
self.resolve_associated_type_with_params(
|
self.resolve_associated_type_with_params(
|
||||||
self_ty,
|
self_ty,
|
||||||
@ -912,7 +912,7 @@ fn infer_expr_array(
|
|||||||
(elem_ty, consteval::usize_const(self.db, Some(0), krate))
|
(elem_ty, consteval::usize_const(self.db, Some(0), krate))
|
||||||
}
|
}
|
||||||
Array::ElementList { elements, .. } => {
|
Array::ElementList { elements, .. } => {
|
||||||
let mut coerce = CoerceMany::new(elem_ty.clone());
|
let mut coerce = CoerceMany::new(elem_ty);
|
||||||
for &expr in elements.iter() {
|
for &expr in elements.iter() {
|
||||||
let cur_elem_ty = self.infer_expr_inner(expr, &expected);
|
let cur_elem_ty = self.infer_expr_inner(expr, &expected);
|
||||||
coerce.coerce(self, Some(expr), &cur_elem_ty);
|
coerce.coerce(self, Some(expr), &cur_elem_ty);
|
||||||
@ -1214,7 +1214,7 @@ fn infer_block(
|
|||||||
let g = self.resolver.update_to_inner_scope(self.db.upcast(), self.owner, expr);
|
let g = self.resolver.update_to_inner_scope(self.db.upcast(), self.owner, expr);
|
||||||
|
|
||||||
let (break_ty, ty) =
|
let (break_ty, ty) =
|
||||||
self.with_breakable_ctx(BreakableKind::Block, Some(coerce_ty.clone()), label, |this| {
|
self.with_breakable_ctx(BreakableKind::Block, Some(coerce_ty), label, |this| {
|
||||||
for stmt in statements {
|
for stmt in statements {
|
||||||
match stmt {
|
match stmt {
|
||||||
Statement::Let { pat, type_ref, initializer, else_branch } => {
|
Statement::Let { pat, type_ref, initializer, else_branch } => {
|
||||||
|
@ -51,8 +51,8 @@ impl chalk_ir::interner::Interner for Interner {
|
|||||||
type InternedGoal = Arc<GoalData<Self>>;
|
type InternedGoal = Arc<GoalData<Self>>;
|
||||||
type InternedGoals = Vec<Goal<Self>>;
|
type InternedGoals = Vec<Goal<Self>>;
|
||||||
type InternedSubstitution = Interned<InternedWrapper<SmallVec<[GenericArg; 2]>>>;
|
type InternedSubstitution = Interned<InternedWrapper<SmallVec<[GenericArg; 2]>>>;
|
||||||
type InternedProgramClause = chalk_ir::ProgramClauseData<Self>;
|
|
||||||
type InternedProgramClauses = Interned<InternedWrapper<Vec<chalk_ir::ProgramClause<Self>>>>;
|
type InternedProgramClauses = Interned<InternedWrapper<Vec<chalk_ir::ProgramClause<Self>>>>;
|
||||||
|
type InternedProgramClause = chalk_ir::ProgramClauseData<Self>;
|
||||||
type InternedQuantifiedWhereClauses =
|
type InternedQuantifiedWhereClauses =
|
||||||
Interned<InternedWrapper<Vec<chalk_ir::QuantifiedWhereClause<Self>>>>;
|
Interned<InternedWrapper<Vec<chalk_ir::QuantifiedWhereClause<Self>>>>;
|
||||||
type InternedVariableKinds = Interned<InternedWrapper<Vec<chalk_ir::VariableKind<Interner>>>>;
|
type InternedVariableKinds = Interned<InternedWrapper<Vec<chalk_ir::VariableKind<Interner>>>>;
|
||||||
@ -86,6 +86,27 @@ fn debug_assoc_type_id(
|
|||||||
tls::with_current_program(|prog| Some(prog?.debug_assoc_type_id(id, fmt)))
|
tls::with_current_program(|prog| Some(prog?.debug_assoc_type_id(id, fmt)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn debug_opaque_ty_id(
|
||||||
|
opaque_ty_id: chalk_ir::OpaqueTyId<Self>,
|
||||||
|
fmt: &mut fmt::Formatter<'_>,
|
||||||
|
) -> Option<fmt::Result> {
|
||||||
|
Some(write!(fmt, "OpaqueTy#{}", opaque_ty_id.0))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn debug_fn_def_id(
|
||||||
|
fn_def_id: chalk_ir::FnDefId<Self>,
|
||||||
|
fmt: &mut fmt::Formatter<'_>,
|
||||||
|
) -> Option<fmt::Result> {
|
||||||
|
tls::with_current_program(|prog| Some(prog?.debug_fn_def_id(fn_def_id, fmt)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn debug_closure_id(
|
||||||
|
_fn_def_id: chalk_ir::ClosureId<Self>,
|
||||||
|
_fmt: &mut fmt::Formatter<'_>,
|
||||||
|
) -> Option<fmt::Result> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn debug_alias(
|
fn debug_alias(
|
||||||
alias: &chalk_ir::AliasTy<Interner>,
|
alias: &chalk_ir::AliasTy<Interner>,
|
||||||
fmt: &mut fmt::Formatter<'_>,
|
fmt: &mut fmt::Formatter<'_>,
|
||||||
@ -113,13 +134,6 @@ fn debug_opaque_ty(
|
|||||||
Some(write!(fmt, "{:?}", opaque_ty.opaque_ty_id))
|
Some(write!(fmt, "{:?}", opaque_ty.opaque_ty_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn debug_opaque_ty_id(
|
|
||||||
opaque_ty_id: chalk_ir::OpaqueTyId<Self>,
|
|
||||||
fmt: &mut fmt::Formatter<'_>,
|
|
||||||
) -> Option<fmt::Result> {
|
|
||||||
Some(write!(fmt, "OpaqueTy#{}", opaque_ty_id.0))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn debug_ty(ty: &chalk_ir::Ty<Interner>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
|
fn debug_ty(ty: &chalk_ir::Ty<Interner>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
|
||||||
Some(write!(fmt, "{:?}", ty.data(Interner)))
|
Some(write!(fmt, "{:?}", ty.data(Interner)))
|
||||||
}
|
}
|
||||||
@ -131,6 +145,13 @@ fn debug_lifetime(
|
|||||||
Some(write!(fmt, "{:?}", lifetime.data(Interner)))
|
Some(write!(fmt, "{:?}", lifetime.data(Interner)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn debug_const(
|
||||||
|
constant: &chalk_ir::Const<Self>,
|
||||||
|
fmt: &mut fmt::Formatter<'_>,
|
||||||
|
) -> Option<fmt::Result> {
|
||||||
|
Some(write!(fmt, "{:?}", constant.data(Interner)))
|
||||||
|
}
|
||||||
|
|
||||||
fn debug_generic_arg(
|
fn debug_generic_arg(
|
||||||
parameter: &GenericArg,
|
parameter: &GenericArg,
|
||||||
fmt: &mut fmt::Formatter<'_>,
|
fmt: &mut fmt::Formatter<'_>,
|
||||||
@ -138,69 +159,42 @@ fn debug_generic_arg(
|
|||||||
Some(write!(fmt, "{:?}", parameter.data(Interner).inner_debug()))
|
Some(write!(fmt, "{:?}", parameter.data(Interner).inner_debug()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn debug_goal(goal: &Goal<Interner>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
|
|
||||||
let goal_data = goal.data(Interner);
|
|
||||||
Some(write!(fmt, "{goal_data:?}"))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn debug_goals(
|
|
||||||
goals: &chalk_ir::Goals<Interner>,
|
|
||||||
fmt: &mut fmt::Formatter<'_>,
|
|
||||||
) -> Option<fmt::Result> {
|
|
||||||
Some(write!(fmt, "{:?}", goals.debug(Interner)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn debug_program_clause_implication(
|
|
||||||
pci: &chalk_ir::ProgramClauseImplication<Interner>,
|
|
||||||
fmt: &mut fmt::Formatter<'_>,
|
|
||||||
) -> Option<fmt::Result> {
|
|
||||||
Some(write!(fmt, "{:?}", pci.debug(Interner)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn debug_substitution(
|
|
||||||
substitution: &chalk_ir::Substitution<Interner>,
|
|
||||||
fmt: &mut fmt::Formatter<'_>,
|
|
||||||
) -> Option<fmt::Result> {
|
|
||||||
Some(write!(fmt, "{:?}", substitution.debug(Interner)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn debug_separator_trait_ref(
|
|
||||||
separator_trait_ref: &chalk_ir::SeparatorTraitRef<'_, Interner>,
|
|
||||||
fmt: &mut fmt::Formatter<'_>,
|
|
||||||
) -> Option<fmt::Result> {
|
|
||||||
Some(write!(fmt, "{:?}", separator_trait_ref.debug(Interner)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn debug_fn_def_id(
|
|
||||||
fn_def_id: chalk_ir::FnDefId<Self>,
|
|
||||||
fmt: &mut fmt::Formatter<'_>,
|
|
||||||
) -> Option<fmt::Result> {
|
|
||||||
tls::with_current_program(|prog| Some(prog?.debug_fn_def_id(fn_def_id, fmt)))
|
|
||||||
}
|
|
||||||
fn debug_const(
|
|
||||||
constant: &chalk_ir::Const<Self>,
|
|
||||||
fmt: &mut fmt::Formatter<'_>,
|
|
||||||
) -> Option<fmt::Result> {
|
|
||||||
Some(write!(fmt, "{:?}", constant.data(Interner)))
|
|
||||||
}
|
|
||||||
fn debug_variable_kinds(
|
fn debug_variable_kinds(
|
||||||
variable_kinds: &chalk_ir::VariableKinds<Self>,
|
variable_kinds: &chalk_ir::VariableKinds<Self>,
|
||||||
fmt: &mut fmt::Formatter<'_>,
|
fmt: &mut fmt::Formatter<'_>,
|
||||||
) -> Option<fmt::Result> {
|
) -> Option<fmt::Result> {
|
||||||
Some(write!(fmt, "{:?}", variable_kinds.as_slice(Interner)))
|
Some(write!(fmt, "{:?}", variable_kinds.as_slice(Interner)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn debug_variable_kinds_with_angles(
|
fn debug_variable_kinds_with_angles(
|
||||||
variable_kinds: &chalk_ir::VariableKinds<Self>,
|
variable_kinds: &chalk_ir::VariableKinds<Self>,
|
||||||
fmt: &mut fmt::Formatter<'_>,
|
fmt: &mut fmt::Formatter<'_>,
|
||||||
) -> Option<fmt::Result> {
|
) -> Option<fmt::Result> {
|
||||||
Some(write!(fmt, "{:?}", variable_kinds.inner_debug(Interner)))
|
Some(write!(fmt, "{:?}", variable_kinds.inner_debug(Interner)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn debug_canonical_var_kinds(
|
fn debug_canonical_var_kinds(
|
||||||
canonical_var_kinds: &chalk_ir::CanonicalVarKinds<Self>,
|
canonical_var_kinds: &chalk_ir::CanonicalVarKinds<Self>,
|
||||||
fmt: &mut fmt::Formatter<'_>,
|
fmt: &mut fmt::Formatter<'_>,
|
||||||
) -> Option<fmt::Result> {
|
) -> Option<fmt::Result> {
|
||||||
Some(write!(fmt, "{:?}", canonical_var_kinds.as_slice(Interner)))
|
Some(write!(fmt, "{:?}", canonical_var_kinds.as_slice(Interner)))
|
||||||
}
|
}
|
||||||
|
fn debug_goal(goal: &Goal<Interner>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
|
||||||
|
let goal_data = goal.data(Interner);
|
||||||
|
Some(write!(fmt, "{goal_data:?}"))
|
||||||
|
}
|
||||||
|
fn debug_goals(
|
||||||
|
goals: &chalk_ir::Goals<Interner>,
|
||||||
|
fmt: &mut fmt::Formatter<'_>,
|
||||||
|
) -> Option<fmt::Result> {
|
||||||
|
Some(write!(fmt, "{:?}", goals.debug(Interner)))
|
||||||
|
}
|
||||||
|
fn debug_program_clause_implication(
|
||||||
|
pci: &chalk_ir::ProgramClauseImplication<Interner>,
|
||||||
|
fmt: &mut fmt::Formatter<'_>,
|
||||||
|
) -> Option<fmt::Result> {
|
||||||
|
Some(write!(fmt, "{:?}", pci.debug(Interner)))
|
||||||
|
}
|
||||||
fn debug_program_clause(
|
fn debug_program_clause(
|
||||||
clause: &chalk_ir::ProgramClause<Self>,
|
clause: &chalk_ir::ProgramClause<Self>,
|
||||||
fmt: &mut fmt::Formatter<'_>,
|
fmt: &mut fmt::Formatter<'_>,
|
||||||
@ -213,6 +207,19 @@ fn debug_program_clauses(
|
|||||||
) -> Option<fmt::Result> {
|
) -> Option<fmt::Result> {
|
||||||
Some(write!(fmt, "{:?}", clauses.as_slice(Interner)))
|
Some(write!(fmt, "{:?}", clauses.as_slice(Interner)))
|
||||||
}
|
}
|
||||||
|
fn debug_substitution(
|
||||||
|
substitution: &chalk_ir::Substitution<Interner>,
|
||||||
|
fmt: &mut fmt::Formatter<'_>,
|
||||||
|
) -> Option<fmt::Result> {
|
||||||
|
Some(write!(fmt, "{:?}", substitution.debug(Interner)))
|
||||||
|
}
|
||||||
|
fn debug_separator_trait_ref(
|
||||||
|
separator_trait_ref: &chalk_ir::SeparatorTraitRef<'_, Interner>,
|
||||||
|
fmt: &mut fmt::Formatter<'_>,
|
||||||
|
) -> Option<fmt::Result> {
|
||||||
|
Some(write!(fmt, "{:?}", separator_trait_ref.debug(Interner)))
|
||||||
|
}
|
||||||
|
|
||||||
fn debug_quantified_where_clauses(
|
fn debug_quantified_where_clauses(
|
||||||
clauses: &chalk_ir::QuantifiedWhereClauses<Self>,
|
clauses: &chalk_ir::QuantifiedWhereClauses<Self>,
|
||||||
fmt: &mut fmt::Formatter<'_>,
|
fmt: &mut fmt::Formatter<'_>,
|
||||||
@ -220,6 +227,13 @@ fn debug_quantified_where_clauses(
|
|||||||
Some(write!(fmt, "{:?}", clauses.as_slice(Interner)))
|
Some(write!(fmt, "{:?}", clauses.as_slice(Interner)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn debug_constraints(
|
||||||
|
_clauses: &chalk_ir::Constraints<Self>,
|
||||||
|
_fmt: &mut fmt::Formatter<'_>,
|
||||||
|
) -> Option<fmt::Result> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn intern_ty(self, kind: chalk_ir::TyKind<Self>) -> Self::InternedType {
|
fn intern_ty(self, kind: chalk_ir::TyKind<Self>) -> Self::InternedType {
|
||||||
let flags = kind.compute_flags(self);
|
let flags = kind.compute_flags(self);
|
||||||
Interned::new(InternedWrapper(chalk_ir::TyData { kind, flags }))
|
Interned::new(InternedWrapper(chalk_ir::TyData { kind, flags }))
|
||||||
@ -272,6 +286,10 @@ fn intern_goal(self, goal: GoalData<Self>) -> Self::InternedGoal {
|
|||||||
Arc::new(goal)
|
Arc::new(goal)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn goal_data(self, goal: &Self::InternedGoal) -> &GoalData<Self> {
|
||||||
|
goal
|
||||||
|
}
|
||||||
|
|
||||||
fn intern_goals<E>(
|
fn intern_goals<E>(
|
||||||
self,
|
self,
|
||||||
data: impl IntoIterator<Item = Result<Goal<Self>, E>>,
|
data: impl IntoIterator<Item = Result<Goal<Self>, E>>,
|
||||||
@ -279,10 +297,6 @@ fn intern_goals<E>(
|
|||||||
data.into_iter().collect()
|
data.into_iter().collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn goal_data(self, goal: &Self::InternedGoal) -> &GoalData<Self> {
|
|
||||||
goal
|
|
||||||
}
|
|
||||||
|
|
||||||
fn goals_data(self, goals: &Self::InternedGoals) -> &[Goal<Interner>] {
|
fn goals_data(self, goals: &Self::InternedGoals) -> &[Goal<Interner>] {
|
||||||
goals
|
goals
|
||||||
}
|
}
|
||||||
@ -367,32 +381,18 @@ fn canonical_var_kinds_data(
|
|||||||
) -> &[chalk_ir::CanonicalVarKind<Self>] {
|
) -> &[chalk_ir::CanonicalVarKind<Self>] {
|
||||||
canonical_var_kinds
|
canonical_var_kinds
|
||||||
}
|
}
|
||||||
|
|
||||||
fn intern_constraints<E>(
|
fn intern_constraints<E>(
|
||||||
self,
|
self,
|
||||||
data: impl IntoIterator<Item = Result<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>, E>>,
|
data: impl IntoIterator<Item = Result<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>, E>>,
|
||||||
) -> Result<Self::InternedConstraints, E> {
|
) -> Result<Self::InternedConstraints, E> {
|
||||||
data.into_iter().collect()
|
data.into_iter().collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn constraints_data(
|
fn constraints_data(
|
||||||
self,
|
self,
|
||||||
constraints: &Self::InternedConstraints,
|
constraints: &Self::InternedConstraints,
|
||||||
) -> &[chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>] {
|
) -> &[chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>] {
|
||||||
constraints
|
constraints
|
||||||
}
|
}
|
||||||
fn debug_closure_id(
|
|
||||||
_fn_def_id: chalk_ir::ClosureId<Self>,
|
|
||||||
_fmt: &mut fmt::Formatter<'_>,
|
|
||||||
) -> Option<fmt::Result> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
fn debug_constraints(
|
|
||||||
_clauses: &chalk_ir::Constraints<Self>,
|
|
||||||
_fmt: &mut fmt::Formatter<'_>,
|
|
||||||
) -> Option<fmt::Result> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
fn intern_variances<E>(
|
fn intern_variances<E>(
|
||||||
self,
|
self,
|
||||||
|
@ -588,7 +588,7 @@ pub fn callable_sig_from_fnonce(
|
|||||||
let fn_once_trait = FnTrait::FnOnce.get_id(db, krate)?;
|
let fn_once_trait = FnTrait::FnOnce.get_id(db, krate)?;
|
||||||
let output_assoc_type = db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?;
|
let output_assoc_type = db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?;
|
||||||
|
|
||||||
let mut table = InferenceTable::new(db, env.clone());
|
let mut table = InferenceTable::new(db, env);
|
||||||
let b = TyBuilder::trait_ref(db, fn_once_trait);
|
let b = TyBuilder::trait_ref(db, fn_once_trait);
|
||||||
if b.remaining() != 2 {
|
if b.remaining() != 2 {
|
||||||
return None;
|
return None;
|
||||||
|
@ -1414,7 +1414,7 @@ fn exec_fn_def(
|
|||||||
}
|
}
|
||||||
CallableDefId::StructId(id) => {
|
CallableDefId::StructId(id) => {
|
||||||
let (size, variant_layout, tag) =
|
let (size, variant_layout, tag) =
|
||||||
self.layout_of_variant(id.into(), generic_args.clone(), &locals)?;
|
self.layout_of_variant(id.into(), generic_args, &locals)?;
|
||||||
let result = self.make_by_layout(
|
let result = self.make_by_layout(
|
||||||
size,
|
size,
|
||||||
&variant_layout,
|
&variant_layout,
|
||||||
@ -1425,7 +1425,7 @@ fn exec_fn_def(
|
|||||||
}
|
}
|
||||||
CallableDefId::EnumVariantId(id) => {
|
CallableDefId::EnumVariantId(id) => {
|
||||||
let (size, variant_layout, tag) =
|
let (size, variant_layout, tag) =
|
||||||
self.layout_of_variant(id.into(), generic_args.clone(), &locals)?;
|
self.layout_of_variant(id.into(), generic_args, &locals)?;
|
||||||
let result = self.make_by_layout(
|
let result = self.make_by_layout(
|
||||||
size,
|
size,
|
||||||
&variant_layout,
|
&variant_layout,
|
||||||
@ -1507,7 +1507,7 @@ fn exec_fn_with_args(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
let (imp, generic_args) =
|
let (imp, generic_args) =
|
||||||
lookup_impl_method(self.db, self.trait_env.clone(), def, generic_args.clone());
|
lookup_impl_method(self.db, self.trait_env.clone(), def, generic_args);
|
||||||
let generic_args = self.subst_filler(&generic_args, &locals);
|
let generic_args = self.subst_filler(&generic_args, &locals);
|
||||||
let def = imp.into();
|
let def = imp.into();
|
||||||
let mir_body =
|
let mir_body =
|
||||||
|
@ -69,9 +69,7 @@ pub(super) fn all_super_trait_refs<T>(
|
|||||||
cb: impl FnMut(TraitRef) -> Option<T>,
|
cb: impl FnMut(TraitRef) -> Option<T>,
|
||||||
) -> Option<T> {
|
) -> Option<T> {
|
||||||
let seen = iter::once(trait_ref.trait_id).collect();
|
let seen = iter::once(trait_ref.trait_id).collect();
|
||||||
let mut stack = Vec::new();
|
SuperTraits { db, seen, stack: vec![trait_ref] }.find_map(cb)
|
||||||
stack.push(trait_ref);
|
|
||||||
SuperTraits { db, seen, stack }.find_map(cb)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SuperTraits<'a> {
|
struct SuperTraits<'a> {
|
||||||
|
@ -148,7 +148,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>)
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let variants_of_enums = vec![variants.clone(); len];
|
let variants_of_enums = vec![variants; len];
|
||||||
|
|
||||||
let missing_pats = variants_of_enums
|
let missing_pats = variants_of_enums
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -5,6 +5,88 @@
|
|||||||
|
|
||||||
use crate::{AssistContext, AssistId, AssistKind, Assists};
|
use crate::{AssistContext, AssistId, AssistKind, Assists};
|
||||||
|
|
||||||
|
// Assist: convert_let_else_to_match
|
||||||
|
//
|
||||||
|
// Converts let-else statement to let statement and match expression.
|
||||||
|
//
|
||||||
|
// ```
|
||||||
|
// fn main() {
|
||||||
|
// let Ok(mut x) = f() else$0 { return };
|
||||||
|
// }
|
||||||
|
// ```
|
||||||
|
// ->
|
||||||
|
// ```
|
||||||
|
// fn main() {
|
||||||
|
// let mut x = match f() {
|
||||||
|
// Ok(x) => x,
|
||||||
|
// _ => return,
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
// ```
|
||||||
|
pub(crate) fn convert_let_else_to_match(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
|
||||||
|
// should focus on else token to trigger
|
||||||
|
let let_stmt = ctx
|
||||||
|
.find_token_syntax_at_offset(T![else])
|
||||||
|
.and_then(|it| it.parent()?.parent())
|
||||||
|
.or_else(|| ctx.find_token_syntax_at_offset(T![let])?.parent())?;
|
||||||
|
let let_stmt = LetStmt::cast(let_stmt)?;
|
||||||
|
let let_else_block = let_stmt.let_else()?.block_expr()?;
|
||||||
|
let let_init = let_stmt.initializer()?;
|
||||||
|
if let_stmt.ty().is_some() {
|
||||||
|
// don't support let with type annotation
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let pat = let_stmt.pat()?;
|
||||||
|
let mut binders = Vec::new();
|
||||||
|
binders_in_pat(&mut binders, &pat, &ctx.sema)?;
|
||||||
|
|
||||||
|
let target = let_stmt.syntax().text_range();
|
||||||
|
acc.add(
|
||||||
|
AssistId("convert_let_else_to_match", AssistKind::RefactorRewrite),
|
||||||
|
"Convert let-else to let and match",
|
||||||
|
target,
|
||||||
|
|edit| {
|
||||||
|
let indent_level = let_stmt.indent_level().0 as usize;
|
||||||
|
let indent = " ".repeat(indent_level);
|
||||||
|
let indent1 = " ".repeat(indent_level + 1);
|
||||||
|
|
||||||
|
let binders_str = binders_to_str(&binders, false);
|
||||||
|
let binders_str_mut = binders_to_str(&binders, true);
|
||||||
|
|
||||||
|
let init_expr = let_init.syntax().text();
|
||||||
|
let mut pat_no_mut = pat.syntax().text().to_string();
|
||||||
|
// remove the mut from the pattern
|
||||||
|
for (b, ismut) in binders.iter() {
|
||||||
|
if *ismut {
|
||||||
|
pat_no_mut = pat_no_mut.replace(&format!("mut {b}"), &b.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let only_expr = let_else_block.statements().next().is_none();
|
||||||
|
let branch2 = match &let_else_block.tail_expr() {
|
||||||
|
Some(tail) if only_expr => format!("{tail},"),
|
||||||
|
_ => let_else_block.syntax().text().to_string(),
|
||||||
|
};
|
||||||
|
let replace = if binders.is_empty() {
|
||||||
|
format!(
|
||||||
|
"match {init_expr} {{
|
||||||
|
{indent1}{pat_no_mut} => {binders_str}
|
||||||
|
{indent1}_ => {branch2}
|
||||||
|
{indent}}}"
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
format!(
|
||||||
|
"let {binders_str_mut} = match {init_expr} {{
|
||||||
|
{indent1}{pat_no_mut} => {binders_str},
|
||||||
|
{indent1}_ => {branch2}
|
||||||
|
{indent}}};"
|
||||||
|
)
|
||||||
|
};
|
||||||
|
edit.replace(target, replace);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// Gets a list of binders in a pattern, and whether they are mut.
|
/// Gets a list of binders in a pattern, and whether they are mut.
|
||||||
fn binders_in_pat(
|
fn binders_in_pat(
|
||||||
acc: &mut Vec<(Name, bool)>,
|
acc: &mut Vec<(Name, bool)>,
|
||||||
@ -97,85 +179,6 @@ fn binders_to_str(binders: &[(Name, bool)], addmut: bool) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assist: convert_let_else_to_match
|
|
||||||
//
|
|
||||||
// Converts let-else statement to let statement and match expression.
|
|
||||||
//
|
|
||||||
// ```
|
|
||||||
// fn main() {
|
|
||||||
// let Ok(mut x) = f() else$0 { return };
|
|
||||||
// }
|
|
||||||
// ```
|
|
||||||
// ->
|
|
||||||
// ```
|
|
||||||
// fn main() {
|
|
||||||
// let mut x = match f() {
|
|
||||||
// Ok(x) => x,
|
|
||||||
// _ => return,
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
// ```
|
|
||||||
pub(crate) fn convert_let_else_to_match(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
|
|
||||||
// should focus on else token to trigger
|
|
||||||
let else_token = ctx.find_token_syntax_at_offset(T![else])?;
|
|
||||||
let let_stmt = LetStmt::cast(else_token.parent()?.parent()?)?;
|
|
||||||
let let_else_block = let_stmt.let_else()?.block_expr()?;
|
|
||||||
let let_init = let_stmt.initializer()?;
|
|
||||||
if let_stmt.ty().is_some() {
|
|
||||||
// don't support let with type annotation
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let pat = let_stmt.pat()?;
|
|
||||||
let mut binders = Vec::new();
|
|
||||||
binders_in_pat(&mut binders, &pat, &ctx.sema)?;
|
|
||||||
|
|
||||||
let target = let_stmt.syntax().text_range();
|
|
||||||
acc.add(
|
|
||||||
AssistId("convert_let_else_to_match", AssistKind::RefactorRewrite),
|
|
||||||
"Convert let-else to let and match",
|
|
||||||
target,
|
|
||||||
|edit| {
|
|
||||||
let indent_level = let_stmt.indent_level().0 as usize;
|
|
||||||
let indent = " ".repeat(indent_level);
|
|
||||||
let indent1 = " ".repeat(indent_level + 1);
|
|
||||||
|
|
||||||
let binders_str = binders_to_str(&binders, false);
|
|
||||||
let binders_str_mut = binders_to_str(&binders, true);
|
|
||||||
|
|
||||||
let init_expr = let_init.syntax().text();
|
|
||||||
let mut pat_no_mut = pat.syntax().text().to_string();
|
|
||||||
// remove the mut from the pattern
|
|
||||||
for (b, ismut) in binders.iter() {
|
|
||||||
if *ismut {
|
|
||||||
pat_no_mut = pat_no_mut.replace(&format!("mut {b}"), &b.to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let only_expr = let_else_block.statements().next().is_none();
|
|
||||||
let branch2 = match &let_else_block.tail_expr() {
|
|
||||||
Some(tail) if only_expr => format!("{tail},"),
|
|
||||||
_ => let_else_block.syntax().text().to_string(),
|
|
||||||
};
|
|
||||||
let replace = if binders.is_empty() {
|
|
||||||
format!(
|
|
||||||
"match {init_expr} {{
|
|
||||||
{indent1}{pat_no_mut} => {binders_str}
|
|
||||||
{indent1}_ => {branch2}
|
|
||||||
{indent}}}"
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
format!(
|
|
||||||
"let {binders_str_mut} = match {init_expr} {{
|
|
||||||
{indent1}{pat_no_mut} => {binders_str},
|
|
||||||
{indent1}_ => {branch2}
|
|
||||||
{indent}}};"
|
|
||||||
)
|
|
||||||
};
|
|
||||||
edit.replace(target, replace);
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
// ```
|
// ```
|
||||||
// # //- minicore: option
|
// # //- minicore: option
|
||||||
// fn foo(opt: Option<()>) {
|
// fn foo(opt: Option<()>) {
|
||||||
// let val = $0match opt {
|
// let val$0 = match opt {
|
||||||
// Some(it) => it,
|
// Some(it) => it,
|
||||||
// None => return,
|
// None => return,
|
||||||
// };
|
// };
|
||||||
@ -30,7 +30,10 @@
|
|||||||
// ```
|
// ```
|
||||||
pub(crate) fn convert_match_to_let_else(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
|
pub(crate) fn convert_match_to_let_else(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
|
||||||
let let_stmt: ast::LetStmt = ctx.find_node_at_offset()?;
|
let let_stmt: ast::LetStmt = ctx.find_node_at_offset()?;
|
||||||
let binding = let_stmt.pat()?;
|
let pat = let_stmt.pat()?;
|
||||||
|
if ctx.offset() > pat.syntax().text_range().end() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
let Some(ast::Expr::MatchExpr(initializer)) = let_stmt.initializer() else { return None };
|
let Some(ast::Expr::MatchExpr(initializer)) = let_stmt.initializer() else { return None };
|
||||||
let initializer_expr = initializer.expr()?;
|
let initializer_expr = initializer.expr()?;
|
||||||
@ -56,7 +59,7 @@ pub(crate) fn convert_match_to_let_else(acc: &mut Assists, ctx: &AssistContext<'
|
|||||||
let_stmt.syntax().text_range(),
|
let_stmt.syntax().text_range(),
|
||||||
|builder| {
|
|builder| {
|
||||||
let extracting_arm_pat =
|
let extracting_arm_pat =
|
||||||
rename_variable(&extracting_arm_pat, &extracted_variable_positions, binding);
|
rename_variable(&extracting_arm_pat, &extracted_variable_positions, pat);
|
||||||
builder.replace(
|
builder.replace(
|
||||||
let_stmt.syntax().text_range(),
|
let_stmt.syntax().text_range(),
|
||||||
format!("let {extracting_arm_pat} = {initializer_expr} else {diverging_arm_expr};"),
|
format!("let {extracting_arm_pat} = {initializer_expr} else {diverging_arm_expr};"),
|
||||||
@ -161,7 +164,7 @@ fn should_not_be_applicable_for_non_diverging_match() {
|
|||||||
r#"
|
r#"
|
||||||
//- minicore: option
|
//- minicore: option
|
||||||
fn foo(opt: Option<()>) {
|
fn foo(opt: Option<()>) {
|
||||||
let val = $0match opt {
|
let val$0 = match opt {
|
||||||
Some(it) => it,
|
Some(it) => it,
|
||||||
None => (),
|
None => (),
|
||||||
};
|
};
|
||||||
@ -211,7 +214,7 @@ fn should_not_be_applicable_if_extracting_arm_is_not_an_identity_expr() {
|
|||||||
r#"
|
r#"
|
||||||
//- minicore: option
|
//- minicore: option
|
||||||
fn foo(opt: Option<i32>) {
|
fn foo(opt: Option<i32>) {
|
||||||
let val = $0match opt {
|
let val$0 = match opt {
|
||||||
Some(it) => it + 1,
|
Some(it) => it + 1,
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
@ -224,7 +227,7 @@ fn foo(opt: Option<i32>) {
|
|||||||
r#"
|
r#"
|
||||||
//- minicore: option
|
//- minicore: option
|
||||||
fn foo(opt: Option<()>) {
|
fn foo(opt: Option<()>) {
|
||||||
let val = $0match opt {
|
let val$0 = match opt {
|
||||||
Some(it) => {
|
Some(it) => {
|
||||||
let _ = 1 + 1;
|
let _ = 1 + 1;
|
||||||
it
|
it
|
||||||
@ -244,7 +247,7 @@ fn should_not_be_applicable_if_extracting_arm_has_guard() {
|
|||||||
r#"
|
r#"
|
||||||
//- minicore: option
|
//- minicore: option
|
||||||
fn foo(opt: Option<()>) {
|
fn foo(opt: Option<()>) {
|
||||||
let val = $0match opt {
|
let val$0 = match opt {
|
||||||
Some(it) if 2 > 1 => it,
|
Some(it) if 2 > 1 => it,
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
@ -260,7 +263,7 @@ fn basic_pattern() {
|
|||||||
r#"
|
r#"
|
||||||
//- minicore: option
|
//- minicore: option
|
||||||
fn foo(opt: Option<()>) {
|
fn foo(opt: Option<()>) {
|
||||||
let val = $0match opt {
|
let val$0 = match opt {
|
||||||
Some(it) => it,
|
Some(it) => it,
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
@ -281,7 +284,7 @@ fn keeps_modifiers() {
|
|||||||
r#"
|
r#"
|
||||||
//- minicore: option
|
//- minicore: option
|
||||||
fn foo(opt: Option<()>) {
|
fn foo(opt: Option<()>) {
|
||||||
let ref mut val = $0match opt {
|
let ref mut val$0 = match opt {
|
||||||
Some(it) => it,
|
Some(it) => it,
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
@ -302,7 +305,7 @@ fn nested_pattern() {
|
|||||||
r#"
|
r#"
|
||||||
//- minicore: option, result
|
//- minicore: option, result
|
||||||
fn foo(opt: Option<Result<()>>) {
|
fn foo(opt: Option<Result<()>>) {
|
||||||
let val = $0match opt {
|
let val$0 = match opt {
|
||||||
Some(Ok(it)) => it,
|
Some(Ok(it)) => it,
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
@ -324,7 +327,7 @@ fn works_with_any_diverging_block() {
|
|||||||
//- minicore: option
|
//- minicore: option
|
||||||
fn foo(opt: Option<()>) {
|
fn foo(opt: Option<()>) {
|
||||||
loop {
|
loop {
|
||||||
let val = $0match opt {
|
let val$0 = match opt {
|
||||||
Some(it) => it,
|
Some(it) => it,
|
||||||
None => break,
|
None => break,
|
||||||
};
|
};
|
||||||
@ -346,7 +349,7 @@ fn foo(opt: Option<()>) {
|
|||||||
//- minicore: option
|
//- minicore: option
|
||||||
fn foo(opt: Option<()>) {
|
fn foo(opt: Option<()>) {
|
||||||
loop {
|
loop {
|
||||||
let val = $0match opt {
|
let val$0 = match opt {
|
||||||
Some(it) => it,
|
Some(it) => it,
|
||||||
None => continue,
|
None => continue,
|
||||||
};
|
};
|
||||||
@ -370,7 +373,7 @@ fn panic() -> ! {}
|
|||||||
|
|
||||||
fn foo(opt: Option<()>) {
|
fn foo(opt: Option<()>) {
|
||||||
loop {
|
loop {
|
||||||
let val = $0match opt {
|
let val$0 = match opt {
|
||||||
Some(it) => it,
|
Some(it) => it,
|
||||||
None => panic(),
|
None => panic(),
|
||||||
};
|
};
|
||||||
@ -401,7 +404,7 @@ struct Point {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn foo(opt: Option<Point>) {
|
fn foo(opt: Option<Point>) {
|
||||||
let val = $0match opt {
|
let val$0 = match opt {
|
||||||
Some(Point { x: 0, y }) => y,
|
Some(Point { x: 0, y }) => y,
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
@ -427,7 +430,7 @@ fn renames_whole_binding() {
|
|||||||
r#"
|
r#"
|
||||||
//- minicore: option
|
//- minicore: option
|
||||||
fn foo(opt: Option<i32>) -> Option<i32> {
|
fn foo(opt: Option<i32>) -> Option<i32> {
|
||||||
let val = $0match opt {
|
let val$0 = match opt {
|
||||||
it @ Some(42) => it,
|
it @ Some(42) => it,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
@ -450,7 +453,7 @@ fn complex_pattern() {
|
|||||||
r#"
|
r#"
|
||||||
//- minicore: option
|
//- minicore: option
|
||||||
fn f() {
|
fn f() {
|
||||||
let (x, y) = $0match Some((0, 1)) {
|
let (x, y)$0 = match Some((0, 1)) {
|
||||||
Some(it) => it,
|
Some(it) => it,
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
@ -471,7 +474,7 @@ fn diverging_block() {
|
|||||||
r#"
|
r#"
|
||||||
//- minicore: option
|
//- minicore: option
|
||||||
fn f() {
|
fn f() {
|
||||||
let x = $0match Some(()) {
|
let x$0 = match Some(()) {
|
||||||
Some(it) => it,
|
Some(it) => it,
|
||||||
None => {//comment
|
None => {//comment
|
||||||
println!("nope");
|
println!("nope");
|
||||||
|
@ -106,10 +106,10 @@ fn get_text_for_generate_constant(
|
|||||||
let mut text = format!("{vis}const {constant_token}: {type_name} = $0;");
|
let mut text = format!("{vis}const {constant_token}: {type_name} = $0;");
|
||||||
while let Some(name_ref) = not_exist_name_ref.pop() {
|
while let Some(name_ref) = not_exist_name_ref.pop() {
|
||||||
let vis = if not_exist_name_ref.len() == 0 && !outer_exists { "" } else { "\npub " };
|
let vis = if not_exist_name_ref.len() == 0 && !outer_exists { "" } else { "\npub " };
|
||||||
text = text.replace("\n", "\n ");
|
text = text.replace('\n', "\n ");
|
||||||
text = format!("{vis}mod {name_ref} {{{text}\n}}");
|
text = format!("{vis}mod {name_ref} {{{text}\n}}");
|
||||||
}
|
}
|
||||||
Some(text.replace("\n", &format!("\n{indent}")))
|
Some(text.replace('\n', &format!("\n{indent}")))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn target_data_for_generate_constant(
|
fn target_data_for_generate_constant(
|
||||||
@ -131,7 +131,7 @@ fn target_data_for_generate_constant(
|
|||||||
|
|
||||||
let siblings_has_newline = l_curly_token
|
let siblings_has_newline = l_curly_token
|
||||||
.siblings_with_tokens(Direction::Next)
|
.siblings_with_tokens(Direction::Next)
|
||||||
.find(|it| it.kind() == SyntaxKind::WHITESPACE && it.to_string().contains("\n"))
|
.find(|it| it.kind() == SyntaxKind::WHITESPACE && it.to_string().contains('\n'))
|
||||||
.is_some();
|
.is_some();
|
||||||
let post_string =
|
let post_string =
|
||||||
if siblings_has_newline { format!("{indent}") } else { format!("\n{indent}") };
|
if siblings_has_newline { format!("{indent}") } else { format!("\n{indent}") };
|
||||||
|
@ -20,9 +20,10 @@
|
|||||||
// const test: Foo = Foo {foo: 1, bar: 0}
|
// const test: Foo = Foo {foo: 1, bar: 0}
|
||||||
// ```
|
// ```
|
||||||
pub(crate) fn reorder_fields(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
|
pub(crate) fn reorder_fields(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
|
||||||
let record = ctx.find_node_at_offset::<Either<ast::RecordExpr, ast::RecordPat>>()?;
|
let path = ctx.find_node_at_offset::<ast::Path>()?;
|
||||||
|
let record =
|
||||||
|
path.syntax().parent().and_then(<Either<ast::RecordExpr, ast::RecordPat>>::cast)?;
|
||||||
|
|
||||||
let path = record.as_ref().either(|it| it.path(), |it| it.path())?;
|
|
||||||
let ranks = compute_fields_ranks(&path, ctx)?;
|
let ranks = compute_fields_ranks(&path, ctx)?;
|
||||||
let get_rank_of_field =
|
let get_rank_of_field =
|
||||||
|of: Option<_>| *ranks.get(&of.unwrap_or_default()).unwrap_or(&usize::MAX);
|
|of: Option<_>| *ranks.get(&of.unwrap_or_default()).unwrap_or(&usize::MAX);
|
||||||
|
@ -51,15 +51,11 @@ pub(crate) fn unwrap_block(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option
|
|||||||
let replaced = match list.syntax().last_child() {
|
let replaced = match list.syntax().last_child() {
|
||||||
Some(last) => {
|
Some(last) => {
|
||||||
let stmts: Vec<ast::Stmt> = list.statements().collect();
|
let stmts: Vec<ast::Stmt> = list.statements().collect();
|
||||||
let initializer = ast::Expr::cast(last.clone())?;
|
let initializer = ast::Expr::cast(last)?;
|
||||||
let let_stmt = make::let_stmt(pattern, ty, Some(initializer));
|
let let_stmt = make::let_stmt(pattern, ty, Some(initializer));
|
||||||
if stmts.len() > 0 {
|
if stmts.len() > 0 {
|
||||||
let block = make::block_expr(stmts, None);
|
let block = make::block_expr(stmts, None);
|
||||||
format!(
|
format!("{}\n {}", update_expr_string(block.to_string()), let_stmt)
|
||||||
"{}\n {}",
|
|
||||||
update_expr_string(block.to_string()),
|
|
||||||
let_stmt.to_string()
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
let_stmt.to_string()
|
let_stmt.to_string()
|
||||||
}
|
}
|
||||||
|
@ -439,7 +439,7 @@ fn doctest_convert_match_to_let_else() {
|
|||||||
r#####"
|
r#####"
|
||||||
//- minicore: option
|
//- minicore: option
|
||||||
fn foo(opt: Option<()>) {
|
fn foo(opt: Option<()>) {
|
||||||
let val = $0match opt {
|
let val$0 = match opt {
|
||||||
Some(it) => it,
|
Some(it) => it,
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
|
@ -92,7 +92,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, file_id: FileId) -> Option<Vec<Assist>> {
|
|||||||
// if we aren't adding to a crate root, walk backwards such that we support `#[path = ...]` overrides if possible
|
// if we aren't adding to a crate root, walk backwards such that we support `#[path = ...]` overrides if possible
|
||||||
|
|
||||||
// build all parent paths of the form `../module_name/mod.rs` and `../module_name.rs`
|
// build all parent paths of the form `../module_name/mod.rs` and `../module_name.rs`
|
||||||
let paths = iter::successors(Some(parent.clone()), |prev| prev.parent()).filter_map(|path| {
|
let paths = iter::successors(Some(parent), |prev| prev.parent()).filter_map(|path| {
|
||||||
let parent = path.parent()?;
|
let parent = path.parent()?;
|
||||||
let (name, _) = path.name_and_extension()?;
|
let (name, _) = path.name_and_extension()?;
|
||||||
Some(([parent.join(&format!("{name}.rs"))?, path.join("mod.rs")?], name.to_owned()))
|
Some(([parent.join(&format!("{name}.rs"))?, path.join("mod.rs")?], name.to_owned()))
|
||||||
|
@ -66,7 +66,6 @@ pub fn run(self) -> Result<()> {
|
|||||||
.as_os_str()
|
.as_os_str()
|
||||||
.to_str()
|
.to_str()
|
||||||
.ok_or(anyhow::anyhow!("Unable to normalize project_root path"))?
|
.ok_or(anyhow::anyhow!("Unable to normalize project_root path"))?
|
||||||
.to_string()
|
|
||||||
),
|
),
|
||||||
text_document_encoding: scip_types::TextEncoding::UTF8.into(),
|
text_document_encoding: scip_types::TextEncoding::UTF8.into(),
|
||||||
special_fields: Default::default(),
|
special_fields: Default::default(),
|
||||||
@ -212,7 +211,7 @@ fn new_descriptor_str(
|
|||||||
|
|
||||||
fn new_descriptor(name: Name, suffix: scip_types::descriptor::Suffix) -> scip_types::Descriptor {
|
fn new_descriptor(name: Name, suffix: scip_types::descriptor::Suffix) -> scip_types::Descriptor {
|
||||||
let mut name = name.to_string();
|
let mut name = name.to_string();
|
||||||
if name.contains("'") {
|
if name.contains('\'') {
|
||||||
name = format!("`{name}`");
|
name = format!("`{name}`");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,7 +279,7 @@ fn completion_item(
|
|||||||
|
|
||||||
let mut lsp_item = lsp_types::CompletionItem {
|
let mut lsp_item = lsp_types::CompletionItem {
|
||||||
label: item.label.to_string(),
|
label: item.label.to_string(),
|
||||||
detail: item.detail.map(|it| it.to_string()),
|
detail: item.detail,
|
||||||
filter_text: Some(lookup),
|
filter_text: Some(lookup),
|
||||||
kind: Some(completion_item_kind(item.kind)),
|
kind: Some(completion_item_kind(item.kind)),
|
||||||
text_edit: Some(text_edit),
|
text_edit: Some(text_edit),
|
||||||
|
Loading…
Reference in New Issue
Block a user