Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/hir-def/src/expr_store/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2731,7 +2731,7 @@ impl<'db> ExprCollector<'db> {
pats.push(self.collect_pat(first, binding_list));
binding_list.reject_new = true;
for rest in it {
for (_, it) in binding_list.is_used.iter_mut() {
for it in binding_list.is_used.values_mut() {
*it = false;
}
pats.push(self.collect_pat(rest, binding_list));
Expand Down
5 changes: 4 additions & 1 deletion crates/hir-def/src/item_tree/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,10 @@ impl UseTreeLowering<'_> {
Some(path) => {
match ModPath::from_src(self.db, path, span_for_range) {
Some(it) => Some(it),
None => return None, // FIXME: report errors somewhere
None => {
// FIXME: report errors somewhere
return None;
}
}
}
};
Expand Down
2 changes: 1 addition & 1 deletion crates/hir-expand/src/eager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ fn eager_macro_recur(
let syntax_node = parse.syntax_node();
ExpandResult {
value: Some((
syntax_node.clone_for_update(),
syntax_node.clone(),
offset + syntax_node.text_range().len(),
)),
err: err.clone().or_else(|| err2.clone()),
Expand Down
5 changes: 2 additions & 3 deletions crates/hir-ty/src/autoderef.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,11 +207,10 @@ where
} else {
(AutoderefKind::Builtin, ty)
}
} else if let Some(ty) = self.overloaded_deref_ty(self.state.cur_ty) {
} else {
let ty = self.overloaded_deref_ty(self.state.cur_ty)?;
// The overloaded deref check already normalizes the pointee type.
(AutoderefKind::Overloaded, ty)
} else {
return None;
};

self.state.steps.push(self.state.cur_ty, kind);
Expand Down
5 changes: 1 addition & 4 deletions crates/hir-ty/src/drop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,7 @@ pub fn destructor(db: &dyn HirDatabase, adt: AdtId) -> Option<ImplId> {
let interner = DbInterner::new_with(db, module.krate(db));
let drop_trait = interner.lang_items().Drop?;
let impls = match module.block(db) {
Some(block) => match TraitImpls::for_block(db, block) {
Some(it) => &**it,
None => return None,
},
Some(block) => TraitImpls::for_block(db, block)?,
None => TraitImpls::for_crate(db, module.krate(db)),
};
impls.for_trait_and_self_ty(drop_trait, &SimplifiedType::Adt(adt.into())).0.first().copied()
Expand Down
10 changes: 5 additions & 5 deletions crates/hir-ty/src/method_resolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ impl TraitImpls {
Arc::new(result)
}

#[salsa::tracked(returns(ref))]
#[salsa::tracked(returns(as_deref))]
pub fn for_block(db: &dyn HirDatabase, block: BlockId) -> Option<Box<Self>> {
let _p = tracing::info_span!("inherent_impls_in_block_query").entered();

Expand All @@ -687,7 +687,7 @@ impl TraitImpls {
if result.map.is_empty() { None } else { Some(Box::new(result)) }
}

#[salsa::tracked(returns(ref))]
#[salsa::tracked(returns(deref))]
pub fn for_crate_and_deps(db: &dyn HirDatabase, krate: Crate) -> Box<[Arc<Self>]> {
krate.transitive_deps(db).iter().map(|&dep| Self::for_crate(db, dep).clone()).collect()
}
Expand Down Expand Up @@ -830,7 +830,7 @@ impl TraitImpls {
for_each: &mut dyn FnMut(&TraitImpls),
) {
let blocks = std::iter::successors(block, |block| block.loc(db).module.block(db));
blocks.filter_map(|block| Self::for_block(db, block).as_deref()).for_each(&mut *for_each);
blocks.filter_map(|block| Self::for_block(db, block)).for_each(&mut *for_each);
Self::for_crate_and_deps(db, krate).iter().map(|it| &**it).for_each(for_each);
}

Expand Down Expand Up @@ -858,11 +858,11 @@ impl TraitImpls {
.take_while(move |&block| {
other_block.is_none_or(|other_block| other_block != block)
})
.filter_map(move |block| TraitImpls::for_block(db, block).as_deref())
.filter_map(move |block| TraitImpls::for_block(db, block))
};
if trait_block == type_block {
blocks_iter(trait_block)
.filter_map(|block| TraitImpls::for_block(db, block).as_deref())
.filter_map(|block| TraitImpls::for_block(db, block))
.for_each(for_each);
} else {
for_each_block(trait_block, type_block).for_each(&mut *for_each);
Expand Down
7 changes: 5 additions & 2 deletions crates/hir-ty/src/mir/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1404,11 +1404,14 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
expr_id: ExprId,
) -> Result<'db, ()> {
if let Expr::Field { expr, name } = &self.store[expr_id] {
if let TyKind::Tuple(..) = self.expr_ty_after_adjustments(*expr).kind() {
if let TyKind::Tuple(tys) = self.expr_ty_after_adjustments(*expr).kind() {
let index =
name.as_tuple_index().ok_or(MirLowerError::TypeError("named field on tuple"))?
as u32;
*place = place.project(ProjectionElem::Field(FieldIndex(index)))
if tys.get(index as usize).is_none() {
return Err(MirLowerError::TypeError("tuple field index out of range"));
}
*place = place.project(ProjectionElem::Field(FieldIndex(index)));
} else {
let field = self
.infer
Expand Down
3 changes: 2 additions & 1 deletion crates/hir-ty/src/mir/lower/pattern_matching.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ impl<'db> MirLowerCtx<'_, 'db> {
}
Pat::Wild => (current, current_else),
Pat::Tuple { args, ellipsis } => {
let subst = match self.infer.pat_ty(pattern).kind() {
let place_ty = cond_place.ty(&self.result, &self.infcx, self.env).ty;
let subst = match place_ty.kind() {
TyKind::Tuple(s) => s,
_ => {
return Err(MirLowerError::TypeError(
Expand Down
26 changes: 26 additions & 0 deletions crates/hir-ty/src/mir/lower/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,29 @@ pub struct AssocTy {
"#,
);
}

#[test]
fn borrowck_tuple_field_projection_recovery_does_not_panic() {
check_borrowck(
r#"
//- minicore: sized
fn tuple_field() {
let t = (1,);
let x = t.1;
}
"#,
);
}

#[test]
fn borrowck_alias_projection_recovery_does_not_panic() {
check_borrowck(
r#"
//- minicore: sized
trait Tr { type A; }
fn alias<T: Tr>(x: T::A) {
let (a, b) = x;
}
"#,
);
}
2 changes: 1 addition & 1 deletion crates/hir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4715,7 +4715,7 @@ impl Impl {
&mut |impls| extend_with_impls(Either::Left(impls.for_self_ty(&simplified_ty))),
);
iter::successors(module.block(db), |block| block.loc(db).module.block(db))
.filter_map(|block| TraitImpls::for_block(db, block).as_deref())
.filter_map(|block| TraitImpls::for_block(db, block))
.for_each(|impls| impls.for_self_ty(&simplified_ty, &mut extend_with_impls));
for &krate in &*all_crates(db) {
TraitImpls::for_crate(db, krate)
Expand Down
5 changes: 2 additions & 3 deletions crates/hir/src/source_analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1427,11 +1427,10 @@ impl<'db> SourceAnalyzer<'db> {
let ty = if let Some(expr) = ast::Expr::cast(parent.clone()) {
let expr_id = self.expr_id(expr)?;
self.infer()?.type_of_expr_or_pat(expr_id)?
} else if let Some(pat) = ast::Pat::cast(parent) {
} else {
let pat = ast::Pat::cast(parent)?;
let pat_id = self.pat_id(&pat)?;
self.infer()?.expr_or_pat_ty(pat_id)
} else {
return None;
};
let (subst, expected_resolution) = match ty.kind() {
TyKind::Adt(adt_def, subst) => {
Expand Down
2 changes: 1 addition & 1 deletion crates/ide-assists/src/handlers/add_missing_match_arms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ fn resolve_tuple_of_enum_def(
})
})
.collect::<Option<Vec<ExtendedEnum>>>()
.and_then(|list| if list.is_empty() { None } else { Some(list) })
.filter(|list| !list.is_empty())
}

fn resolve_array_of_enum_def(
Expand Down
5 changes: 2 additions & 3 deletions crates/ide-assists/src/handlers/change_visibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,13 @@ fn add_vis(acc: &mut Assists, ctx: &AssistContext<'_, '_>) -> Option<()> {
}
check_is_not_variant(&field)?;
(vis_offset(field.syntax()), field_name.syntax().text_range())
} else if let Some(field) = ctx.find_node_at_offset::<ast::TupleField>() {
} else {
let field = ctx.find_node_at_offset::<ast::TupleField>()?;
if field.visibility().is_some() {
return None;
}
check_is_not_variant(&field)?;
(vis_offset(field.syntax()), field.syntax().text_range())
} else {
return None;
};

acc.add(
Expand Down
10 changes: 4 additions & 6 deletions crates/ide-assists/src/handlers/extract_variable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,11 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_, '_>) -
let node = if ctx.has_empty_selection() {
if let Some(t) = ctx.token_at_offset().find(|it| it.kind() == T![;]) {
t.parent().and_then(ast::ExprStmt::cast)?.syntax().clone()
} else if let Some(expr) = ancestors_at_offset(ctx.source_file().syntax(), ctx.offset())
.next()
.and_then(ast::Expr::cast)
{
expr.syntax().ancestors().find_map(valid_target_expr(ctx))?.syntax().clone()
} else {
return None;
let expr = ancestors_at_offset(ctx.source_file().syntax(), ctx.offset())
.next()
.and_then(ast::Expr::cast)?;
expr.syntax().ancestors().find_map(valid_target_expr(ctx))?.syntax().clone()
}
} else {
match ctx.covering_element() {
Expand Down
2 changes: 1 addition & 1 deletion crates/ide-assists/src/handlers/generate_enum_is_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ impl Method {
};

let variant_name = variant.name()?;
let fn_name = format!("is_{}", &to_lower_snake_case(&variant_name.text()));
let fn_name = format!("is_{}", to_lower_snake_case(&variant_name.text()));
Some(Method { pattern_suffix, fn_name, variant_name })
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ impl Method {
fn new(variant: &ast::Variant, fn_name_prefix: &str) -> Option<Self> {
use itertools::Itertools as _;
let variant_name = variant.name()?;
let fn_name = format!("{fn_name_prefix}_{}", &to_lower_snake_case(&variant_name.text()));
let fn_name = format!("{fn_name_prefix}_{}", to_lower_snake_case(&variant_name.text()));

match variant.kind() {
ast::StructKind::Record(record) => {
Expand Down
33 changes: 23 additions & 10 deletions crates/ide-assists/src/handlers/generate_function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ fn get_fn_target(
let mut file = ctx.vfs_file_id();
let target = match target_module {
Some(target_module) => {
let (in_file, target) = next_space_for_fn_in_module(ctx.db(), target_module);
let (in_file, target) = next_space_for_fn_in_module(ctx.db(), target_module)?;
file = in_file;
target
}
Expand Down Expand Up @@ -1310,22 +1310,21 @@ fn next_space_for_fn_after_call_site(expr: ast::CallableExpr) -> Option<Generate
fn next_space_for_fn_in_module(
db: &dyn hir::db::HirDatabase,
target_module: hir::Module,
) -> (FileId, GeneratedFunctionTarget) {
) -> Option<(FileId, GeneratedFunctionTarget)> {
let module_source = target_module.definition_source(db);
let file = module_source.file_id.original_file(db);
let assist_item = match &module_source.value {
hir::ModuleSource::SourceFile(it) => match it.items().last() {
Some(last_item) => GeneratedFunctionTarget::AfterItem(last_item.syntax().clone()),
None => GeneratedFunctionTarget::AfterItem(it.syntax().clone()),
},
hir::ModuleSource::Module(it) => match it.item_list().and_then(|it| it.items().last()) {
Some(last_item) => GeneratedFunctionTarget::AfterItem(last_item.syntax().clone()),
None => {
let item_list =
it.item_list().expect("module definition source should have an item list");
GeneratedFunctionTarget::InEmptyItemList(item_list.syntax().clone())
hir::ModuleSource::Module(it) => {
let item_list = it.item_list()?;
match item_list.items().last() {
Some(last_item) => GeneratedFunctionTarget::AfterItem(last_item.syntax().clone()),
None => GeneratedFunctionTarget::InEmptyItemList(item_list.syntax().clone()),
}
},
}
hir::ModuleSource::BlockExpr(it) => {
if let Some(last_item) =
it.statements().take_while(|stmt| matches!(stmt, ast::Stmt::Item(_))).last()
Expand All @@ -1337,7 +1336,7 @@ fn next_space_for_fn_in_module(
}
};

(file.file_id(db), assist_item)
Some((file.file_id(db), assist_item))
}

#[derive(Clone, Copy)]
Expand Down Expand Up @@ -2459,6 +2458,20 @@ pub(crate) fn bar() {
)
}

#[test]
fn add_function_not_applicable_in_unresolved_module() {
check_assist_not_applicable(
generate_function,
r"
mod foo;

fn main() {
foo::bar$0();
}
",
)
}

#[test]
fn add_function_with_return_type() {
check_assist(
Expand Down
11 changes: 11 additions & 0 deletions crates/ide-assists/src/handlers/merge_imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,17 @@ mod top {
}

use top::{a::A, b::{B as D, B as C}};
",
);
}

#[test]
fn test_merge_with_trailing_path_separator() {
check_assist_not_applicable(
merge_imports,
r"
use foo::bar;
use foo::$0;
",
);
}
Expand Down
5 changes: 2 additions & 3 deletions crates/ide-assists/src/handlers/remove_underscore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ pub(crate) fn remove_underscore(acc: &mut Assists, ctx: &AssistContext<'_, '_>)
_ => return None,
};
(text.to_owned(), name_ref.syntax().text_range(), def)
} else if let Some(name_ref) = ctx.find_node_at_offset::<ast::NameRef>() {
} else {
let name_ref = ctx.find_node_at_offset::<ast::NameRef>()?;
let text = name_ref.text();
if !text.starts_with('_') {
return None;
Expand All @@ -48,8 +49,6 @@ pub(crate) fn remove_underscore(acc: &mut Assists, ctx: &AssistContext<'_, '_>)
_ => return None,
};
(text.to_owned(), name_ref.syntax().text_range(), def)
} else {
return None;
};

if !def.usages(&ctx.sema).at_least_one() {
Expand Down
5 changes: 1 addition & 4 deletions crates/ide-completion/src/snippet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,7 @@ fn import_edits(
};
let mut res = Vec::with_capacity(requires.len());
for import in requires {
match resolve(import) {
Some(first) => res.extend(first),
None => return None,
}
res.extend(resolve(import)?)
}
Some(res)
}
Expand Down
5 changes: 4 additions & 1 deletion crates/ide-db/src/imports/merge_imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,10 @@ fn split_prefix(
make.use_tree(self_path, None, use_tree.rename(), false)
}
} else {
let suffix_segments = path.segments().skip(prefix.segments().count());
let suffix_segments: Vec<_> = path.segments().skip(prefix.segments().count()).collect();
if suffix_segments.is_empty() {
return None;
}
let suffix_path = make.path_from_segments(suffix_segments, false);
make.use_tree(
suffix_path,
Expand Down
Loading