Repository: astral-sh/ruff
File: crates/ty_ide/src/completion.rs (Rust)

Code before:
                    scoped,
                    |module_name: &ModuleName, symbol: &str| {
                        ImportRequest::import_from(module_name.as_str(), symbol)
                    },
                    &mut completions,
                );
            }
        }

        if let Some(sig_help) = signature_help(db, file, offset) {
            let param_completions = sig_help
                .signatures
                .iter()
                .flat_map(|sig| &sig.parameters)
                .filter(|p| !p.is_positional_only)
                .map(|p| {
                    let name = Name::new(&p.name);
                    let documentation = p
                        .documentation
                        .as_ref()
                        .map(|d| Docstring::new(d.to_owned()));
                    let insert = Some(format!("{name}=").into_boxed_str());
                    Completion {
                        name,
                        insert,
                        ty: None,
                        kind: Some(CompletionKind::Variable),
                        module_name: None,
                        import: None,
                        builtin: false,
                        is_type_check_only: false,
                        is_definitively_raisable: false,
                        documentation,
                    }
                });
            completions.extend(param_completions);
        }
    }

    if is_raising_exception(tokens) {
        completions.tag_raisable();

        // As a special case, and because it's a common footgun, we
        // specifically disallow `NotImplemented` in this context.
        // `NotImplementedError` should be used instead. So if we can
        // definitively detect `NotImplemented`, then we can safely
        // omit it from suggestions.
        completions.retain(|item| {
            let Some(ty) = item.ty else { return true };
            !ty.is_notimplemented(db)
        });

Review comment (suggestion):
This PR does not add any type information here but if this approach seems reasonable then it would make a lot of sense to also pass down the type information to be able to give better context in the autocomplete suggestions.

Code after:
            add_keyword_completions(db, &mut completions);
        }
        if settings.auto_import {
            if let Some(scoped) = scoped {
                add_unimported_completions(
                    db,
                    file,
                    &parsed,
                    scoped,
                    |module_name: &ModuleName, symbol: &str| {
                        ImportRequest::import_from(module_name.as_str(), symbol)
                    },
                    &mut completions,
                );
            }
        }

        if let Some(arg_completions) = detect_function_arg_completions(db, file, &parsed, offset) {
            completions.extend(arg_completions);
        }
    }

    if is_raising_exception(tokens) {
        completions.tag_raisable();

        // As a special case, and because it's a common footgun, we
        // specifically disallow `NotImplemented` in this context.
        // `NotImplementedError` should be used instead. So if we can
        // definitively detect `NotImplemented`, then we can safely
        // omit it from suggestions.
        completions.retain(|item| {
            let Some(ty) = item.ty else { return true };
            !ty.is_notimplemented(db)
        });
    }
    completions.into_completions()
}

/// Detect and construct completions for unset function arguments.
///
/// Suggestions are only provided if the cursor is currently inside a
/// function call and the function arguments have not 1) already been
/// set and 2) been defined as positional-only.
fn detect_function_arg_completions<'db>(
    db: &'db dyn Db,
    file: File,
    parsed: &ParsedModuleRef,
    offset: TextSize,
) -> Option<Vec<Completion<'db>>> {
    let sig_help = signature_help(db, file, offset)?;
    let set_function_args = detect_set_function_args(parsed, offset);