Skip to content

Commit 723f09b

Browse files
committed
Add the core logic in both old solver and new solver
1 parent 8c262fc commit 723f09b

File tree

3 files changed

+85
-0
lines changed

3 files changed

+85
-0
lines changed

compiler/rustc_next_trait_solver/src/solve/mod.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,37 @@ where
148148
}
149149
}
150150

151+
fn compute_unstable_feature_goal(
152+
&mut self,
153+
param_env: <I as Interner>::ParamEnv,
154+
symbol: <I as Interner>::Symbol,
155+
) -> QueryResult<I> {
156+
// Iterate through all goals in param_env to find the one that has the same symbol.
157+
for pred in param_env.caller_bounds().iter() {
158+
if let ty::ClauseKind::UnstableFeature(sym) = pred.kind().skip_binder() {
159+
if sym == symbol {
160+
return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
161+
}
162+
}
163+
}
164+
165+
// During codegen we must assume that all feature bounds hold as we may be
166+
// monomorphizing a body from an upstream crate which had an unstable feature
167+
// enabled that we do not.
168+
//
169+
// Note: `feature_bound_holds_in_crate` does not consider a feature to be enabled
170+
// if we are in std/core even if there is a corresponding `feature` attribute on the crate.
171+
if self.cx().features().feature_bound_holds_in_crate(symbol)
172+
|| (self.typing_mode() == TypingMode::PostAnalysis)
173+
{
174+
return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
175+
} else {
176+
return self.evaluate_added_goals_and_make_canonical_response(Certainty::Maybe(
177+
MaybeCause::Ambiguity,
178+
));
179+
}
180+
}
181+
151182
#[instrument(level = "trace", skip(self))]
152183
fn compute_const_evaluatable_goal(
153184
&mut self,

compiler/rustc_trait_selection/src/traits/fulfill.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,9 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
404404
ty::PredicateKind::AliasRelate(..) => {
405405
bug!("AliasRelate is only used by the new solver")
406406
}
407+
ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(_)) => {
408+
unreachable!("unexpected higher ranked `UnstableFeature` goal")
409+
}
407410
},
408411
Some(pred) => match pred {
409412
ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => {
@@ -761,6 +764,31 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
761764
}
762765
}
763766
}
767+
ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(symbol)) => {
768+
// Iterate through all goals in param_env to find the one that has the same symbol.
769+
for pred in obligation.param_env.caller_bounds().iter() {
770+
if let ty::ClauseKind::UnstableFeature(sym) = pred.kind().skip_binder() {
771+
if sym == symbol {
772+
return ProcessResult::Changed(Default::default());
773+
}
774+
}
775+
}
776+
777+
// During codegen we must assume that all feature bounds hold as we may be
778+
// monomorphizing a body from an upstream crate which had an unstable feature
779+
// enabled that we do not.
780+
//
781+
// Note: we don't consider a feature to be enabled
782+
// if we are in std/core even if there is a corresponding `feature` attribute on the crate.
783+
if (!self.selcx.tcx().features().staged_api()
784+
&& self.selcx.tcx().features().enabled(symbol))
785+
|| (self.selcx.infcx.typing_mode() == TypingMode::PostAnalysis)
786+
{
787+
return ProcessResult::Changed(Default::default());
788+
} else {
789+
return ProcessResult::Unchanged;
790+
}
791+
}
764792
},
765793
}
766794
}

compiler/rustc_trait_selection/src/traits/select/mod.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,32 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
838838
}
839839
}
840840

841+
ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(symbol)) => {
842+
// Iterate through all goals in param_env to find the one that has the same symbol.
843+
for pred in obligation.param_env.caller_bounds().iter() {
844+
if let ty::ClauseKind::UnstableFeature(sym) = pred.kind().skip_binder() {
845+
if sym == symbol {
846+
return Ok(EvaluatedToOk);
847+
}
848+
}
849+
}
850+
851+
// During codegen we must assume that all feature bounds hold as we may be
852+
// monomorphizing a body from an upstream crate which had an unstable feature
853+
// enabled that we do not.
854+
//
855+
// Note: we don't not consider a feature to be enabled
856+
// if we are in std/core even if there is a corresponding `feature` attribute on the crate.
857+
if (!self.tcx().features().staged_api()
858+
&& self.tcx().features().enabled(symbol))
859+
|| (self.infcx.typing_mode() == TypingMode::PostAnalysis)
860+
{
861+
return Ok(EvaluatedToOk);
862+
} else {
863+
return Ok(EvaluatedToAmbig);
864+
}
865+
}
866+
841867
ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(uv)) => {
842868
match const_evaluatable::is_const_evaluatable(
843869
self.infcx,

0 commit comments

Comments
 (0)