Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--Cargo.toml2
-rw-r--r--bench_data/glorious_old_parser18
-rw-r--r--crates/edition/src/lib.rs2
-rw-r--r--crates/hir/src/term_search/tactics.rs19
-rw-r--r--crates/ide-assists/src/handlers/auto_import.rs1
-rw-r--r--crates/ide-db/src/imports/insert_use.rs9
-rw-r--r--crates/ide-db/src/syntax_helpers/suggest_name.rs50
-rw-r--r--crates/ide/src/typing.rs18
-rw-r--r--crates/project-model/src/sysroot.rs6
-rw-r--r--crates/project-model/src/workspace.rs2
10 files changed, 70 insertions, 57 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 2288933a96..9f31e1903a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -192,8 +192,6 @@ unused_lifetimes = "warn"
unreachable_pub = "warn"
[workspace.lints.clippy]
-# FIXME Remove the tidy test once the lint table is stable
-
## lint groups
complexity = { level = "warn", priority = -1 }
correctness = { level = "deny", priority = -1 }
diff --git a/bench_data/glorious_old_parser b/bench_data/glorious_old_parser
index f593f2b295..8136daa832 100644
--- a/bench_data/glorious_old_parser
+++ b/bench_data/glorious_old_parser
@@ -724,7 +724,7 @@ impl<'a> Parser<'a> {
// {foo(bar {}}
// - ^
// | |
- // | help: `)` may belong here (FIXME: #58270)
+ // | help: `)` may belong here
// |
// unclosed delimiter
if let Some(sp) = unmatched.unclosed_span {
@@ -3217,7 +3217,6 @@ impl<'a> Parser<'a> {
}
_ => {
- // FIXME Could factor this out into non_fatal_unexpected or something.
let actual = self.this_token_to_string();
self.span_err(self.span, &format!("unexpected token: `{}`", actual));
}
@@ -5250,7 +5249,6 @@ impl<'a> Parser<'a> {
}
}
} else {
- // FIXME: Bad copy of attrs
let old_directory_ownership =
mem::replace(&mut self.directory.ownership, DirectoryOwnership::UnownedViaBlock);
let item = self.parse_item_(attrs.clone(), false, true)?;
@@ -5953,23 +5951,14 @@ impl<'a> Parser<'a> {
});
assoc_ty_bindings.push(span);
} else if self.check_const_arg() {
- // FIXME(const_generics): to distinguish between idents for types and consts,
- // we should introduce a GenericArg::Ident in the AST and distinguish when
- // lowering to the HIR. For now, idents for const args are not permitted.
-
// Parse const argument.
let expr = if let token::OpenDelim(token::Brace) = self.token {
self.parse_block_expr(None, self.span, BlockCheckMode::Default, ThinVec::new())?
} else if self.token.is_ident() {
- // FIXME(const_generics): to distinguish between idents for types and consts,
- // we should introduce a GenericArg::Ident in the AST and distinguish when
- // lowering to the HIR. For now, idents for const args are not permitted.
return Err(
self.fatal("identifiers may currently not be used for const generics")
);
} else {
- // FIXME(const_generics): this currently conflicts with emplacement syntax
- // with negative integer literals.
self.parse_literal_maybe_minus()?
};
let value = AnonConst {
@@ -5991,9 +5980,6 @@ impl<'a> Parser<'a> {
}
}
- // FIXME: we would like to report this in ast_validation instead, but we currently do not
- // preserve ordering of generic parameters with respect to associated type binding, so we
- // lose that information after parsing.
if misplaced_assoc_ty_bindings.len() > 0 {
let mut err = self.struct_span_err(
args_lo.to(self.prev_span),
@@ -6079,8 +6065,6 @@ impl<'a> Parser<'a> {
bounds,
}
));
- // FIXME: Decide what should be used here, `=` or `==`.
- // FIXME: We are just dropping the binders in lifetime_defs on the floor here.
} else if self.eat(&token::Eq) || self.eat(&token::EqEq) {
let rhs_ty = self.parse_ty()?;
where_clause.predicates.push(ast::WherePredicate::EqPredicate(
diff --git a/crates/edition/src/lib.rs b/crates/edition/src/lib.rs
index f1a1fe5964..eb4cec39dc 100644
--- a/crates/edition/src/lib.rs
+++ b/crates/edition/src/lib.rs
@@ -16,8 +16,6 @@ impl Edition {
pub const DEFAULT: Edition = Edition::Edition2015;
pub const LATEST: Edition = Edition::Edition2024;
pub const CURRENT: Edition = Edition::Edition2024;
- /// The current latest stable edition, note this is usually not the right choice in code.
- pub const CURRENT_FIXME: Edition = Edition::Edition2024;
pub fn from_u32(u32: u32) -> Edition {
match u32 {
diff --git a/crates/hir/src/term_search/tactics.rs b/crates/hir/src/term_search/tactics.rs
index 05a89e7652..8622aa1378 100644
--- a/crates/hir/src/term_search/tactics.rs
+++ b/crates/hir/src/term_search/tactics.rs
@@ -18,7 +18,6 @@ use hir_ty::{
use itertools::Itertools;
use rustc_hash::FxHashSet;
use rustc_type_ir::inherent::Ty as _;
-use span::Edition;
use crate::{
Adt, AssocItem, GenericDef, GenericParam, HasAttrs, HasVisibility, Impl, ModuleDef, ScopeDef,
@@ -367,7 +366,11 @@ pub(super) fn free_function<'a, 'lt, 'db, DB: HirDatabase>(
let ret_ty = it.ret_type_with_args(db, generics.iter().cloned());
// Filter out private and unsafe functions
if !it.is_visible_from(db, module)
- || it.is_unsafe_to_call(db, None, Edition::CURRENT_FIXME)
+ || it.is_unsafe_to_call(
+ db,
+ None,
+ crate::Crate::from(ctx.scope.resolver().krate()).edition(db),
+ )
|| it.is_unstable(db)
|| ctx.config.enable_borrowcheck && ret_ty.contains_reference(db)
|| ret_ty.is_raw_ptr()
@@ -473,7 +476,11 @@ pub(super) fn impl_method<'a, 'lt, 'db, DB: HirDatabase>(
// Filter out private and unsafe functions
if !it.is_visible_from(db, module)
- || it.is_unsafe_to_call(db, None, Edition::CURRENT_FIXME)
+ || it.is_unsafe_to_call(
+ db,
+ None,
+ crate::Crate::from(ctx.scope.resolver().krate()).edition(db),
+ )
|| it.is_unstable(db)
{
return None;
@@ -667,7 +674,11 @@ pub(super) fn impl_static_method<'a, 'lt, 'db, DB: HirDatabase>(
// Filter out private and unsafe functions
if !it.is_visible_from(db, module)
- || it.is_unsafe_to_call(db, None, Edition::CURRENT_FIXME)
+ || it.is_unsafe_to_call(
+ db,
+ None,
+ crate::Crate::from(ctx.scope.resolver().krate()).edition(db),
+ )
|| it.is_unstable(db)
{
return None;
diff --git a/crates/ide-assists/src/handlers/auto_import.rs b/crates/ide-assists/src/handlers/auto_import.rs
index cc2bf81749..2694910aa6 100644
--- a/crates/ide-assists/src/handlers/auto_import.rs
+++ b/crates/ide-assists/src/handlers/auto_import.rs
@@ -155,6 +155,7 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<
&scope,
mod_path_to_ast(&import_path, edition),
&ctx.config.insert_use,
+ edition,
);
},
);
diff --git a/crates/ide-db/src/imports/insert_use.rs b/crates/ide-db/src/imports/insert_use.rs
index 4444ef5d81..db1d599d55 100644
--- a/crates/ide-db/src/imports/insert_use.rs
+++ b/crates/ide-db/src/imports/insert_use.rs
@@ -146,9 +146,14 @@ pub fn insert_use(scope: &ImportScope, path: ast::Path, cfg: &InsertUseConfig) {
insert_use_with_alias_option(scope, path, cfg, None);
}
-pub fn insert_use_as_alias(scope: &ImportScope, path: ast::Path, cfg: &InsertUseConfig) {
+pub fn insert_use_as_alias(
+ scope: &ImportScope,
+ path: ast::Path,
+ cfg: &InsertUseConfig,
+ edition: span::Edition,
+) {
let text: &str = "use foo as _";
- let parse = syntax::SourceFile::parse(text, span::Edition::CURRENT_FIXME);
+ let parse = syntax::SourceFile::parse(text, edition);
let node = parse
.tree()
.syntax()
diff --git a/crates/ide-db/src/syntax_helpers/suggest_name.rs b/crates/ide-db/src/syntax_helpers/suggest_name.rs
index b8b9a7a768..5d1e876ea2 100644
--- a/crates/ide-db/src/syntax_helpers/suggest_name.rs
+++ b/crates/ide-db/src/syntax_helpers/suggest_name.rs
@@ -206,17 +206,18 @@ impl NameGenerator {
expr: &ast::Expr,
sema: &Semantics<'_, RootDatabase>,
) -> Option<SmolStr> {
+ let edition = sema.scope(expr.syntax())?.krate().edition(sema.db);
// `from_param` does not benefit from stripping it need the largest
// context possible so we check firstmost
- if let Some(name) = from_param(expr, sema) {
+ if let Some(name) = from_param(expr, sema, edition) {
return Some(self.suggest_name(&name));
}
let mut next_expr = Some(expr.clone());
while let Some(expr) = next_expr {
- let name = from_call(&expr)
- .or_else(|| from_type(&expr, sema))
- .or_else(|| from_field_name(&expr));
+ let name = from_call(&expr, edition)
+ .or_else(|| from_type(&expr, sema, edition))
+ .or_else(|| from_field_name(&expr, edition));
if let Some(name) = name {
return Some(self.suggest_name(&name));
}
@@ -270,7 +271,7 @@ impl NameGenerator {
}
}
-fn normalize(name: &str) -> Option<SmolStr> {
+fn normalize(name: &str, edition: syntax::Edition) -> Option<SmolStr> {
let name = to_lower_snake_case(name).to_smolstr();
if USELESS_NAMES.contains(&name.as_str()) {
@@ -281,16 +282,16 @@ fn normalize(name: &str) -> Option<SmolStr> {
return None;
}
- if !is_valid_name(&name) {
+ if !is_valid_name(&name, edition) {
return None;
}
Some(name)
}
-fn is_valid_name(name: &str) -> bool {
+fn is_valid_name(name: &str, edition: syntax::Edition) -> bool {
matches!(
- super::LexedStr::single_token(syntax::Edition::CURRENT_FIXME, name),
+ super::LexedStr::single_token(edition, name),
Some((syntax::SyntaxKind::IDENT, _error))
)
}
@@ -304,11 +305,11 @@ fn is_useless_method(method: &ast::MethodCallExpr) -> bool {
}
}
-fn from_call(expr: &ast::Expr) -> Option<SmolStr> {
- from_func_call(expr).or_else(|| from_method_call(expr))
+fn from_call(expr: &ast::Expr, edition: syntax::Edition) -> Option<SmolStr> {
+ from_func_call(expr, edition).or_else(|| from_method_call(expr, edition))
}
-fn from_func_call(expr: &ast::Expr) -> Option<SmolStr> {
+fn from_func_call(expr: &ast::Expr, edition: syntax::Edition) -> Option<SmolStr> {
let call = match expr {
ast::Expr::CallExpr(call) => call,
_ => return None,
@@ -318,10 +319,10 @@ fn from_func_call(expr: &ast::Expr) -> Option<SmolStr> {
_ => return None,
};
let ident = func.path()?.segment()?.name_ref()?.ident_token()?;
- normalize(ident.text())
+ normalize(ident.text(), edition)
}
-fn from_method_call(expr: &ast::Expr) -> Option<SmolStr> {
+fn from_method_call(expr: &ast::Expr, edition: syntax::Edition) -> Option<SmolStr> {
let method = match expr {
ast::Expr::MethodCallExpr(call) => call,
_ => return None,
@@ -340,10 +341,14 @@ fn from_method_call(expr: &ast::Expr) -> Option<SmolStr> {
}
}
- normalize(name)
+ normalize(name, edition)
}
-fn from_param(expr: &ast::Expr, sema: &Semantics<'_, RootDatabase>) -> Option<SmolStr> {
+fn from_param(
+ expr: &ast::Expr,
+ sema: &Semantics<'_, RootDatabase>,
+ edition: Edition,
+) -> Option<SmolStr> {
let arg_list = expr.syntax().parent().and_then(ast::ArgList::cast)?;
let args_parent = arg_list.syntax().parent()?;
let func = match_ast! {
@@ -362,7 +367,7 @@ fn from_param(expr: &ast::Expr, sema: &Semantics<'_, RootDatabase>) -> Option<Sm
let param = func.params().into_iter().nth(idx)?;
let pat = sema.source(param)?.value.right()?.pat()?;
let name = var_name_from_pat(&pat)?;
- normalize(&name.to_smolstr())
+ normalize(&name.to_smolstr(), edition)
}
fn var_name_from_pat(pat: &ast::Pat) -> Option<ast::Name> {
@@ -374,10 +379,13 @@ fn var_name_from_pat(pat: &ast::Pat) -> Option<ast::Name> {
}
}
-fn from_type(expr: &ast::Expr, sema: &Semantics<'_, RootDatabase>) -> Option<SmolStr> {
+fn from_type(
+ expr: &ast::Expr,
+ sema: &Semantics<'_, RootDatabase>,
+ edition: Edition,
+) -> Option<SmolStr> {
let ty = sema.type_of_expr(expr)?.adjusted();
let ty = ty.remove_ref().unwrap_or(ty);
- let edition = sema.scope(expr.syntax())?.krate().edition(sema.db);
name_of_type(&ty, sema.db, edition)
}
@@ -417,7 +425,7 @@ fn name_of_type<'db>(
} else {
return None;
};
- normalize(&name)
+ normalize(&name, edition)
}
fn sequence_name<'db>(
@@ -450,13 +458,13 @@ fn trait_name(trait_: &hir::Trait, db: &RootDatabase, edition: Edition) -> Optio
Some(name)
}
-fn from_field_name(expr: &ast::Expr) -> Option<SmolStr> {
+fn from_field_name(expr: &ast::Expr, edition: syntax::Edition) -> Option<SmolStr> {
let field = match expr {
ast::Expr::FieldExpr(field) => field,
_ => return None,
};
let ident = field.name_ref()?.ident_token()?;
- normalize(ident.text())
+ normalize(ident.text(), edition)
}
#[cfg(test)]
diff --git a/crates/ide/src/typing.rs b/crates/ide/src/typing.rs
index 0381865fed..f8b0dbfe62 100644
--- a/crates/ide/src/typing.rs
+++ b/crates/ide/src/typing.rs
@@ -17,7 +17,10 @@ mod on_enter;
use either::Either;
use hir::EditionedFileId;
-use ide_db::{FilePosition, RootDatabase, base_db::RootQueryDb};
+use ide_db::{
+ FilePosition, RootDatabase,
+ base_db::{RootQueryDb, SourceDatabase},
+};
use span::Edition;
use std::iter;
@@ -70,11 +73,12 @@ pub(crate) fn on_char_typed(
if !TRIGGER_CHARS.contains(&char_typed) {
return None;
}
- // FIXME: We need to figure out the edition of the file here, but that means hitting the
- // database for more than just parsing the file which is bad.
+ let edition = db
+ .source_root_crates(db.file_source_root(position.file_id).source_root_id(db))
+ .first()
+ .map_or(Edition::CURRENT, |crates| crates.data(db).edition);
// FIXME: We are hitting the database here, if we are unlucky this call might block momentarily
- // causing the editor to feel sluggish!
- let edition = Edition::CURRENT_FIXME;
+ // causing the editor to feel sluggish! We need to make this bail if it would block too long?
let editioned_file_id_wrapper = EditionedFileId::from_span_guess_origin(
db,
span::EditionedFileId::new(position.file_id, edition),
@@ -457,8 +461,8 @@ mod tests {
let (offset, mut before) = extract_offset(before);
let edit = TextEdit::insert(offset, char_typed.to_string());
edit.apply(&mut before);
- let parse = SourceFile::parse(&before, span::Edition::CURRENT_FIXME);
- on_char_typed_(&parse, offset, char_typed, span::Edition::CURRENT_FIXME).map(|it| {
+ let parse = SourceFile::parse(&before, span::Edition::CURRENT);
+ on_char_typed_(&parse, offset, char_typed, span::Edition::CURRENT).map(|it| {
it.apply(&mut before);
before.to_string()
})
diff --git a/crates/project-model/src/sysroot.rs b/crates/project-model/src/sysroot.rs
index f244c9736c..546a1e05a0 100644
--- a/crates/project-model/src/sysroot.rs
+++ b/crates/project-model/src/sysroot.rs
@@ -275,7 +275,10 @@ impl Sysroot {
}
tracing::debug!("Stitching sysroot library: {src_root}");
- let mut stitched = stitched::Stitched { crates: Default::default() };
+ let mut stitched = stitched::Stitched {
+ crates: Default::default(),
+ edition: span::Edition::Edition2024,
+ };
for path in stitched::SYSROOT_CRATES.trim().lines() {
let name = path.split('/').next_back().unwrap();
@@ -511,6 +514,7 @@ pub(crate) mod stitched {
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Stitched {
pub(super) crates: Arena<RustLibSrcCrateData>,
+ pub(crate) edition: span::Edition,
}
impl ops::Index<RustLibSrcCrate> for Stitched {
diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs
index 8f15f7e150..581b5fa514 100644
--- a/crates/project-model/src/workspace.rs
+++ b/crates/project-model/src/workspace.rs
@@ -1831,7 +1831,7 @@ fn sysroot_to_crate_graph(
let display_name = CrateDisplayName::from_canonical_name(&stitched[krate].name);
let crate_id = crate_graph.add_crate_root(
file_id,
- Edition::CURRENT_FIXME,
+ stitched.edition,
Some(display_name),
None,
cfg_options.clone(),