Skip to content

Commit 63c4e69

Browse files
committed
Auto merge of rust-lang#16367 - Veykril:value-ty, r=Veykril
fix: Make `value_ty` query fallible
2 parents 2d5ce88 + 8f4f5a6 commit 63c4e69

File tree

8 files changed

+59
-38
lines changed

8 files changed

+59
-38
lines changed

crates/hir-def/src/db.rs

+1-15
Original file line numberDiff line numberDiff line change
@@ -95,21 +95,7 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast<dyn ExpandDataba
9595
#[salsa::invoke(DefMap::crate_def_map_query)]
9696
fn crate_def_map_query(&self, krate: CrateId) -> Arc<DefMap>;
9797

98-
/// Computes the block-level `DefMap`, returning `None` when `block` doesn't contain any inner
99-
/// items directly.
100-
///
101-
/// For example:
102-
///
103-
/// ```
104-
/// fn f() { // (0)
105-
/// { // (1)
106-
/// fn inner() {}
107-
/// }
108-
/// }
109-
/// ```
110-
///
111-
/// The `block_def_map` for block 0 would return `None`, while `block_def_map` of block 1 would
112-
/// return a `DefMap` containing `inner`.
98+
/// Computes the block-level `DefMap`.
11399
#[salsa::invoke(DefMap::block_def_map_query)]
114100
fn block_def_map(&self, block: BlockId) -> Arc<DefMap>;
115101

crates/hir-ty/src/db.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,10 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
8686
#[salsa::cycle(crate::lower::ty_recover)]
8787
fn ty(&self, def: TyDefId) -> Binders<Ty>;
8888

89+
/// Returns the type of the value of the given constant, or `None` if the the `ValueTyDefId` is
90+
/// a `StructId` or `EnumVariantId` with a record constructor.
8991
#[salsa::invoke(crate::lower::value_ty_query)]
90-
fn value_ty(&self, def: ValueTyDefId) -> Binders<Ty>;
92+
fn value_ty(&self, def: ValueTyDefId) -> Option<Binders<Ty>>;
9193

9294
#[salsa::invoke(crate::lower::impl_self_ty_query)]
9395
#[salsa::cycle(crate::lower::impl_self_ty_recover)]

crates/hir-ty/src/infer/expr.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1245,7 +1245,7 @@ impl InferenceContext<'_> {
12451245
.build();
12461246
self.write_method_resolution(tgt_expr, func, subst.clone());
12471247

1248-
let method_ty = self.db.value_ty(func.into()).substitute(Interner, &subst);
1248+
let method_ty = self.db.value_ty(func.into()).unwrap().substitute(Interner, &subst);
12491249
self.register_obligations_for_call(&method_ty);
12501250

12511251
self.infer_expr_coerce(rhs, &Expectation::has_type(rhs_ty.clone()));
@@ -1541,7 +1541,7 @@ impl InferenceContext<'_> {
15411541
self.check_method_call(
15421542
tgt_expr,
15431543
&[],
1544-
self.db.value_ty(func.into()),
1544+
self.db.value_ty(func.into()).unwrap(),
15451545
substs,
15461546
ty,
15471547
expected,
@@ -1586,7 +1586,7 @@ impl InferenceContext<'_> {
15861586
item: func.into(),
15871587
})
15881588
}
1589-
(ty, self.db.value_ty(func.into()), substs)
1589+
(ty, self.db.value_ty(func.into()).unwrap(), substs)
15901590
}
15911591
None => {
15921592
let field_with_same_name_exists = match self.lookup_field(&receiver_ty, method_name)

crates/hir-ty/src/infer/path.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ impl InferenceContext<'_> {
3434

3535
self.add_required_obligations_for_value_path(generic_def, &substs);
3636

37-
let ty = self.db.value_ty(value_def).substitute(Interner, &substs);
37+
let ty = self.db.value_ty(value_def)?.substitute(Interner, &substs);
3838
let ty = self.normalize_associated_types_in(ty);
3939
Some(ty)
4040
}
@@ -98,7 +98,7 @@ impl InferenceContext<'_> {
9898
let Some(generic_def) = value_def.to_generic_def_id() else {
9999
// `value_def` is the kind of item that can never be generic (i.e. statics, at least
100100
// currently). We can just skip the binders to get its type.
101-
let (ty, binders) = self.db.value_ty(value_def).into_value_and_skipped_binders();
101+
let (ty, binders) = self.db.value_ty(value_def)?.into_value_and_skipped_binders();
102102
stdx::always!(
103103
parent_substs.is_none() && binders.is_empty(Interner),
104104
"non-empty binders for non-generic def",

crates/hir-ty/src/lower.rs

+18-15
Original file line numberDiff line numberDiff line change
@@ -1727,19 +1727,19 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS
17271727
}
17281728

17291729
/// Build the type of a tuple struct constructor.
1730-
fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<Ty> {
1730+
fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Option<Binders<Ty>> {
17311731
let struct_data = db.struct_data(def);
17321732
match struct_data.variant_data.kind() {
1733-
StructKind::Record => unreachable!("callers check for valueness of variant"),
1734-
StructKind::Unit => return type_for_adt(db, def.into()),
1733+
StructKind::Record => None,
1734+
StructKind::Unit => Some(type_for_adt(db, def.into())),
17351735
StructKind::Tuple => {
17361736
let generics = generics(db.upcast(), AdtId::from(def).into());
17371737
let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1738-
make_binders(
1738+
Some(make_binders(
17391739
db,
17401740
&generics,
17411741
TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(Interner),
1742-
)
1742+
))
17431743
}
17441744
}
17451745
}
@@ -1757,20 +1757,23 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId)
17571757
}
17581758

17591759
/// Build the type of a tuple enum variant constructor.
1760-
fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> Binders<Ty> {
1760+
fn type_for_enum_variant_constructor(
1761+
db: &dyn HirDatabase,
1762+
def: EnumVariantId,
1763+
) -> Option<Binders<Ty>> {
17611764
let e = def.lookup(db.upcast()).parent;
17621765
match db.enum_variant_data(def).variant_data.kind() {
1763-
StructKind::Record => unreachable!("callers check for valueness of variant"),
1764-
StructKind::Unit => return type_for_adt(db, e.into()),
1766+
StructKind::Record => None,
1767+
StructKind::Unit => Some(type_for_adt(db, e.into())),
17651768
StructKind::Tuple => {
17661769
let generics = generics(db.upcast(), e.into());
17671770
let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
1768-
make_binders(
1771+
Some(make_binders(
17691772
db,
17701773
&generics,
17711774
TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs)
17721775
.intern(Interner),
1773-
)
1776+
))
17741777
}
17751778
}
17761779
}
@@ -1889,14 +1892,14 @@ pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &Cycle, def: &TyDefId) ->
18891892
make_binders(db, &generics, TyKind::Error.intern(Interner))
18901893
}
18911894

1892-
pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> {
1895+
pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Option<Binders<Ty>> {
18931896
match def {
1894-
ValueTyDefId::FunctionId(it) => type_for_fn(db, it),
1897+
ValueTyDefId::FunctionId(it) => Some(type_for_fn(db, it)),
18951898
ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it),
1896-
ValueTyDefId::UnionId(it) => type_for_adt(db, it.into()),
1899+
ValueTyDefId::UnionId(it) => Some(type_for_adt(db, it.into())),
18971900
ValueTyDefId::EnumVariantId(it) => type_for_enum_variant_constructor(db, it),
1898-
ValueTyDefId::ConstId(it) => type_for_const(db, it),
1899-
ValueTyDefId::StaticId(it) => type_for_static(db, it),
1901+
ValueTyDefId::ConstId(it) => Some(type_for_const(db, it)),
1902+
ValueTyDefId::StaticId(it) => Some(type_for_static(db, it)),
19001903
}
19011904
}
19021905

crates/hir-ty/src/tests/regression.rs

+28
Original file line numberDiff line numberDiff line change
@@ -2012,3 +2012,31 @@ fn rustc_test_issue_52437() {
20122012
"#,
20132013
);
20142014
}
2015+
2016+
#[test]
2017+
fn incorrect_variant_form_through_alias_caught() {
2018+
check_types(
2019+
r#"
2020+
enum Enum { Braced {}, Unit, Tuple() }
2021+
type Alias = Enum;
2022+
2023+
fn main() {
2024+
Alias::Braced;
2025+
//^^^^^^^^^^^^^ {unknown}
2026+
let Alias::Braced = loop {};
2027+
//^^^^^^^^^^^^^ !
2028+
let Alias::Braced(..) = loop {};
2029+
//^^^^^^^^^^^^^^^^^ Enum
2030+
2031+
Alias::Unit();
2032+
//^^^^^^^^^^^^^ {unknown}
2033+
Alias::Unit{};
2034+
//^^^^^^^^^^^^^ Enum
2035+
let Alias::Unit() = loop {};
2036+
//^^^^^^^^^^^^^ Enum
2037+
let Alias::Unit{} = loop {};
2038+
//^^^^^^^^^^^^^ Enum
2039+
}
2040+
"#,
2041+
)
2042+
}

crates/hir/src/lib.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -3786,7 +3786,9 @@ impl Type {
37863786
}
37873787

37883788
fn from_value_def(db: &dyn HirDatabase, def: impl Into<ValueTyDefId> + HasResolver) -> Type {
3789-
let ty = db.value_ty(def.into());
3789+
let Some(ty) = db.value_ty(def.into()) else {
3790+
return Type::new(db, def, TyKind::Error.intern(Interner));
3791+
};
37903792
let substs = TyBuilder::unknown_subst(
37913793
db,
37923794
match def.into() {

crates/hir/src/source_analyzer.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ impl SourceAnalyzer {
268268
) -> Option<Callable> {
269269
let expr_id = self.expr_id(db, &call.clone().into())?;
270270
let (func, substs) = self.infer.as_ref()?.method_resolution(expr_id)?;
271-
let ty = db.value_ty(func.into()).substitute(Interner, &substs);
271+
let ty = db.value_ty(func.into())?.substitute(Interner, &substs);
272272
let ty = Type::new_with_resolver(db, &self.resolver, ty);
273273
let mut res = ty.as_callable(db)?;
274274
res.is_bound_method = true;

0 commit comments

Comments
 (0)