Skip to content

Commit 0d5693b

Browse files
committed
Add the core logic in both old solver and new solver
1 parent 0751165 commit 0d5693b

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)) => {
@@ -767,6 +770,31 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
767770
}
768771
}
769772
}
773+
ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(symbol)) => {
774+
// Iterate through all goals in param_env to find the one that has the same symbol.
775+
for pred in obligation.param_env.caller_bounds().iter() {
776+
if let ty::ClauseKind::UnstableFeature(sym) = pred.kind().skip_binder() {
777+
if sym == symbol {
778+
return ProcessResult::Changed(Default::default());
779+
}
780+
}
781+
}
782+
783+
// During codegen we must assume that all feature bounds hold as we may be
784+
// monomorphizing a body from an upstream crate which had an unstable feature
785+
// enabled that we do not.
786+
//
787+
// Note: we don't consider a feature to be enabled
788+
// if we are in std/core even if there is a corresponding `feature` attribute on the crate.
789+
if (!self.selcx.tcx().features().staged_api()
790+
&& self.selcx.tcx().features().enabled(symbol))
791+
|| (self.selcx.infcx.typing_mode() == TypingMode::PostAnalysis)
792+
{
793+
return ProcessResult::Changed(Default::default());
794+
} else {
795+
return ProcessResult::Unchanged;
796+
}
797+
}
770798
},
771799
}
772800
}

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,32 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
844844
}
845845
}
846846

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

0 commit comments

Comments
 (0)