diff --git a/crates/hir-ty/src/mir.rs b/crates/hir-ty/src/mir.rs index d004e3b5daef..ac30c52b33a5 100644 --- a/crates/hir-ty/src/mir.rs +++ b/crates/hir-ty/src/mir.rs @@ -1274,6 +1274,9 @@ impl<'db> PlaceTy<'db> { .get(f.0 as usize) .cloned() .unwrap_or_else(|| panic!("field {f:?} out of range: {self_ty:?}")), + TyKind::Array(..) | TyKind::Slice(..) => { + Ty::new_error(infcx.interner, ErrorGuaranteed) + } _ => panic!("can't project out of {self_ty:?}"), } } diff --git a/crates/hir-ty/src/mir/lower/tests.rs b/crates/hir-ty/src/mir/lower/tests.rs index d8f7d549d6bf..fc60d228d15c 100644 --- a/crates/hir-ty/src/mir/lower/tests.rs +++ b/crates/hir-ty/src/mir/lower/tests.rs @@ -1,7 +1,14 @@ use hir_def::DefWithBodyId; +use rustc_type_ir::inherent::Ty as _; use test_fixture::WithFixture; -use crate::{db::HirDatabase, setup_tracing, test_db::TestDB}; +use crate::{ + db::HirDatabase, + mir::{FieldIndex, PlaceElem, PlaceTy, ProjectionElem}, + next_solver::{DbInterner, ParamEnv, Ty, TypingMode, infer::DbInternerInferExt}, + setup_tracing, + test_db::TestDB, +}; fn lower_mir(#[rust_analyzer::rust_fixture] ra_fixture: &str) { let _tracing = setup_tracing(); @@ -134,3 +141,20 @@ fn alias(x: T::A) { "#, ); } + +#[test] +fn field_projection_on_slice_recovers_with_error_type() { + let (db, file_id) = TestDB::with_single_file(""); + crate::attach_db(&db, || { + let module = db.module_for_file(file_id.file_id(&db)); + let interner = DbInterner::new_with(&db, module.krate(&db)); + let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis); + let slice = Ty::new_slice(interner, Ty::new_bool(interner)); + let field: PlaceElem = ProjectionElem::Field(FieldIndex(0)); + + let result = + PlaceTy::from_ty(slice).projection_ty(&infcx, &field, ParamEnv::empty(interner)); + + assert!(result.ty.is_ty_error()); + }); +}