Unnamed repository; edit this file 'description' to name the repository.
| -rw-r--r-- | crates/hir-ty/src/infer/expr.rs | 33 | ||||
| -rw-r--r-- | crates/hir-ty/src/lib.rs | 8 | ||||
| -rw-r--r-- | crates/hir-ty/src/tests/never_type.rs | 16 | ||||
| -rw-r--r-- | crates/rust-analyzer/src/bin/main.rs | 2 | ||||
| -rw-r--r-- | crates/rust-analyzer/src/tracing/config.rs | 34 | ||||
| -rw-r--r-- | crates/rust-analyzer/tests/slow-tests/support.rs | 2 |
6 files changed, 51 insertions, 44 deletions
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs index df17cc3877..40465e3952 100644 --- a/crates/hir-ty/src/infer/expr.rs +++ b/crates/hir-ty/src/infer/expr.rs @@ -143,29 +143,22 @@ impl<'db> InferenceContext<'_, 'db> { expr: ExprId, is_read: ExprIsRead, ) -> bool { - // rustc does the place expr check first, but since we are feeding - // readness of the `expr` as a given value, we just can short-circuit - // the place expr check if it's true(see codes and comments below) - if is_read == ExprIsRead::Yes { - return true; - } - - // We only care about place exprs. Anything else returns an immediate - // which would constitute a read. We don't care about distinguishing - // "syntactic" place exprs since if the base of a field projection is - // not a place then it would've been UB to read from it anyways since - // that constitutes a read. - if !self.is_syntactic_place_expr(expr) { - return true; - } - // rustc queries parent hir node of `expr` here and determine whether // the current `expr` is read of value per its parent. // But since we don't have hir node, we cannot follow such "bottom-up" // method. // So, we pass down such readness from the parent expression through the // recursive `infer_expr*` calls in a "top-down" manner. + // rustc does the place expr check first, but since we are feeding + // readness of the `expr` as a given value, we just can short-circuit + // the place expr check if it's true(see codes and comments below) is_read == ExprIsRead::Yes + // We only care about place exprs. Anything else returns an immediate + // which would constitute a read. We don't care about distinguishing + // "syntactic" place exprs since if the base of a field projection is + // not a place then it would've been UB to read from it anyways since + // that constitutes a read. + || !self.is_syntactic_place_expr(expr) } /// Whether this pattern constitutes a read of value of the scrutinee that @@ -904,7 +897,7 @@ impl<'db> InferenceContext<'_, 'db> { }; let ty = self.insert_type_vars_shallow(ty); self.write_expr_ty(tgt_expr, ty); - if self.shallow_resolve(ty).is_never() + if self.table.resolve_vars_with_obligations(ty).is_never() && self.expr_guaranteed_to_constitute_read_for_never(tgt_expr, is_read) { // Any expression that produces a value of type `!` must have diverged @@ -969,8 +962,10 @@ impl<'db> InferenceContext<'_, 'db> { return self.types.types.error; }; self.table.register_bound(awaitee_ty, into_future, ObligationCause::new(expr)); - // Do not eagerly normalize. - Ty::new_projection(self.interner(), into_future_output.into(), [awaitee_ty]) + self.table.try_structurally_resolve_type( + expr.into(), + Ty::new_projection(self.interner(), into_future_output.into(), [awaitee_ty]), + ) } fn infer_record_expr( diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs index a9975615be..120c265fdc 100644 --- a/crates/hir-ty/src/lib.rs +++ b/crates/hir-ty/src/lib.rs @@ -631,17 +631,11 @@ impl InferBodyId { pub fn setup_tracing() -> Option<tracing::subscriber::DefaultGuard> { use std::env; - use std::sync::LazyLock; use tracing_subscriber::{Registry, layer::SubscriberExt}; use tracing_tree::HierarchicalLayer; - static ENABLE: LazyLock<bool> = LazyLock::new(|| env::var("CHALK_DEBUG").is_ok()); - if !*ENABLE { - return None; - } - let filter: tracing_subscriber::filter::Targets = - env::var("CHALK_DEBUG").ok().and_then(|it| it.parse().ok()).unwrap_or_default(); + env::var("SOLVER_DEBUG").ok().and_then(|it| it.parse().ok()).unwrap_or_default(); let layer = HierarchicalLayer::default() .with_indent_lines(true) .with_ansi(false) diff --git a/crates/hir-ty/src/tests/never_type.rs b/crates/hir-ty/src/tests/never_type.rs index fd21286d50..9d98218107 100644 --- a/crates/hir-ty/src/tests/never_type.rs +++ b/crates/hir-ty/src/tests/never_type.rs @@ -901,3 +901,19 @@ fn example() -> Struct { "#, ); } + +#[test] +fn never_await() { + check_no_mismatches( + r#" +//- minicore: future +async fn test() -> ! { + loop {} +} + +pub async fn test1() -> ! { + test().await; +} + "#, + ); +} diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs index e05385528a..6bd27c2621 100644 --- a/crates/rust-analyzer/src/bin/main.rs +++ b/crates/rust-analyzer/src/bin/main.rs @@ -157,7 +157,7 @@ fn setup_logging(log_file_flag: Option<PathBuf>) -> anyhow::Result<()> { // Deliberately enable all `warn` logs if the user has not set RA_LOG, as there is usually // useful information in there for debugging. filter: env::var("RA_LOG").ok().unwrap_or_else(|| "warn".to_owned()), - chalk_filter: env::var("CHALK_DEBUG").ok(), + solver_filter: env::var("SOLVER_DEBUG").ok(), profile_filter: env::var("RA_PROFILE").ok(), json_profile_filter: std::env::var("RA_PROFILE_JSON").ok(), } diff --git a/crates/rust-analyzer/src/tracing/config.rs b/crates/rust-analyzer/src/tracing/config.rs index 2bc9f3c34a..9c6648916a 100644 --- a/crates/rust-analyzer/src/tracing/config.rs +++ b/crates/rust-analyzer/src/tracing/config.rs @@ -20,16 +20,16 @@ use crate::tracing::json; pub struct Config<T> { pub writer: T, pub filter: String, - /// The meaning of CHALK_DEBUG is to tell chalk crates - /// (i.e. chalk-solve, chalk-ir, chalk-recursive) how to filter tracing + /// The meaning of SOLVER_DEBUG is to tell the solver crates + /// (i.e. rustc_type_ir, rustc_next_trait_solver) how to filter tracing /// logs. But now we can only have just one filter, which means we have to - /// merge chalk filter to our main filter (from RA_LOG env). + /// merge the solver filter to our main filter (from RA_LOG env). /// - /// The acceptable syntax of CHALK_DEBUG is `target[span{field=value}]=level`. + /// The acceptable syntax of SOLVER_DEBUG is `target[span{field=value}]=level`. /// As the value should only affect chalk crates, we'd better manually - /// specify the target. And for simplicity, CHALK_DEBUG only accept the value + /// specify the target. And for simplicity, SOLVER_DEBUG only accept the value /// that specify level. - pub chalk_filter: Option<String>, + pub solver_filter: Option<String>, /// Filtering syntax, set in a shell: /// ```text /// env RA_PROFILE=* // dump everything @@ -75,22 +75,24 @@ where } .with_filter(targets_filter); - let chalk_layer = match self.chalk_filter { - Some(chalk_filter) => { + let solver_layer = match self.solver_filter { + Some(solver_filter) => { let level: LevelFilter = - chalk_filter.parse().with_context(|| "invalid chalk log filter")?; - - let chalk_filter = Targets::new() - .with_target("chalk_solve", level) - .with_target("chalk_ir", level) - .with_target("chalk_recursive", level); + solver_filter.parse().with_context(|| "invalid solver log filter")?; + + // Once with `ra_ap_` and once without; in-tree r-a uses without, out-of-tree uses with. + let solver_filter = Targets::new() + .with_target("ra_ap_rustc_type_ir", level) + .with_target("rustc_type_ir", level) + .with_target("ra_ap_rustc_next_trait_solver", level) + .with_target("rustc_next_trait_solver", level); // TODO: remove `.with_filter(LevelFilter::OFF)` on the `None` branch. HierarchicalLayer::default() .with_indent_lines(true) .with_ansi(false) .with_indent_amount(2) .with_writer(io::stderr) - .with_filter(chalk_filter) + .with_filter(solver_filter) .boxed() } None => None::<HierarchicalLayer>.with_filter(LevelFilter::OFF).boxed(), @@ -122,7 +124,7 @@ where .with(ra_fmt_layer) .with(json_profiler_layer) .with(profiler_layer) - .with(chalk_layer); + .with(solver_layer); tracing::subscriber::set_global_default(subscriber)?; diff --git a/crates/rust-analyzer/tests/slow-tests/support.rs b/crates/rust-analyzer/tests/slow-tests/support.rs index c3568ce950..2a469a5bfb 100644 --- a/crates/rust-analyzer/tests/slow-tests/support.rs +++ b/crates/rust-analyzer/tests/slow-tests/support.rs @@ -170,7 +170,7 @@ impl Project<'_> { // Deliberately enable all `error` logs if the user has not set RA_LOG, as there is usually // useful information in there for debugging. filter: std::env::var("RA_LOG").ok().unwrap_or_else(|| "error".to_owned()), - chalk_filter: std::env::var("CHALK_DEBUG").ok(), + solver_filter: std::env::var("SOLVER_DEBUG").ok(), profile_filter: std::env::var("RA_PROFILE").ok(), json_profile_filter: std::env::var("RA_PROFILE_JSON").ok(), } |