Skip to content

Commit b8ef885

Browse files
Introduce trivial WF functions, use it in fast path
1 parent 706f244 commit b8ef885

File tree

5 files changed

+84
-1
lines changed

5 files changed

+84
-1
lines changed

compiler/rustc_infer/src/infer/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,6 +1046,13 @@ impl<'tcx> InferCtxt<'tcx> {
10461046
}
10471047
}
10481048

1049+
pub fn shallow_resolve_term(&self, term: ty::Term<'tcx>) -> ty::Term<'tcx> {
1050+
match term.kind() {
1051+
ty::TermKind::Ty(ty) => self.shallow_resolve(ty).into(),
1052+
ty::TermKind::Const(ct) => self.shallow_resolve_const(ct).into(),
1053+
}
1054+
}
1055+
10491056
pub fn root_var(&self, var: ty::TyVid) -> ty::TyVid {
10501057
self.inner.borrow_mut().type_variables().root_var(var)
10511058
}

compiler/rustc_middle/src/ty/consts.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,19 @@ impl<'tcx> Const<'tcx> {
144144
let reported = tcx.dcx().span_delayed_bug(span, msg);
145145
Const::new_error(tcx, reported)
146146
}
147+
148+
pub fn is_trivially_wf(self) -> bool {
149+
match self.kind() {
150+
ty::ConstKind::Param(_) | ty::ConstKind::Placeholder(_) | ty::ConstKind::Bound(..) => {
151+
true
152+
}
153+
ty::ConstKind::Infer(_)
154+
| ty::ConstKind::Unevaluated(..)
155+
| ty::ConstKind::Value(_)
156+
| ty::ConstKind::Error(_)
157+
| ty::ConstKind::Expr(_) => false,
158+
}
159+
}
147160
}
148161

149162
impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> {

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,13 @@ impl<'tcx> Term<'tcx> {
652652
}
653653
}
654654

655+
pub fn is_trivially_wf(&self, tcx: TyCtxt<'tcx>) -> bool {
656+
match self.kind() {
657+
TermKind::Ty(ty) => ty.is_trivially_wf(tcx),
658+
TermKind::Const(ct) => ct.is_trivially_wf(),
659+
}
660+
}
661+
655662
/// Iterator that walks `self` and any types reachable from
656663
/// `self`, in depth-first order. Note that just walks the types
657664
/// that appear in `self`, it does not descend into the fields of

compiler/rustc_middle/src/ty/sty.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1832,7 +1832,7 @@ impl<'tcx> Ty<'tcx> {
18321832
ty::Infer(ty::TyVar(_)) => false,
18331833

18341834
ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
1835-
bug!("`is_trivially_sized` applied to unexpected type: {:?}", self)
1835+
bug!("`has_trivial_sizedness` applied to unexpected type: {:?}", self)
18361836
}
18371837
}
18381838
}
@@ -1896,6 +1896,52 @@ impl<'tcx> Ty<'tcx> {
18961896
}
18971897
}
18981898

1899+
pub fn is_trivially_wf(self, tcx: TyCtxt<'tcx>) -> bool {
1900+
match *self.kind() {
1901+
ty::Bool
1902+
| ty::Char
1903+
| ty::Int(_)
1904+
| ty::Uint(_)
1905+
| ty::Float(_)
1906+
| ty::Str
1907+
| ty::Never
1908+
| ty::Param(_)
1909+
| ty::Placeholder(_)
1910+
| ty::Bound(..) => true,
1911+
1912+
ty::Slice(ty) => {
1913+
ty.is_trivially_wf(tcx) && ty.has_trivial_sizedness(tcx, SizedTraitKind::Sized)
1914+
}
1915+
ty::RawPtr(ty, _) => ty.is_trivially_wf(tcx),
1916+
1917+
ty::FnPtr(sig_tys, _) => {
1918+
sig_tys.skip_binder().inputs_and_output.iter().all(|ty| ty.is_trivially_wf(tcx))
1919+
}
1920+
ty::Ref(_, ty, _) => ty.is_global() && ty.is_trivially_wf(tcx),
1921+
1922+
ty::Infer(infer) => match infer {
1923+
ty::TyVar(_) => false,
1924+
ty::IntVar(_) | ty::FloatVar(_) => true,
1925+
ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => true,
1926+
},
1927+
1928+
ty::Adt(_, _)
1929+
| ty::Tuple(_)
1930+
| ty::Array(..)
1931+
| ty::Foreign(_)
1932+
| ty::Pat(_, _)
1933+
| ty::FnDef(..)
1934+
| ty::UnsafeBinder(..)
1935+
| ty::Dynamic(..)
1936+
| ty::Closure(..)
1937+
| ty::CoroutineClosure(..)
1938+
| ty::Coroutine(..)
1939+
| ty::CoroutineWitness(..)
1940+
| ty::Alias(..)
1941+
| ty::Error(_) => false,
1942+
}
1943+
}
1944+
18991945
/// If `self` is a primitive, return its [`Symbol`].
19001946
pub fn primitive_symbol(self) -> Option<Symbol> {
19011947
match self.kind() {

compiler/rustc_trait_selection/src/solve/delegate.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,16 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
143143
None
144144
}
145145
}
146+
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => {
147+
let arg = self.shallow_resolve_term(arg);
148+
if arg.is_trivially_wf(self.tcx) {
149+
Some(Certainty::Yes)
150+
} else if arg.is_infer() {
151+
Some(Certainty::AMBIGUOUS)
152+
} else {
153+
None
154+
}
155+
}
146156
_ => None,
147157
}
148158
}

0 commit comments

Comments
 (0)