Auto merge of #15206 - Veykril:let-else-fmt, r=Veykril

internal: Format let-else

As nightly finally got support for it I went ahead and formatted r-a with the latest nightly, then with the latest stable (in case other stuff changed)
This commit is contained in:
bors 2023-07-03 18:41:59 +00:00
commit daba334611
38 changed files with 572 additions and 306 deletions

View File

@ -137,13 +137,16 @@ impl Attrs {
let cfg_options = &crate_graph[krate].cfg_options;
let Some(variant) = enum_.variants.clone().filter(|variant| {
let attrs = item_tree.attrs(db, krate, (*variant).into());
attrs.is_cfg_enabled(cfg_options)
})
.zip(0u32..)
.find(|(_variant, idx)| it.local_id == Idx::from_raw(RawIdx::from(*idx)))
.map(|(variant, _idx)| variant)
let Some(variant) = enum_
.variants
.clone()
.filter(|variant| {
let attrs = item_tree.attrs(db, krate, (*variant).into());
attrs.is_cfg_enabled(cfg_options)
})
.zip(0u32..)
.find(|(_variant, idx)| it.local_id == Idx::from_raw(RawIdx::from(*idx)))
.map(|(variant, _idx)| variant)
else {
return Arc::new(res);
};

View File

@ -1451,9 +1451,7 @@ impl ExprCollector<'_> {
&self,
lifetime: Option<ast::Lifetime>,
) -> Result<Option<LabelId>, BodyDiagnostic> {
let Some(lifetime) = lifetime else {
return Ok(None)
};
let Some(lifetime) = lifetime else { return Ok(None) };
let name = Name::new_lifetime(&lifetime);
for (rib_idx, rib) in self.label_ribs.iter().enumerate().rev() {

View File

@ -2235,8 +2235,12 @@ impl ModCollector<'_, '_> {
}
fn import_all_legacy_macros(&mut self, module_id: LocalModuleId) {
let Some((source, target)) = Self::borrow_modules(self.def_collector.def_map.modules.as_mut(), module_id, self.module_id) else {
return
let Some((source, target)) = Self::borrow_modules(
self.def_collector.def_map.modules.as_mut(),
module_id,
self.module_id,
) else {
return;
};
for (name, macs) in source.scope.legacy_macros() {

View File

@ -135,10 +135,7 @@ impl Path {
pub fn segments(&self) -> PathSegments<'_> {
let Path::Normal { mod_path, generic_args, .. } = self else {
return PathSegments {
segments: &[],
generic_args: None,
};
return PathSegments { segments: &[], generic_args: None };
};
let s =
PathSegments { segments: mod_path.segments(), generic_args: generic_args.as_deref() };

View File

@ -74,8 +74,8 @@ pub(super) fn lower_path(mut path: ast::Path, ctx: &LowerCtx<'_>) -> Option<Path
// <T as Trait<A>>::Foo desugars to Trait<Self=T, A>::Foo
Some(trait_ref) => {
let Path::Normal { mod_path, generic_args: path_generic_args, .. } =
Path::from_src(trait_ref.path()?, ctx)? else
{
Path::from_src(trait_ref.path()?, ctx)?
else {
return None;
};
let num_segments = mod_path.segments().len();

View File

@ -692,7 +692,7 @@ pub(crate) fn include_arg_to_tt(
arg_id: MacroCallId,
) -> Result<(triomphe::Arc<(::tt::Subtree<::tt::TokenId>, TokenMap)>, FileId), ExpandError> {
let loc = db.lookup_intern_macro_call(arg_id);
let Some(EagerCallInfo {arg, arg_id: Some(arg_id), .. }) = loc.eager.as_deref() else {
let Some(EagerCallInfo { arg, arg_id: Some(arg_id), .. }) = loc.eager.as_deref() else {
panic!("include_arg_to_tt called on non include macro call: {:?}", &loc.eager);
};
let path = parse_string(&arg.0)?;

View File

@ -471,17 +471,13 @@ fn macro_expand(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult<Arc<tt
};
let Some(macro_arg) = db.macro_arg(id) else {
return ExpandResult {
value: Arc::new(
tt::Subtree {
delimiter: tt::Delimiter::UNSPECIFIED,
token_trees: Vec::new(),
},
),
value: Arc::new(tt::Subtree {
delimiter: tt::Delimiter::UNSPECIFIED,
token_trees: Vec::new(),
}),
// FIXME: We should make sure to enforce an invariant that invalid macro
// calls do not reach this call path!
err: Some(ExpandError::other(
"invalid token tree"
)),
err: Some(ExpandError::other("invalid token tree")),
};
};
let (arg_tt, arg_tm, undo_info) = &*macro_arg;
@ -510,9 +506,7 @@ fn expand_proc_macro(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult<A
delimiter: tt::Delimiter::UNSPECIFIED,
token_trees: Vec::new(),
}),
err: Some(ExpandError::other(
"invalid token tree"
)),
err: Some(ExpandError::other("invalid token tree")),
};
};
let (arg_tt, arg_tm, undo_info) = &*macro_arg;

View File

@ -42,10 +42,9 @@ pub fn expand_eager_macro_input(
let token_tree = macro_call.value.token_tree();
let Some(token_tree) = token_tree else {
return Ok(ExpandResult { value: None, err:
Some(ExpandError::other(
"invalid token tree"
)),
return Ok(ExpandResult {
value: None,
err: Some(ExpandError::other("invalid token tree")),
});
};
let (parsed_args, arg_token_map) = mbe::syntax_node_to_token_tree(token_tree.syntax());
@ -85,7 +84,7 @@ pub fn expand_eager_macro_input(
resolver,
)?;
let Some(expanded_eager_input) = expanded_eager_input else {
return Ok(ExpandResult { value: None, err })
return Ok(ExpandResult { value: None, err });
};
let (mut subtree, token_map) = mbe::syntax_node_to_token_tree(&expanded_eager_input);
subtree.delimiter = crate::tt::Delimiter::unspecified();

View File

@ -343,7 +343,8 @@ impl TyExt for Ty {
fn is_copy(self, db: &dyn HirDatabase, owner: DefWithBodyId) -> bool {
let crate_id = owner.module(db.upcast()).krate();
let Some(copy_trait) = db.lang_item(crate_id, LangItem::Copy).and_then(|x| x.as_trait()) else {
let Some(copy_trait) = db.lang_item(crate_id, LangItem::Copy).and_then(|x| x.as_trait())
else {
return false;
};
let trait_ref = TyBuilder::trait_ref(db, copy_trait).push(self).build();

View File

@ -636,7 +636,8 @@ fn render_const_scalar(
}
hir_def::AdtId::EnumId(e) => {
let Some((var_id, var_layout)) =
detect_variant_from_bytes(&layout, f.db, krate, b, e) else {
detect_variant_from_bytes(&layout, f.db, krate, b, e)
else {
return f.write_str("<failed-to-detect-variant>");
};
let data = &f.db.enum_data(e).variants[var_id];

View File

@ -1232,7 +1232,9 @@ impl<'a> InferenceContext<'a> {
.as_function()?
.lookup(self.db.upcast())
.container
else { return None };
else {
return None;
};
self.resolve_output_on(trait_)
}

View File

@ -154,7 +154,9 @@ pub fn layout_of_ty_query(
ty: Ty,
krate: CrateId,
) -> Result<Arc<Layout>, LayoutError> {
let Some(target) = db.target_data_layout(krate) else { return Err(LayoutError::TargetLayoutNotAvailable) };
let Some(target) = db.target_data_layout(krate) else {
return Err(LayoutError::TargetLayoutNotAvailable);
};
let cx = LayoutCx { krate, target: &target };
let dl = &*cx.current_data_layout();
let trait_env = Arc::new(TraitEnvironment::empty(krate));

View File

@ -31,7 +31,9 @@ pub fn layout_of_adt_query(
subst: Substitution,
krate: CrateId,
) -> Result<Arc<Layout>, LayoutError> {
let Some(target) = db.target_data_layout(krate) else { return Err(LayoutError::TargetLayoutNotAvailable) };
let Some(target) = db.target_data_layout(krate) else {
return Err(LayoutError::TargetLayoutNotAvailable);
};
let cx = LayoutCx { krate, target: &target };
let dl = cx.current_data_layout();
let handle_variant = |def: VariantId, var: &VariantData| {

View File

@ -689,7 +689,7 @@ pub fn lookup_impl_method(
fn_subst: Substitution,
) -> (FunctionId, Substitution) {
let ItemContainerId::TraitId(trait_id) = func.lookup(db.upcast()).container else {
return (func, fn_subst)
return (func, fn_subst);
};
let trait_params = db.generic_params(trait_id.into()).type_or_consts.len();
let fn_params = fn_subst.len(Interner) - trait_params;
@ -699,8 +699,8 @@ pub fn lookup_impl_method(
};
let name = &db.function_data(func).name;
let Some((impl_fn, impl_subst)) = lookup_impl_assoc_item_for_trait_ref(trait_ref, db, env, name)
.and_then(|assoc| {
let Some((impl_fn, impl_subst)) =
lookup_impl_assoc_item_for_trait_ref(trait_ref, db, env, name).and_then(|assoc| {
if let (AssocItemId::FunctionId(id), subst) = assoc {
Some((id, subst))
} else {

View File

@ -271,7 +271,10 @@ fn ever_initialized_map(
}
}
let Some(terminator) = &block.terminator else {
never!("Terminator should be none only in construction.\nThe body:\n{}", body.pretty_print(db));
never!(
"Terminator should be none only in construction.\nThe body:\n{}",
body.pretty_print(db)
);
return;
};
let targets = match &terminator.kind {

View File

@ -1226,8 +1226,8 @@ impl Evaluator<'_> {
}
Variants::Multiple { tag, tag_encoding, variants, .. } => {
let Some(target_data_layout) = self.db.target_data_layout(self.crate_id) else {
not_supported!("missing target data layout");
};
not_supported!("missing target data layout");
};
let size = tag.size(&*target_data_layout).bytes_usize();
let offset = layout.fields.offset(0).bytes_usize(); // The only field on enum variants is the tag field
match tag_encoding {
@ -1344,7 +1344,9 @@ impl Evaluator<'_> {
AdtId::UnionId(_) => not_supported!("unsizing unions"),
AdtId::EnumId(_) => not_supported!("unsizing enums"),
};
let Some((last_field, _)) = self.db.struct_data(id).variant_data.fields().iter().rev().next() else {
let Some((last_field, _)) =
self.db.struct_data(id).variant_data.fields().iter().rev().next()
else {
not_supported!("unsizing struct without field");
};
let target_last_field = self.db.field_types(id.into())[last_field]

View File

@ -327,7 +327,9 @@ impl Evaluator<'_> {
}
"pthread_getspecific" => {
let Some(arg0) = args.get(0) else {
return Err(MirEvalError::TypeError("pthread_getspecific arg0 is not provided"));
return Err(MirEvalError::TypeError(
"pthread_getspecific arg0 is not provided",
));
};
let key = from_bytes!(usize, &pad16(arg0.get(self)?, false)[0..8]);
let value = self.thread_local_storage.get_key(key)?;
@ -336,11 +338,15 @@ impl Evaluator<'_> {
}
"pthread_setspecific" => {
let Some(arg0) = args.get(0) else {
return Err(MirEvalError::TypeError("pthread_setspecific arg0 is not provided"));
return Err(MirEvalError::TypeError(
"pthread_setspecific arg0 is not provided",
));
};
let key = from_bytes!(usize, &pad16(arg0.get(self)?, false)[0..8]);
let Some(arg1) = args.get(1) else {
return Err(MirEvalError::TypeError("pthread_setspecific arg1 is not provided"));
return Err(MirEvalError::TypeError(
"pthread_setspecific arg1 is not provided",
));
};
let value = from_bytes!(u128, pad16(arg1.get(self)?, false));
self.thread_local_storage.set_key(key, value)?;
@ -390,7 +396,9 @@ impl Evaluator<'_> {
"sqrt" | "sin" | "cos" | "exp" | "exp2" | "log" | "log10" | "log2" | "fabs"
| "floor" | "ceil" | "trunc" | "rint" | "nearbyint" | "round" | "roundeven" => {
let [arg] = args else {
return Err(MirEvalError::TypeError("f64 intrinsic signature doesn't match fn (f64) -> f64"));
return Err(MirEvalError::TypeError(
"f64 intrinsic signature doesn't match fn (f64) -> f64",
));
};
let arg = from_bytes!(f64, arg.get(self)?);
match name {
@ -416,7 +424,9 @@ impl Evaluator<'_> {
}
"pow" | "minnum" | "maxnum" | "copysign" => {
let [arg1, arg2] = args else {
return Err(MirEvalError::TypeError("f64 intrinsic signature doesn't match fn (f64, f64) -> f64"));
return Err(MirEvalError::TypeError(
"f64 intrinsic signature doesn't match fn (f64, f64) -> f64",
));
};
let arg1 = from_bytes!(f64, arg1.get(self)?);
let arg2 = from_bytes!(f64, arg2.get(self)?);
@ -430,7 +440,9 @@ impl Evaluator<'_> {
}
"powi" => {
let [arg1, arg2] = args else {
return Err(MirEvalError::TypeError("powif64 signature doesn't match fn (f64, i32) -> f64"));
return Err(MirEvalError::TypeError(
"powif64 signature doesn't match fn (f64, i32) -> f64",
));
};
let arg1 = from_bytes!(f64, arg1.get(self)?);
let arg2 = from_bytes!(i32, arg2.get(self)?);
@ -438,7 +450,9 @@ impl Evaluator<'_> {
}
"fma" => {
let [arg1, arg2, arg3] = args else {
return Err(MirEvalError::TypeError("fmaf64 signature doesn't match fn (f64, f64, f64) -> f64"));
return Err(MirEvalError::TypeError(
"fmaf64 signature doesn't match fn (f64, f64, f64) -> f64",
));
};
let arg1 = from_bytes!(f64, arg1.get(self)?);
let arg2 = from_bytes!(f64, arg2.get(self)?);
@ -454,7 +468,9 @@ impl Evaluator<'_> {
"sqrt" | "sin" | "cos" | "exp" | "exp2" | "log" | "log10" | "log2" | "fabs"
| "floor" | "ceil" | "trunc" | "rint" | "nearbyint" | "round" | "roundeven" => {
let [arg] = args else {
return Err(MirEvalError::TypeError("f32 intrinsic signature doesn't match fn (f32) -> f32"));
return Err(MirEvalError::TypeError(
"f32 intrinsic signature doesn't match fn (f32) -> f32",
));
};
let arg = from_bytes!(f32, arg.get(self)?);
match name {
@ -480,7 +496,9 @@ impl Evaluator<'_> {
}
"pow" | "minnum" | "maxnum" | "copysign" => {
let [arg1, arg2] = args else {
return Err(MirEvalError::TypeError("f32 intrinsic signature doesn't match fn (f32, f32) -> f32"));
return Err(MirEvalError::TypeError(
"f32 intrinsic signature doesn't match fn (f32, f32) -> f32",
));
};
let arg1 = from_bytes!(f32, arg1.get(self)?);
let arg2 = from_bytes!(f32, arg2.get(self)?);
@ -494,7 +512,9 @@ impl Evaluator<'_> {
}
"powi" => {
let [arg1, arg2] = args else {
return Err(MirEvalError::TypeError("powif32 signature doesn't match fn (f32, i32) -> f32"));
return Err(MirEvalError::TypeError(
"powif32 signature doesn't match fn (f32, i32) -> f32",
));
};
let arg1 = from_bytes!(f32, arg1.get(self)?);
let arg2 = from_bytes!(i32, arg2.get(self)?);
@ -502,7 +522,9 @@ impl Evaluator<'_> {
}
"fma" => {
let [arg1, arg2, arg3] = args else {
return Err(MirEvalError::TypeError("fmaf32 signature doesn't match fn (f32, f32, f32) -> f32"));
return Err(MirEvalError::TypeError(
"fmaf32 signature doesn't match fn (f32, f32, f32) -> f32",
));
};
let arg1 = from_bytes!(f32, arg1.get(self)?);
let arg2 = from_bytes!(f32, arg2.get(self)?);
@ -515,14 +537,16 @@ impl Evaluator<'_> {
}
match name {
"size_of" => {
let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|x| x.ty(Interner)) else {
let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|x| x.ty(Interner))
else {
return Err(MirEvalError::TypeError("size_of generic arg is not provided"));
};
let size = self.size_of_sized(ty, locals, "size_of arg")?;
destination.write_from_bytes(self, &size.to_le_bytes()[0..destination.size])
}
"size_of_val" => {
let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|x| x.ty(Interner)) else {
let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|x| x.ty(Interner))
else {
return Err(MirEvalError::TypeError("size_of_val generic arg is not provided"));
};
let [arg] = args else {
@ -549,14 +573,16 @@ impl Evaluator<'_> {
destination.write_from_bytes(self, &size.to_le_bytes())
}
"min_align_of" | "pref_align_of" => {
let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|x| x.ty(Interner)) else {
let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|x| x.ty(Interner))
else {
return Err(MirEvalError::TypeError("align_of generic arg is not provided"));
};
let align = self.layout(ty)?.align.abi.bytes();
destination.write_from_bytes(self, &align.to_le_bytes()[0..destination.size])
}
"needs_drop" => {
let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|x| x.ty(Interner)) else {
let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|x| x.ty(Interner))
else {
return Err(MirEvalError::TypeError("size_of generic arg is not provided"));
};
let result = !ty.clone().is_copy(self.db, locals.body.owner);
@ -697,10 +723,15 @@ impl Evaluator<'_> {
}
"copy" | "copy_nonoverlapping" => {
let [src, dst, offset] = args else {
return Err(MirEvalError::TypeError("copy_nonoverlapping args are not provided"));
return Err(MirEvalError::TypeError(
"copy_nonoverlapping args are not provided",
));
};
let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|x| x.ty(Interner)) else {
return Err(MirEvalError::TypeError("copy_nonoverlapping generic arg is not provided"));
let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|x| x.ty(Interner))
else {
return Err(MirEvalError::TypeError(
"copy_nonoverlapping generic arg is not provided",
));
};
let src = Address::from_bytes(src.get(self)?)?;
let dst = Address::from_bytes(dst.get(self)?)?;
@ -715,7 +746,8 @@ impl Evaluator<'_> {
let [ptr, offset] = args else {
return Err(MirEvalError::TypeError("offset args are not provided"));
};
let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|x| x.ty(Interner)) else {
let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|x| x.ty(Interner))
else {
return Err(MirEvalError::TypeError("offset generic arg is not provided"));
};
let ptr = u128::from_le_bytes(pad16(ptr.get(self)?, false));
@ -824,8 +856,11 @@ impl Evaluator<'_> {
let [arg] = args else {
return Err(MirEvalError::TypeError("discriminant_value arg is not provided"));
};
let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|x| x.ty(Interner)) else {
return Err(MirEvalError::TypeError("discriminant_value generic arg is not provided"));
let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|x| x.ty(Interner))
else {
return Err(MirEvalError::TypeError(
"discriminant_value generic arg is not provided",
));
};
let addr = Address::from_bytes(arg.get(self)?)?;
let size = self.size_of_sized(ty, locals, "discriminant_value ptr type")?;

View File

@ -23,7 +23,8 @@ impl Evaluator<'_> {
fn detect_simd_ty(&self, ty: &Ty) -> Result<usize> {
match ty.kind(Interner) {
TyKind::Adt(_, subst) => {
let Some(len) = subst.as_slice(Interner).get(1).and_then(|x| x.constant(Interner)) else {
let Some(len) = subst.as_slice(Interner).get(1).and_then(|x| x.constant(Interner))
else {
return Err(MirEvalError::TypeError("simd type without len param"));
};
match try_const_usize(self.db, len) {
@ -89,7 +90,9 @@ impl Evaluator<'_> {
return Err(MirEvalError::TypeError("simd_shuffle args are not provided"));
};
let TyKind::Array(_, index_len) = index.ty.kind(Interner) else {
return Err(MirEvalError::TypeError("simd_shuffle index argument has non-array type"));
return Err(MirEvalError::TypeError(
"simd_shuffle index argument has non-array type",
));
};
let index_len = match try_const_usize(self.db, index_len) {
Some(x) => x as usize,

View File

@ -310,24 +310,30 @@ impl<'ctx> MirLowerCtx<'ctx> {
self.lower_expr_to_place_with_adjust(expr_id, temp.into(), current, rest)
}
Adjust::Deref(_) => {
let Some((p, current)) = self.lower_expr_as_place_with_adjust(current, expr_id, true, adjustments)? else {
return Ok(None);
};
let Some((p, current)) =
self.lower_expr_as_place_with_adjust(current, expr_id, true, adjustments)?
else {
return Ok(None);
};
self.push_assignment(current, place, Operand::Copy(p).into(), expr_id.into());
Ok(Some(current))
}
Adjust::Borrow(AutoBorrow::Ref(m) | AutoBorrow::RawPtr(m)) => {
let Some((p, current)) = self.lower_expr_as_place_with_adjust(current, expr_id, true, rest)? else {
return Ok(None);
};
let Some((p, current)) =
self.lower_expr_as_place_with_adjust(current, expr_id, true, rest)?
else {
return Ok(None);
};
let bk = BorrowKind::from_chalk(*m);
self.push_assignment(current, place, Rvalue::Ref(bk, p), expr_id.into());
Ok(Some(current))
}
Adjust::Pointer(cast) => {
let Some((p, current)) = self.lower_expr_as_place_with_adjust(current, expr_id, true, rest)? else {
return Ok(None);
};
let Some((p, current)) =
self.lower_expr_as_place_with_adjust(current, expr_id, true, rest)?
else {
return Ok(None);
};
self.push_assignment(
current,
place,
@ -373,45 +379,49 @@ impl<'ctx> MirLowerCtx<'ctx> {
}
}
Err(MirLowerError::IncompleteExpr)
},
}
Expr::Path(p) => {
let pr = if let Some((assoc, subst)) = self
.infer
.assoc_resolutions_for_expr(expr_id)
{
match assoc {
hir_def::AssocItemId::ConstId(c) => {
self.lower_const(c.into(), current, place, subst, expr_id.into(), self.expr_ty_without_adjust(expr_id))?;
return Ok(Some(current))
},
hir_def::AssocItemId::FunctionId(_) => {
// FnDefs are zero sized, no action is needed.
return Ok(Some(current))
let pr =
if let Some((assoc, subst)) = self.infer.assoc_resolutions_for_expr(expr_id) {
match assoc {
hir_def::AssocItemId::ConstId(c) => {
self.lower_const(
c.into(),
current,
place,
subst,
expr_id.into(),
self.expr_ty_without_adjust(expr_id),
)?;
return Ok(Some(current));
}
hir_def::AssocItemId::FunctionId(_) => {
// FnDefs are zero sized, no action is needed.
return Ok(Some(current));
}
hir_def::AssocItemId::TypeAliasId(_) => {
// FIXME: If it is unreachable, use proper error instead of `not_supported`.
not_supported!("associated functions and types")
}
}
hir_def::AssocItemId::TypeAliasId(_) => {
// FIXME: If it is unreachable, use proper error instead of `not_supported`.
not_supported!("associated functions and types")
},
}
} else if let Some(variant) = self
.infer
.variant_resolution_for_expr(expr_id)
{
match variant {
VariantId::EnumVariantId(e) => ValueNs::EnumVariantId(e),
VariantId::StructId(s) => ValueNs::StructId(s),
VariantId::UnionId(_) => implementation_error!("Union variant as path"),
}
} else {
let unresolved_name = || MirLowerError::unresolved_path(self.db, p);
let resolver = resolver_for_expr(self.db.upcast(), self.owner, expr_id);
resolver
.resolve_path_in_value_ns_fully(self.db.upcast(), p)
.ok_or_else(unresolved_name)?
};
} else if let Some(variant) = self.infer.variant_resolution_for_expr(expr_id) {
match variant {
VariantId::EnumVariantId(e) => ValueNs::EnumVariantId(e),
VariantId::StructId(s) => ValueNs::StructId(s),
VariantId::UnionId(_) => implementation_error!("Union variant as path"),
}
} else {
let unresolved_name = || MirLowerError::unresolved_path(self.db, p);
let resolver = resolver_for_expr(self.db.upcast(), self.owner, expr_id);
resolver
.resolve_path_in_value_ns_fully(self.db.upcast(), p)
.ok_or_else(unresolved_name)?
};
match pr {
ValueNs::LocalBinding(_) | ValueNs::StaticId(_) => {
let Some((temp, current)) = self.lower_expr_as_place_without_adjust(current, expr_id, false)? else {
let Some((temp, current)) =
self.lower_expr_as_place_without_adjust(current, expr_id, false)?
else {
return Ok(None);
};
self.push_assignment(
@ -423,11 +433,19 @@ impl<'ctx> MirLowerCtx<'ctx> {
Ok(Some(current))
}
ValueNs::ConstId(const_id) => {
self.lower_const(const_id.into(), current, place, Substitution::empty(Interner), expr_id.into(), self.expr_ty_without_adjust(expr_id))?;
self.lower_const(
const_id.into(),
current,
place,
Substitution::empty(Interner),
expr_id.into(),
self.expr_ty_without_adjust(expr_id),
)?;
Ok(Some(current))
}
ValueNs::EnumVariantId(variant_id) => {
let variant_data = &self.db.enum_data(variant_id.parent).variants[variant_id.local_id];
let variant_data =
&self.db.enum_data(variant_id.parent).variants[variant_id.local_id];
if variant_data.variant_data.kind() == StructKind::Unit {
let ty = self.infer.type_of_expr[expr_id].clone();
current = self.lower_enum_variant(
@ -478,7 +496,9 @@ impl<'ctx> MirLowerCtx<'ctx> {
}
}
Expr::If { condition, then_branch, else_branch } => {
let Some((discr, current)) = self.lower_expr_to_some_operand(*condition, current)? else {
let Some((discr, current)) =
self.lower_expr_to_some_operand(*condition, current)?
else {
return Ok(None);
};
let start_of_then = self.new_basic_block();
@ -501,15 +521,12 @@ impl<'ctx> MirLowerCtx<'ctx> {
Ok(self.merge_blocks(end_of_then, end_of_else, expr_id.into()))
}
Expr::Let { pat, expr } => {
let Some((cond_place, current)) = self.lower_expr_as_place(current, *expr, true)? else {
let Some((cond_place, current)) = self.lower_expr_as_place(current, *expr, true)?
else {
return Ok(None);
};
let (then_target, else_target) = self.pattern_match(
current,
None,
cond_place,
*pat,
)?;
let (then_target, else_target) =
self.pattern_match(current, None, cond_place, *pat)?;
self.write_bytes_to_place(
then_target,
place.clone(),
@ -533,31 +550,47 @@ impl<'ctx> MirLowerCtx<'ctx> {
}
Expr::Block { id: _, statements, tail, label } => {
if let Some(label) = label {
self.lower_loop(current, place.clone(), Some(*label), expr_id.into(), |this, begin| {
if let Some(current) = this.lower_block_to_place(statements, begin, *tail, place, expr_id.into())? {
let end = this.current_loop_end()?;
this.set_goto(current, end, expr_id.into());
}
Ok(())
})
self.lower_loop(
current,
place.clone(),
Some(*label),
expr_id.into(),
|this, begin| {
if let Some(current) = this.lower_block_to_place(
statements,
begin,
*tail,
place,
expr_id.into(),
)? {
let end = this.current_loop_end()?;
this.set_goto(current, end, expr_id.into());
}
Ok(())
},
)
} else {
self.lower_block_to_place(statements, current, *tail, place, expr_id.into())
}
}
Expr::Loop { body, label } => self.lower_loop(current, place, *label, expr_id.into(), |this, begin| {
let scope = this.push_drop_scope();
if let Some((_, mut current)) = this.lower_expr_as_place(begin, *body, true)? {
current = scope.pop_and_drop(this, current);
this.set_goto(current, begin, expr_id.into());
} else {
scope.pop_assume_dropped(this);
}
Ok(())
}),
Expr::While { condition, body, label } => {
self.lower_loop(current, place, *label, expr_id.into(),|this, begin| {
Expr::Loop { body, label } => {
self.lower_loop(current, place, *label, expr_id.into(), |this, begin| {
let scope = this.push_drop_scope();
let Some((discr, to_switch)) = this.lower_expr_to_some_operand(*condition, begin)? else {
if let Some((_, mut current)) = this.lower_expr_as_place(begin, *body, true)? {
current = scope.pop_and_drop(this, current);
this.set_goto(current, begin, expr_id.into());
} else {
scope.pop_assume_dropped(this);
}
Ok(())
})
}
Expr::While { condition, body, label } => {
self.lower_loop(current, place, *label, expr_id.into(), |this, begin| {
let scope = this.push_drop_scope();
let Some((discr, to_switch)) =
this.lower_expr_to_some_operand(*condition, begin)?
else {
return Ok(());
};
let fail_cond = this.new_basic_block();
@ -583,8 +616,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
})
}
Expr::Call { callee, args, .. } => {
if let Some((func_id, generic_args)) =
self.infer.method_resolution(expr_id) {
if let Some((func_id, generic_args)) = self.infer.method_resolution(expr_id) {
let ty = chalk_ir::TyKind::FnDef(
CallableDefId::FunctionId(func_id).to_chalk(self.db),
generic_args,
@ -604,21 +636,43 @@ impl<'ctx> MirLowerCtx<'ctx> {
match &callee_ty.data(Interner).kind {
chalk_ir::TyKind::FnDef(..) => {
let func = Operand::from_bytes(vec![], callee_ty.clone());
self.lower_call_and_args(func, args.iter().copied(), place, current, self.is_uninhabited(expr_id), expr_id.into())
self.lower_call_and_args(
func,
args.iter().copied(),
place,
current,
self.is_uninhabited(expr_id),
expr_id.into(),
)
}
chalk_ir::TyKind::Function(_) => {
let Some((func, current)) = self.lower_expr_to_some_operand(*callee, current)? else {
let Some((func, current)) =
self.lower_expr_to_some_operand(*callee, current)?
else {
return Ok(None);
};
self.lower_call_and_args(func, args.iter().copied(), place, current, self.is_uninhabited(expr_id), expr_id.into())
self.lower_call_and_args(
func,
args.iter().copied(),
place,
current,
self.is_uninhabited(expr_id),
expr_id.into(),
)
}
TyKind::Error => {
return Err(MirLowerError::MissingFunctionDefinition(self.owner, expr_id))
}
TyKind::Error => return Err(MirLowerError::MissingFunctionDefinition(self.owner, expr_id)),
_ => return Err(MirLowerError::TypeError("function call on bad type")),
}
}
Expr::MethodCall { receiver, args, method_name, .. } => {
let (func_id, generic_args) =
self.infer.method_resolution(expr_id).ok_or_else(|| MirLowerError::UnresolvedMethod(method_name.display(self.db.upcast()).to_string()))?;
self.infer.method_resolution(expr_id).ok_or_else(|| {
MirLowerError::UnresolvedMethod(
method_name.display(self.db.upcast()).to_string(),
)
})?;
let func = Operand::from_fn(self.db, func_id, generic_args);
self.lower_call_and_args(
func,
@ -630,23 +684,27 @@ impl<'ctx> MirLowerCtx<'ctx> {
)
}
Expr::Match { expr, arms } => {
let Some((cond_place, mut current)) = self.lower_expr_as_place(current, *expr, true)?
let Some((cond_place, mut current)) =
self.lower_expr_as_place(current, *expr, true)?
else {
return Ok(None);
};
let mut end = None;
for MatchArm { pat, guard, expr } in arms.iter() {
let (then, mut otherwise) = self.pattern_match(
current,
None,
cond_place.clone(),
*pat,
)?;
let (then, mut otherwise) =
self.pattern_match(current, None, cond_place.clone(), *pat)?;
let then = if let &Some(guard) = guard {
let next = self.new_basic_block();
let o = otherwise.get_or_insert_with(|| self.new_basic_block());
if let Some((discr, c)) = self.lower_expr_to_some_operand(guard, then)? {
self.set_terminator(c, TerminatorKind::SwitchInt { discr, targets: SwitchTargets::static_if(1, next, *o) }, expr_id.into());
self.set_terminator(
c,
TerminatorKind::SwitchInt {
discr,
targets: SwitchTargets::static_if(1, next, *o),
},
expr_id.into(),
);
}
next
} else {
@ -672,33 +730,53 @@ impl<'ctx> MirLowerCtx<'ctx> {
}
Expr::Continue { label } => {
let loop_data = match label {
Some(l) => self.labeled_loop_blocks.get(l).ok_or(MirLowerError::UnresolvedLabel)?,
None => self.current_loop_blocks.as_ref().ok_or(MirLowerError::ContinueWithoutLoop)?,
Some(l) => {
self.labeled_loop_blocks.get(l).ok_or(MirLowerError::UnresolvedLabel)?
}
None => self
.current_loop_blocks
.as_ref()
.ok_or(MirLowerError::ContinueWithoutLoop)?,
};
let begin = loop_data.begin;
current = self.drop_until_scope(loop_data.drop_scope_index, current);
self.set_goto(current, begin, expr_id.into());
Ok(None)
},
}
&Expr::Break { expr, label } => {
if let Some(expr) = expr {
let loop_data = match label {
Some(l) => self.labeled_loop_blocks.get(&l).ok_or(MirLowerError::UnresolvedLabel)?,
None => self.current_loop_blocks.as_ref().ok_or(MirLowerError::BreakWithoutLoop)?,
Some(l) => self
.labeled_loop_blocks
.get(&l)
.ok_or(MirLowerError::UnresolvedLabel)?,
None => self
.current_loop_blocks
.as_ref()
.ok_or(MirLowerError::BreakWithoutLoop)?,
};
let Some(c) = self.lower_expr_to_place(expr, loop_data.place.clone(), current)? else {
let Some(c) =
self.lower_expr_to_place(expr, loop_data.place.clone(), current)?
else {
return Ok(None);
};
current = c;
}
let (end, drop_scope) = match label {
Some(l) => {
let loop_blocks = self.labeled_loop_blocks.get(&l).ok_or(MirLowerError::UnresolvedLabel)?;
(loop_blocks.end.expect("We always generate end for labeled loops"), loop_blocks.drop_scope_index)
},
None => {
(self.current_loop_end()?, self.current_loop_blocks.as_ref().unwrap().drop_scope_index)
},
let loop_blocks = self
.labeled_loop_blocks
.get(&l)
.ok_or(MirLowerError::UnresolvedLabel)?;
(
loop_blocks.end.expect("We always generate end for labeled loops"),
loop_blocks.drop_scope_index,
)
}
None => (
self.current_loop_end()?,
self.current_loop_blocks.as_ref().unwrap().drop_scope_index,
),
};
current = self.drop_until_scope(drop_scope, current);
self.set_goto(current, end, expr_id.into());
@ -706,7 +784,9 @@ impl<'ctx> MirLowerCtx<'ctx> {
}
Expr::Return { expr } => {
if let Some(expr) = expr {
if let Some(c) = self.lower_expr_to_place(*expr, return_slot().into(), current)? {
if let Some(c) =
self.lower_expr_to_place(*expr, return_slot().into(), current)?
{
current = c;
} else {
return Ok(None);
@ -725,13 +805,11 @@ impl<'ctx> MirLowerCtx<'ctx> {
};
current = c;
Some(p)
},
}
None => None,
};
let variant_id = self
.infer
.variant_resolution_for_expr(expr_id)
.ok_or_else(|| match path {
let variant_id =
self.infer.variant_resolution_for_expr(expr_id).ok_or_else(|| match path {
Some(p) => MirLowerError::UnresolvedName(p.display(self.db).to_string()),
None => MirLowerError::RecordLiteralWithoutPath,
})?;
@ -746,7 +824,8 @@ impl<'ctx> MirLowerCtx<'ctx> {
for RecordLitField { name, expr } in fields.iter() {
let field_id =
variant_data.field(name).ok_or(MirLowerError::UnresolvedField)?;
let Some((op, c)) = self.lower_expr_to_some_operand(*expr, current)? else {
let Some((op, c)) = self.lower_expr_to_some_operand(*expr, current)?
else {
return Ok(None);
};
current = c;
@ -758,18 +837,23 @@ impl<'ctx> MirLowerCtx<'ctx> {
Rvalue::Aggregate(
AggregateKind::Adt(variant_id, subst),
match spread_place {
Some(sp) => operands.into_iter().enumerate().map(|(i, x)| {
match x {
Some(sp) => operands
.into_iter()
.enumerate()
.map(|(i, x)| match x {
Some(x) => x,
None => {
let p = sp.project(ProjectionElem::Field(FieldId {
parent: variant_id,
local_id: LocalFieldId::from_raw(RawIdx::from(i as u32)),
}));
let p =
sp.project(ProjectionElem::Field(FieldId {
parent: variant_id,
local_id: LocalFieldId::from_raw(
RawIdx::from(i as u32),
),
}));
Operand::Copy(p)
},
}
}).collect(),
}
})
.collect(),
None => operands.into_iter().collect::<Option<_>>().ok_or(
MirLowerError::TypeError("missing field in record literal"),
)?,
@ -785,7 +869,10 @@ impl<'ctx> MirLowerCtx<'ctx> {
};
let local_id =
variant_data.field(name).ok_or(MirLowerError::UnresolvedField)?;
let place = place.project(PlaceElem::Field(FieldId { parent: union_id.into(), local_id }));
let place = place.project(PlaceElem::Field(FieldId {
parent: union_id.into(),
local_id,
}));
self.lower_expr_to_place(*expr, place, current)
}
}
@ -795,9 +882,16 @@ impl<'ctx> MirLowerCtx<'ctx> {
Expr::Async { .. } => not_supported!("async block"),
&Expr::Const(id) => {
let subst = self.placeholder_subst();
self.lower_const(id.into(), current, place, subst, expr_id.into(), self.expr_ty_without_adjust(expr_id))?;
self.lower_const(
id.into(),
current,
place,
subst,
expr_id.into(),
self.expr_ty_without_adjust(expr_id),
)?;
Ok(Some(current))
},
}
Expr::Cast { expr, type_ref: _ } => {
let Some((x, current)) = self.lower_expr_to_some_operand(*expr, current)? else {
return Ok(None);
@ -822,23 +916,37 @@ impl<'ctx> MirLowerCtx<'ctx> {
}
Expr::Box { expr } => {
let ty = self.expr_ty_after_adjustments(*expr);
self.push_assignment(current, place.clone(), Rvalue::ShallowInitBoxWithAlloc(ty), expr_id.into());
let Some((operand, current)) = self.lower_expr_to_some_operand(*expr, current)? else {
self.push_assignment(
current,
place.clone(),
Rvalue::ShallowInitBoxWithAlloc(ty),
expr_id.into(),
);
let Some((operand, current)) = self.lower_expr_to_some_operand(*expr, current)?
else {
return Ok(None);
};
let p = place.project(ProjectionElem::Deref);
self.push_assignment(current, p, operand.into(), expr_id.into());
Ok(Some(current))
},
Expr::Field { .. } | Expr::Index { .. } | Expr::UnaryOp { op: hir_def::hir::UnaryOp::Deref, .. } => {
let Some((p, current)) = self.lower_expr_as_place_without_adjust(current, expr_id, true)? else {
}
Expr::Field { .. }
| Expr::Index { .. }
| Expr::UnaryOp { op: hir_def::hir::UnaryOp::Deref, .. } => {
let Some((p, current)) =
self.lower_expr_as_place_without_adjust(current, expr_id, true)?
else {
return Ok(None);
};
self.push_assignment(current, place, Operand::Copy(p).into(), expr_id.into());
Ok(Some(current))
}
Expr::UnaryOp { expr, op: op @ (hir_def::hir::UnaryOp::Not | hir_def::hir::UnaryOp::Neg) } => {
let Some((operand, current)) = self.lower_expr_to_some_operand(*expr, current)? else {
Expr::UnaryOp {
expr,
op: op @ (hir_def::hir::UnaryOp::Not | hir_def::hir::UnaryOp::Neg),
} => {
let Some((operand, current)) = self.lower_expr_to_some_operand(*expr, current)?
else {
return Ok(None);
};
let operation = match op {
@ -853,7 +961,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
expr_id.into(),
);
Ok(Some(current))
},
}
Expr::BinaryOp { lhs, rhs, op } => {
let op = op.ok_or(MirLowerError::IncompleteExpr)?;
let is_builtin = 'b: {
@ -861,16 +969,19 @@ impl<'ctx> MirLowerCtx<'ctx> {
// for binary operator, and use without adjust to simplify our conditions.
let lhs_ty = self.expr_ty_without_adjust(*lhs);
let rhs_ty = self.expr_ty_without_adjust(*rhs);
if matches!(op ,BinaryOp::CmpOp(syntax::ast::CmpOp::Eq { .. })) {
if matches!(op, BinaryOp::CmpOp(syntax::ast::CmpOp::Eq { .. })) {
if lhs_ty.as_raw_ptr().is_some() && rhs_ty.as_raw_ptr().is_some() {
break 'b true;
}
}
let builtin_inequal_impls = matches!(
op,
BinaryOp::ArithOp(ArithOp::Shl | ArithOp::Shr) | BinaryOp::Assignment { op: Some(ArithOp::Shl | ArithOp::Shr) }
BinaryOp::ArithOp(ArithOp::Shl | ArithOp::Shr)
| BinaryOp::Assignment { op: Some(ArithOp::Shl | ArithOp::Shr) }
);
lhs_ty.is_scalar() && rhs_ty.is_scalar() && (lhs_ty == rhs_ty || builtin_inequal_impls)
lhs_ty.is_scalar()
&& rhs_ty.is_scalar()
&& (lhs_ty == rhs_ty || builtin_inequal_impls)
};
if !is_builtin {
if let Some((func_id, generic_args)) = self.infer.method_resolution(expr_id) {
@ -894,32 +1005,43 @@ impl<'ctx> MirLowerCtx<'ctx> {
.get(lhs)
.and_then(|x| x.split_last())
.map(|x| x.1)
.ok_or(MirLowerError::TypeError("adjustment of binary op was missing"))?;
.ok_or(MirLowerError::TypeError(
"adjustment of binary op was missing",
))?;
let Some((lhs_place, current)) =
self.lower_expr_as_place_with_adjust(current, *lhs, false, adjusts)?
else {
return Ok(None);
};
let Some((rhs_op, current)) = self.lower_expr_to_some_operand(*rhs, current)? else {
let Some((rhs_op, current)) =
self.lower_expr_to_some_operand(*rhs, current)?
else {
return Ok(None);
};
let r_value = Rvalue::CheckedBinaryOp(op.into(), Operand::Copy(lhs_place.clone()), rhs_op);
let r_value = Rvalue::CheckedBinaryOp(
op.into(),
Operand::Copy(lhs_place.clone()),
rhs_op,
);
self.push_assignment(current, lhs_place, r_value, expr_id.into());
return Ok(Some(current));
} else {
let Some((lhs_place, current)) =
self.lower_expr_as_place(current, *lhs, false)?
self.lower_expr_as_place(current, *lhs, false)?
else {
return Ok(None);
};
let Some((rhs_op, current)) = self.lower_expr_to_some_operand(*rhs, current)? else {
let Some((rhs_op, current)) =
self.lower_expr_to_some_operand(*rhs, current)?
else {
return Ok(None);
};
self.push_assignment(current, lhs_place, rhs_op.into(), expr_id.into());
return Ok(Some(current));
}
}
let Some((lhs_op, current)) = self.lower_expr_to_some_operand(*lhs, current)? else {
let Some((lhs_op, current)) = self.lower_expr_to_some_operand(*lhs, current)?
else {
return Ok(None);
};
if let hir_def::hir::BinaryOp::LogicOp(op) = op {
@ -928,22 +1050,31 @@ impl<'ctx> MirLowerCtx<'ctx> {
syntax::ast::LogicOp::Or => 1,
};
let start_of_then = self.new_basic_block();
self.push_assignment(start_of_then, place.clone(), lhs_op.clone().into(), expr_id.into());
self.push_assignment(
start_of_then,
place.clone(),
lhs_op.clone().into(),
expr_id.into(),
);
let end_of_then = Some(start_of_then);
let start_of_else = self.new_basic_block();
let end_of_else =
self.lower_expr_to_place(*rhs, place, start_of_else)?;
let end_of_else = self.lower_expr_to_place(*rhs, place, start_of_else)?;
self.set_terminator(
current,
TerminatorKind::SwitchInt {
discr: lhs_op,
targets: SwitchTargets::static_if(value_to_short, start_of_then, start_of_else),
targets: SwitchTargets::static_if(
value_to_short,
start_of_then,
start_of_else,
),
},
expr_id.into(),
);
return Ok(self.merge_blocks(end_of_then, end_of_else, expr_id.into()));
}
let Some((rhs_op, current)) = self.lower_expr_to_some_operand(*rhs, current)? else {
let Some((rhs_op, current)) = self.lower_expr_to_some_operand(*rhs, current)?
else {
return Ok(None);
};
self.push_assignment(
@ -995,20 +1126,28 @@ impl<'ctx> MirLowerCtx<'ctx> {
place,
Rvalue::Aggregate(
AggregateKind::Adt(st.into(), subst.clone()),
self.db.struct_data(st).variant_data.fields().iter().map(|x| {
let o = match x.1.name.as_str() {
Some("start") => lp.take(),
Some("end") => rp.take(),
Some("exhausted") => Some(Operand::from_bytes(vec![0], TyBuilder::bool())),
_ => None,
};
o.ok_or(MirLowerError::UnresolvedField)
}).collect::<Result<_>>()?,
self.db
.struct_data(st)
.variant_data
.fields()
.iter()
.map(|x| {
let o = match x.1.name.as_str() {
Some("start") => lp.take(),
Some("end") => rp.take(),
Some("exhausted") => {
Some(Operand::from_bytes(vec![0], TyBuilder::bool()))
}
_ => None,
};
o.ok_or(MirLowerError::UnresolvedField)
})
.collect::<Result<_>>()?,
),
expr_id.into(),
);
Ok(Some(current))
},
}
Expr::Closure { .. } => {
let ty = self.expr_ty_without_adjust(expr_id);
let TyKind::Closure(id, _) = ty.kind(Interner) else {
@ -1020,22 +1159,33 @@ impl<'ctx> MirLowerCtx<'ctx> {
for capture in captures.iter() {
let p = Place {
local: self.binding_local(capture.place.local)?,
projection: capture.place.projections.clone().into_iter().map(|x| {
match x {
projection: capture
.place
.projections
.clone()
.into_iter()
.map(|x| match x {
ProjectionElem::Deref => ProjectionElem::Deref,
ProjectionElem::Field(x) => ProjectionElem::Field(x),
ProjectionElem::TupleOrClosureField(x) => ProjectionElem::TupleOrClosureField(x),
ProjectionElem::ConstantIndex { offset, from_end } => ProjectionElem::ConstantIndex { offset, from_end },
ProjectionElem::Subslice { from, to } => ProjectionElem::Subslice { from, to },
ProjectionElem::TupleOrClosureField(x) => {
ProjectionElem::TupleOrClosureField(x)
}
ProjectionElem::ConstantIndex { offset, from_end } => {
ProjectionElem::ConstantIndex { offset, from_end }
}
ProjectionElem::Subslice { from, to } => {
ProjectionElem::Subslice { from, to }
}
ProjectionElem::OpaqueCast(x) => ProjectionElem::OpaqueCast(x),
ProjectionElem::Index(x) => match x { },
}
}).collect(),
ProjectionElem::Index(x) => match x {},
})
.collect(),
};
match &capture.kind {
CaptureKind::ByRef(bk) => {
let placeholder_subst = self.placeholder_subst();
let tmp_ty = capture.ty.clone().substitute(Interner, &placeholder_subst);
let tmp_ty =
capture.ty.clone().substitute(Interner, &placeholder_subst);
let tmp: Place = self.temp(tmp_ty, current, capture.span)?.into();
self.push_assignment(
current,
@ -1044,7 +1194,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
capture.span,
);
operands.push(Operand::Move(tmp));
},
}
CaptureKind::ByValue => operands.push(Operand::Move(p)),
}
}
@ -1055,18 +1205,18 @@ impl<'ctx> MirLowerCtx<'ctx> {
expr_id.into(),
);
Ok(Some(current))
},
}
Expr::Tuple { exprs, is_assignee_expr: _ } => {
let Some(values) = exprs
.iter()
.map(|x| {
let Some((o, c)) = self.lower_expr_to_some_operand(*x, current)? else {
return Ok(None);
};
current = c;
Ok(Some(o))
})
.collect::<Result<Option<_>>>()?
.iter()
.map(|x| {
let Some((o, c)) = self.lower_expr_to_some_operand(*x, current)? else {
return Ok(None);
};
current = c;
Ok(Some(o))
})
.collect::<Result<Option<_>>>()?
else {
return Ok(None);
};
@ -1088,27 +1238,26 @@ impl<'ctx> MirLowerCtx<'ctx> {
}
};
let Some(values) = elements
.iter()
.map(|x| {
let Some((o, c)) = self.lower_expr_to_some_operand(*x, current)? else {
return Ok(None);
};
current = c;
Ok(Some(o))
})
.collect::<Result<Option<_>>>()?
.iter()
.map(|x| {
let Some((o, c)) = self.lower_expr_to_some_operand(*x, current)? else {
return Ok(None);
};
current = c;
Ok(Some(o))
})
.collect::<Result<Option<_>>>()?
else {
return Ok(None);
};
let r = Rvalue::Aggregate(
AggregateKind::Array(elem_ty),
values,
);
let r = Rvalue::Aggregate(AggregateKind::Array(elem_ty), values);
self.push_assignment(current, place, r, expr_id.into());
Ok(Some(current))
}
Array::Repeat { initializer, .. } => {
let Some((init, current)) = self.lower_expr_to_some_operand(*initializer, current)? else {
let Some((init, current)) =
self.lower_expr_to_some_operand(*initializer, current)?
else {
return Ok(None);
};
let len = match &self.expr_ty_without_adjust(expr_id).data(Interner).kind {
@ -1122,7 +1271,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
let r = Rvalue::Repeat(init, len);
self.push_assignment(current, place, r, expr_id.into());
Ok(Some(current))
},
}
},
Expr::Literal(l) => {
let ty = self.expr_ty_without_adjust(expr_id);

View File

@ -18,7 +18,9 @@ impl MirLowerCtx<'_> {
) -> Result<Option<(Place, BasicBlockId)>> {
let ty = self.expr_ty_without_adjust(expr_id);
let place = self.temp(ty, prev_block, expr_id.into())?;
let Some(current) = self.lower_expr_to_place_without_adjust(expr_id, place.into(), prev_block)? else {
let Some(current) =
self.lower_expr_to_place_without_adjust(expr_id, place.into(), prev_block)?
else {
return Ok(None);
};
Ok(Some((place.into(), current)))
@ -35,7 +37,9 @@ impl MirLowerCtx<'_> {
.map(|x| x.target.clone())
.unwrap_or_else(|| self.expr_ty_without_adjust(expr_id));
let place = self.temp(ty, prev_block, expr_id.into())?;
let Some(current) = self.lower_expr_to_place_with_adjust(expr_id, place.into(), prev_block, adjustments)? else {
let Some(current) =
self.lower_expr_to_place_with_adjust(expr_id, place.into(), prev_block, adjustments)?
else {
return Ok(None);
};
Ok(Some((place.into(), current)))
@ -62,7 +66,8 @@ impl MirLowerCtx<'_> {
expr_id,
upgrade_rvalue,
rest,
)? else {
)?
else {
return Ok(None);
};
x.0 = x.0.project(ProjectionElem::Deref);
@ -74,7 +79,8 @@ impl MirLowerCtx<'_> {
expr_id,
upgrade_rvalue,
rest,
)? else {
)?
else {
return Ok(None);
};
self.lower_overloaded_deref(
@ -165,7 +171,8 @@ impl MirLowerCtx<'_> {
_ => false,
};
if !is_builtin {
let Some((p, current)) = self.lower_expr_as_place(current, *expr, true)? else {
let Some((p, current)) = self.lower_expr_as_place(current, *expr, true)?
else {
return Ok(None);
};
return self.lower_overloaded_deref(
@ -192,7 +199,8 @@ impl MirLowerCtx<'_> {
},
);
}
let Some((mut r, current)) = self.lower_expr_as_place(current, *expr, true)? else {
let Some((mut r, current)) = self.lower_expr_as_place(current, *expr, true)?
else {
return Ok(None);
};
r = r.project(ProjectionElem::Deref);
@ -217,12 +225,18 @@ impl MirLowerCtx<'_> {
)
{
let Some(index_fn) = self.infer.method_resolution(expr_id) else {
return Err(MirLowerError::UnresolvedMethod("[overloaded index]".to_string()));
return Err(MirLowerError::UnresolvedMethod(
"[overloaded index]".to_string(),
));
};
let Some((base_place, current)) = self.lower_expr_as_place(current, *base, true)? else {
let Some((base_place, current)) =
self.lower_expr_as_place(current, *base, true)?
else {
return Ok(None);
};
let Some((index_operand, current)) = self.lower_expr_to_some_operand(*index, current)? else {
let Some((index_operand, current)) =
self.lower_expr_to_some_operand(*index, current)?
else {
return Ok(None);
};
return self.lower_overloaded_index(
@ -249,7 +263,8 @@ impl MirLowerCtx<'_> {
};
let l_index =
self.temp(self.expr_ty_after_adjustments(*index), current, expr_id.into())?;
let Some(current) = self.lower_expr_to_place(*index, l_index.into(), current)? else {
let Some(current) = self.lower_expr_to_place(*index, l_index.into(), current)?
else {
return Ok(None);
};
p_base = p_base.project(ProjectionElem::Index(l_index));
@ -282,7 +297,15 @@ impl MirLowerCtx<'_> {
)
.intern(Interner),
);
let Some(current) = self.lower_call(index_fn_op, Box::new([Operand::Copy(place), index_operand]), result.clone(), current, false, span)? else {
let Some(current) = self.lower_call(
index_fn_op,
Box::new([Operand::Copy(place), index_operand]),
result.clone(),
current,
false,
span,
)?
else {
return Ok(None);
};
result = result.project(ProjectionElem::Deref);
@ -329,7 +352,15 @@ impl MirLowerCtx<'_> {
.intern(Interner),
);
let mut result: Place = self.temp(target_ty_ref, current, span)?.into();
let Some(current) = self.lower_call(deref_fn_op, Box::new([Operand::Copy(ref_place)]), result.clone(), current, false, span)? else {
let Some(current) = self.lower_call(
deref_fn_op,
Box::new([Operand::Copy(ref_place)]),
result.clone(),
current,
false,
span,
)?
else {
return Ok(None);
};
result = result.project(ProjectionElem::Deref);

View File

@ -206,7 +206,9 @@ fn check_impl(ra_fixture: &str, allow_none: bool, only_types: bool, display_sour
let Some(node) = (match expr_or_pat {
hir_def::hir::ExprOrPatId::ExprId(expr) => expr_node(&body_source_map, expr, &db),
hir_def::hir::ExprOrPatId::PatId(pat) => pat_node(&body_source_map, pat, &db),
}) else { continue; };
}) else {
continue;
};
let range = node.as_ref().original_file_range(&db);
let actual = format!(
"expected {}, got {}",

View File

@ -701,9 +701,9 @@ fn emit_macro_def_diagnostics(db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>
let id = macro_id_to_def_id(db.upcast(), m.id);
if let Err(e) = db.macro_def(id) {
let Some(ast) = id.ast_id().left() else {
never!("MacroDefError for proc-macro: {:?}", e);
return;
};
never!("MacroDefError for proc-macro: {:?}", e);
return;
};
emit_def_diagnostic_(
db,
acc,

View File

@ -1494,7 +1494,11 @@ impl<'db> SemanticsImpl<'db> {
}
fn is_inside_unsafe(&self, expr: &ast::Expr) -> bool {
let Some(enclosing_item) = expr.syntax().ancestors().find_map(Either::<ast::Item, ast::Variant>::cast) else { return false };
let Some(enclosing_item) =
expr.syntax().ancestors().find_map(Either::<ast::Item, ast::Variant>::cast)
else {
return false;
};
let def = match &enclosing_item {
Either::Left(ast::Item::Fn(it)) if it.unsafe_token().is_some() => return true,

View File

@ -27,7 +27,9 @@ use crate::{
pub(crate) fn desugar_doc_comment(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
let comment = ctx.find_token_at_offset::<ast::Comment>()?;
// Only allow doc comments
let Some(placement) = comment.kind().doc else { return None; };
let Some(placement) = comment.kind().doc else {
return None;
};
// Only allow comments which are alone on their line
if let Some(prev) = comment.syntax().prev_token() {

View File

@ -40,12 +40,16 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>)
let qualifier = path.qualifier()?;
let name_ref = path.segment()?.name_ref()?;
let qualifier_res = ctx.sema.resolve_path(&qualifier)?;
let PathResolution::Def(ModuleDef::Module(module)) = qualifier_res else { return None; };
let PathResolution::Def(ModuleDef::Module(module)) = qualifier_res else {
return None;
};
let (_, def) = module
.scope(ctx.db(), None)
.into_iter()
.find(|(name, _)| name.to_smol_str() == name_ref.text().as_str())?;
let ScopeDef::ModuleDef(def) = def else { return None; };
let ScopeDef::ModuleDef(def) = def else {
return None;
};
let current_module = ctx.sema.scope(path.syntax())?.module();
let target_module = def.module(ctx.db())?;

View File

@ -88,7 +88,9 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<'
let adt = ast::Adt::Struct(strukt.clone());
let name = name.display(ctx.db()).to_string();
// if `find_struct_impl` returns None, that means that a function named `name` already exists.
let Some(impl_def) = find_struct_impl(ctx, &adt, std::slice::from_ref(&name)) else { continue; };
let Some(impl_def) = find_struct_impl(ctx, &adt, std::slice::from_ref(&name)) else {
continue;
};
acc.add_group(
&GroupLabel("Generate delegate methods…".to_owned()),
AssistId("generate_delegate_methods", AssistKind::Generate),

View File

@ -623,7 +623,9 @@ fn fn_generic_params(
fn params_and_where_preds_in_scope(
ctx: &AssistContext<'_>,
) -> (Vec<ast::GenericParam>, Vec<ast::WherePred>) {
let Some(body) = containing_body(ctx) else { return Default::default(); };
let Some(body) = containing_body(ctx) else {
return Default::default();
};
let mut generic_params = Vec::new();
let mut where_clauses = Vec::new();

View File

@ -54,7 +54,11 @@ pub(crate) fn move_const_to_impl(acc: &mut Assists, ctx: &AssistContext<'_>) ->
// NOTE: We can technically provide this assist for default methods in trait definitions, but
// it's somewhat complex to handle it correctly when the const's name conflicts with
// supertrait's item. We may want to consider implementing it in the future.
let AssocItemContainer::Impl(impl_) = ctx.sema.to_def(&parent_fn)?.as_assoc_item(db)?.container(db) else { return None; };
let AssocItemContainer::Impl(impl_) =
ctx.sema.to_def(&parent_fn)?.as_assoc_item(db)?.container(db)
else {
return None;
};
if impl_.trait_(db).is_some() {
return None;
}

View File

@ -38,14 +38,18 @@ pub(crate) fn unwrap_result_return_type(acc: &mut Assists, ctx: &AssistContext<'
};
let type_ref = &ret_type.ty()?;
let Some(hir::Adt::Enum(ret_enum)) = ctx.sema.resolve_type(type_ref)?.as_adt() else { return None; };
let Some(hir::Adt::Enum(ret_enum)) = ctx.sema.resolve_type(type_ref)?.as_adt() else {
return None;
};
let result_enum =
FamousDefs(&ctx.sema, ctx.sema.scope(type_ref.syntax())?.krate()).core_result_Result()?;
if ret_enum != result_enum {
return None;
}
let Some(ok_type) = unwrap_result_type(type_ref) else { return None; };
let Some(ok_type) = unwrap_result_type(type_ref) else {
return None;
};
acc.add(
AssistId("unwrap_result_return_type", AssistKind::RefactorRewrite),
@ -130,12 +134,16 @@ fn tail_cb_impl(acc: &mut Vec<ast::Expr>, e: &ast::Expr) {
// Tries to extract `T` from `Result<T, E>`.
fn unwrap_result_type(ty: &ast::Type) -> Option<ast::Type> {
let ast::Type::PathType(path_ty) = ty else { return None; };
let ast::Type::PathType(path_ty) = ty else {
return None;
};
let path = path_ty.path()?;
let segment = path.first_segment()?;
let generic_arg_list = segment.generic_arg_list()?;
let generic_args: Vec<_> = generic_arg_list.generic_args().collect();
let ast::GenericArg::TypeArg(ok_type) = generic_args.first()? else { return None; };
let ast::GenericArg::TypeArg(ok_type) = generic_args.first()? else {
return None;
};
ok_type.ty()
}

View File

@ -463,7 +463,9 @@ impl CompletionContext<'_> {
/// Checks whether this item should be listed in regards to stability. Returns `true` if we should.
pub(crate) fn check_stability(&self, attrs: Option<&hir::Attrs>) -> bool {
let Some(attrs) = attrs else { return true; };
let Some(attrs) = attrs else {
return true;
};
!attrs.is_unstable() || self.is_nightly
}

View File

@ -243,10 +243,7 @@ fn analyze(
let Some(name_like) = find_node_at_offset(&speculative_file, offset) else {
let analysis = if let Some(original) = ast::String::cast(original_token.clone()) {
CompletionAnalysis::String {
original,
expanded: ast::String::cast(self_token.clone()),
}
CompletionAnalysis::String { original, expanded: ast::String::cast(self_token.clone()) }
} else {
// Fix up trailing whitespace problem
// #[attr(foo = $0

View File

@ -119,10 +119,11 @@ fn fixes(ctx: &DiagnosticsContext<'_>, file_id: FileId) -> Option<Vec<Assist>> {
stack.pop();
'crates: for &krate in ctx.sema.db.relevant_crates(parent_id).iter() {
let crate_def_map = ctx.sema.db.crate_def_map(krate);
let Some((_, module)) =
crate_def_map.modules()
.find(|(_, module)| module.origin.file_id() == Some(parent_id) && !module.origin.is_inline())
else { continue };
let Some((_, module)) = crate_def_map.modules().find(|(_, module)| {
module.origin.file_id() == Some(parent_id) && !module.origin.is_inline()
}) else {
continue;
};
if stack.is_empty() {
return make_fixes(

View File

@ -330,7 +330,9 @@ fn get_doc_links(
base_url.and_then(|url| url.join(path).ok())
};
let Some((target, file, frag)) = filename_and_frag_for_def(db, def) else { return Default::default(); };
let Some((target, file, frag)) = filename_and_frag_for_def(db, def) else {
return Default::default();
};
let (mut web_url, mut local_url) = get_doc_base_urls(db, target, target_dir, sysroot);

View File

@ -259,7 +259,7 @@ fn needs_parens_for_adjustment_hints(expr: &ast::Expr, postfix: bool) -> (bool,
}
})() else {
never!("broken syntax tree?\n{:?}\n{:?}", expr, dummy_expr);
return (true, true)
return (true, true);
};
// At this point

View File

@ -274,10 +274,12 @@ impl flags::AnalysisStats {
continue;
}
all += 1;
let Err(e)
= db.layout_of_adt(hir_def::AdtId::from(a).into(), Substitution::empty(Interner), a.krate(db).into())
else {
continue
let Err(e) = db.layout_of_adt(
hir_def::AdtId::from(a).into(),
Substitution::empty(Interner),
a.krate(db).into(),
) else {
continue;
};
if verbosity.is_spammy() {
let full_name = full_name_of_item(db, a.module(db), a.name(db));

View File

@ -1331,7 +1331,9 @@ pub(crate) fn handle_code_lens_resolve(
snap: GlobalStateSnapshot,
code_lens: CodeLens,
) -> anyhow::Result<CodeLens> {
let Some(annotation) = from_proto::annotation(&snap, code_lens.clone())? else { return Ok(code_lens) };
let Some(annotation) = from_proto::annotation(&snap, code_lens.clone())? else {
return Ok(code_lens);
};
let annotation = snap.analysis.resolve_annotation(annotation)?;
let mut acc = Vec::new();
@ -1632,9 +1634,9 @@ pub(crate) fn handle_open_docs(
let Ok(remote_urls) = snap.analysis.external_docs(position, target_dir, sysroot) else {
return if snap.config.local_docs() {
Ok(ExternalDocsResponse::WithLocal(Default::default()))
} else {
} else {
Ok(ExternalDocsResponse::Simple(None))
}
};
};
let web = remote_urls.web_url.and_then(|it| Url::parse(&it).ok());

View File

@ -334,7 +334,11 @@ impl GlobalState {
let _p = profile::span("GlobalState::switch_workspaces");
tracing::info!(%cause, "will switch workspaces");
let Some((workspaces, force_reload_crate_graph)) = self.fetch_workspaces_queue.last_op_result() else { return; };
let Some((workspaces, force_reload_crate_graph)) =
self.fetch_workspaces_queue.last_op_result()
else {
return;
};
if let Err(_) = self.fetch_workspace_error() {
if !self.workspaces.is_empty() {
@ -525,7 +529,7 @@ impl GlobalState {
let mut buf = String::new();
let Some((last_op_result, _)) = self.fetch_workspaces_queue.last_op_result() else {
return Ok(())
return Ok(());
};
if last_op_result.is_empty() {
stdx::format_to!(buf, "rust-analyzer failed to discover workspace");

View File

@ -61,7 +61,9 @@ impl CommentBlock {
let mut blocks = CommentBlock::extract_untagged(text);
blocks.retain_mut(|block| {
let first = block.contents.remove(0);
let Some(id) = first.strip_prefix(&tag) else { return false; };
let Some(id) = first.strip_prefix(&tag) else {
return false;
};
if block.is_doc {
panic!("Use plain (non-doc) comments with tags like {tag}:\n {first}");