@@ -11,7 +11,6 @@ use anyhow::bail;
11
11
use harp:: r_symbol;
12
12
use harp:: utils:: is_symbol_valid;
13
13
use harp:: utils:: r_env_binding_is_active;
14
- use harp:: utils:: r_envir_name;
15
14
use harp:: utils:: r_promise_force_with_rollback;
16
15
use harp:: utils:: r_promise_is_forced;
17
16
use harp:: utils:: r_promise_is_lazy_load_binding;
@@ -374,35 +373,44 @@ pub(super) unsafe fn completion_item_from_namespace(
374
373
package : & str ,
375
374
parameter_hints : & ParameterHints ,
376
375
) -> anyhow:: Result < CompletionItem > {
376
+ // We perform two passes to locate the object. It is normal for the first pass to
377
+ // error when the `namespace` doesn't have a binding for `name` because the associated
378
+ // object has been imported and re-exported. For example, the way dplyr imports and
379
+ // re-exports `rlang::.data` or `tidyselect::all_of()`. In such a case, we'll succeed
380
+ // in the second pass, when we try again in the imports environment. If both fail,
381
+ // something is seriously wrong.
382
+
377
383
// First, look in the namespace itself.
378
- if let Some ( item ) = completion_item_from_symbol (
384
+ let error_namespace = match completion_item_from_symbol (
379
385
name,
380
386
namespace,
381
387
Some ( package) ,
382
388
PromiseStrategy :: Force ,
383
389
parameter_hints,
384
390
) {
385
- return item;
386
- }
391
+ Ok ( item) => return Ok ( item) ,
392
+ Err ( error) => error,
393
+ } ;
387
394
388
395
// Otherwise, try the imports environment.
389
396
let imports = ENCLOS ( namespace) ;
390
- if let Some ( item ) = completion_item_from_symbol (
397
+ let error_imports = match completion_item_from_symbol (
391
398
name,
392
399
imports,
393
400
Some ( package) ,
394
401
PromiseStrategy :: Force ,
395
402
parameter_hints,
396
403
) {
397
- return item;
398
- }
404
+ Ok ( item) => return Ok ( item) ,
405
+ Err ( error) => error,
406
+ } ;
399
407
400
- // If still not found, something is wrong .
401
- bail ! (
402
- "Object '{ }' not defined in namespace {:?}" ,
403
- name ,
404
- r_envir_name ( namespace ) ?
405
- )
408
+ // This is really unexpected .
409
+ Err ( anyhow :: anyhow !(
410
+ "Failed to form completion item for '{name }' in namespace '{package}':
411
+ Namespace environment error: {error_namespace}
412
+ Imports environment error: {error_imports}"
413
+ ) )
406
414
}
407
415
408
416
pub ( super ) unsafe fn completion_item_from_lazydata (
@@ -416,14 +424,14 @@ pub(super) unsafe fn completion_item_from_lazydata(
416
424
let promise_strategy = PromiseStrategy :: Simple ;
417
425
418
426
// Lazydata objects are never functions, so this doesn't really matter
419
- let parameter_hints = ParameterHints :: Enabled ;
427
+ let parameter_hints = ParameterHints :: Disabled ;
420
428
421
429
match completion_item_from_symbol ( name, env, Some ( package) , promise_strategy, & parameter_hints)
422
430
{
423
- Some ( item) => item,
424
- None => {
431
+ Ok ( item) => Ok ( item) ,
432
+ Err ( err ) => {
425
433
// Should be impossible, but we'll be extra safe
426
- bail ! ( "Object '{name}' not defined in lazydata environment for namespace {package}" )
434
+ Err ( anyhow :: anyhow !( "Object '{name}' not defined in lazydata environment for namespace {package}: {err}" ) )
427
435
} ,
428
436
}
429
437
}
@@ -434,7 +442,7 @@ pub(super) unsafe fn completion_item_from_symbol(
434
442
package : Option < & str > ,
435
443
promise_strategy : PromiseStrategy ,
436
444
parameter_hints : & ParameterHints ,
437
- ) -> Option < anyhow:: Result < CompletionItem > > {
445
+ ) -> anyhow:: Result < CompletionItem > {
438
446
let symbol = r_symbol ! ( name) ;
439
447
440
448
match r_env_binding_is_active ( envir, symbol) {
@@ -445,29 +453,33 @@ pub(super) unsafe fn completion_item_from_symbol(
445
453
Ok ( true ) => {
446
454
// We can't even extract out the object for active bindings so they
447
455
// are handled extremely specially.
448
- return Some ( completion_item_from_active_binding ( name) ) ;
456
+ return completion_item_from_active_binding ( name) ;
449
457
} ,
450
458
Err ( err) => {
451
- log:: error!( "Can't determine if binding is active: {err:?}" ) ;
452
- return None ;
459
+ // The only error we anticipate is the case where `envir` doesn't
460
+ // have a binding for `name`.
461
+ return Err ( anyhow:: anyhow!(
462
+ "Failed to check if binding is active: {err}"
463
+ ) ) ;
453
464
} ,
454
465
}
455
466
456
467
let object = Rf_findVarInFrame ( envir, symbol) ;
457
468
458
469
if object == R_UnboundValue {
459
- log:: error!( "Symbol '{name}' should have been found." ) ;
460
- return None ;
470
+ return Err ( anyhow:: anyhow!(
471
+ "Symbol '{name}' should have been found but wasn't"
472
+ ) ) ;
461
473
}
462
474
463
- Some ( completion_item_from_object (
475
+ completion_item_from_object (
464
476
name,
465
477
object,
466
478
envir,
467
479
package,
468
480
promise_strategy,
469
481
parameter_hints,
470
- ) )
482
+ )
471
483
}
472
484
473
485
// This is used when providing completions for a parameter in a document
0 commit comments