Skip to content

Commit 32aff32

Browse files
committed
a
1 parent 8fedd86 commit 32aff32

File tree

9 files changed

+34
-81
lines changed

9 files changed

+34
-81
lines changed

compiler/rustc_const_eval/src/check_consts/ops.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
142142
|err, self_ty, trait_id| {
143143
// FIXME(const_trait_impl): Do we need any of this on the non-const codepath?
144144

145-
let trait_ref = TraitRef::from_method(tcx, trait_id, self.args);
145+
let trait_ref = TraitRef::from_assoc_args(tcx, trait_id, self.args);
146146

147147
match self_ty.kind() {
148148
Param(param_ty) => {

compiler/rustc_const_eval/src/interpret/call.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
741741
let tcx = *self.tcx;
742742

743743
let trait_def_id = tcx.trait_of_item(def_id).unwrap();
744-
let virtual_trait_ref = ty::TraitRef::from_method(tcx, trait_def_id, virtual_instance.args);
744+
let virtual_trait_ref =
745+
ty::TraitRef::from_assoc_args(tcx, trait_def_id, virtual_instance.args);
745746
let existential_trait_ref = ty::ExistentialTraitRef::erase_self_ty(tcx, virtual_trait_ref);
746747
let concrete_trait_ref = existential_trait_ref.with_self_ty(tcx, dyn_ty);
747748

compiler/rustc_middle/src/query/mod.rs

-12
Original file line numberDiff line numberDiff line change
@@ -2374,18 +2374,6 @@ rustc_queries! {
23742374
}
23752375
}
23762376

2377-
query check_constant_safe_to_evaluate(
2378-
key: ty::CanonicalQueryInput<
2379-
TyCtxt<'tcx>,
2380-
ty::ParamEnvAnd<'tcx, ty::UnevaluatedConst<'tcx>>,
2381-
>
2382-
) -> bool {
2383-
desc { |tcx|
2384-
"checking constant `{}` is safe to evaluate",
2385-
tcx.def_path_str(key.canonical.value.into_parts().1.def)
2386-
}
2387-
}
2388-
23892377
query method_autoderef_steps(
23902378
goal: CanonicalTyGoal<'tcx>
23912379
) -> MethodAutoderefStepsResult<'tcx> {

compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ pub(crate) fn transform_instance<'tcx>(
343343
let upcast_ty = match tcx.trait_of_item(def_id) {
344344
Some(trait_id) => trait_object_ty(
345345
tcx,
346-
ty::Binder::dummy(ty::TraitRef::from_method(tcx, trait_id, instance.args)),
346+
ty::Binder::dummy(ty::TraitRef::from_assoc_args(tcx, trait_id, instance.args)),
347347
),
348348
// drop_in_place won't have a defining trait, skip the upcast
349349
None => instance.args.type_at(0),
@@ -482,7 +482,7 @@ fn implemented_method<'tcx>(
482482
trait_method = trait_method_bound;
483483
method_id = instance.def_id();
484484
trait_id = tcx.trait_of_item(method_id)?;
485-
trait_ref = ty::EarlyBinder::bind(TraitRef::from_method(tcx, trait_id, instance.args));
485+
trait_ref = ty::EarlyBinder::bind(TraitRef::from_assoc_args(tcx, trait_id, instance.args));
486486
trait_id
487487
} else {
488488
return None;

compiler/rustc_trait_selection/src/traits/mod.rs

+13-54
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ use std::ops::ControlFlow;
2828

2929
use rustc_errors::ErrorGuaranteed;
3030
use rustc_hir::def::DefKind;
31-
use rustc_infer::infer::canonical::OriginalQueryValues;
3231
pub use rustc_infer::traits::*;
3332
use rustc_middle::query::Providers;
3433
use rustc_middle::span_bug;
@@ -646,13 +645,18 @@ pub fn try_evaluate_const<'tcx>(
646645
// it is well formed as otherwise CTFE will ICE. For the same reasons as with
647646
// deferring evaluation of generic/uninferred constants, we do not have to worry
648647
// about `generic_const_expr`
649-
let input = infcx
650-
.canonicalize_query(param_env.and(uv), &mut OriginalQueryValues::default());
651-
if !tcx.check_constant_safe_to_evaluate(input) {
652-
let e = tcx.dcx().delayed_bug(
653-
"Attempted to evaluate illformed constant but no error emitted",
654-
);
655-
return Err(EvaluateConstErr::EvaluationFailure(e));
648+
if tcx.instantiate_and_check_impossible_predicates((
649+
uv.def,
650+
tcx.erase_regions(uv.args),
651+
)) {
652+
// We treat these consts as rigid instead of an error or delaying a bug as we may
653+
// be checking a constant with a trivialy-false where clause that is satisfied from
654+
// a trivially-false clause in the environment.
655+
//
656+
// Delaying a bug would ICE the compiler as trivial bounds are somewhat supported.
657+
// Emitting an error would be fine but feels weird as we allow the where clause to be
658+
// written.
659+
return Ok(ct);
656660
}
657661

658662
let typing_env = infcx
@@ -747,50 +751,6 @@ fn replace_param_and_infer_args_with_placeholder<'tcx>(
747751
args.fold_with(&mut ReplaceParamAndInferWithPlaceholder { tcx, idx: 0 })
748752
}
749753

750-
#[instrument(level = "debug", skip(tcx), ret)]
751-
fn check_constant_safe_to_evaluate<'tcx>(
752-
tcx: TyCtxt<'tcx>,
753-
input: ty::CanonicalQueryInput<TyCtxt<'tcx>, ty::ParamEnvAnd<'tcx, ty::UnevaluatedConst<'tcx>>>,
754-
) -> bool {
755-
let (infcx, param_env_and, _) = tcx.infer_ctxt().build_with_canonical(DUMMY_SP, &input);
756-
let (param_env, uv) = param_env_and.into_parts();
757-
758-
// We can't just register a wf goal for the constant as that would require evaluating the constant
759-
// which would result in a query cycle.
760-
let mut predicates = tcx.predicates_of(uv.def).instantiate(tcx, uv.args).predicates;
761-
762-
// Specifically check trait fulfillment to avoid an error when trying to resolve
763-
// associated items.
764-
if let Some(trait_def_id) = tcx.trait_of_item(uv.def) {
765-
let trait_ref = ty::TraitRef::from_method(tcx, trait_def_id, uv.args);
766-
predicates.push(trait_ref.upcast(tcx));
767-
}
768-
769-
let ocx = ObligationCtxt::new(&infcx);
770-
let predicates = ocx.normalize(&ObligationCause::dummy(), param_env, predicates);
771-
for predicate in predicates {
772-
let obligation = Obligation::new(tcx, ObligationCause::dummy(), param_env, predicate);
773-
ocx.register_obligation(obligation);
774-
}
775-
let errors = ocx.select_all_or_error();
776-
777-
if !errors.is_empty() {
778-
return false;
779-
}
780-
781-
// Leak check for any higher-ranked trait mismatches.
782-
// We only need to do this in the old solver, since the new solver already
783-
// leak-checks.
784-
if !infcx.next_trait_solver() && infcx.leak_check(ty::UniverseIndex::ROOT, None).is_err() {
785-
return false;
786-
}
787-
788-
// We don't check non-higher-ranked region constraints, but we don't need to as region
789-
// constraints cant affect coherence and therefore result in overlapping impls in codegen/ctfe
790-
// so it shouldn't matter to speculatively evaluate constants with failing region constraints.
791-
true
792-
}
793-
794754
/// Normalizes the predicates and checks whether they hold in a given empty. If this
795755
/// returns true, then either normalize encountered an error or one of the predicates did not
796756
/// hold. Used when creating vtables to check for unsatisfiable methods. This should not be
@@ -832,7 +792,7 @@ fn instantiate_and_check_impossible_predicates<'tcx>(
832792
// Specifically check trait fulfillment to avoid an error when trying to resolve
833793
// associated items.
834794
if let Some(trait_def_id) = tcx.trait_of_item(key.0) {
835-
let trait_ref = ty::TraitRef::from_method(tcx, trait_def_id, key.1);
795+
let trait_ref = ty::TraitRef::from_assoc_args(tcx, trait_def_id, key.1);
836796
predicates.push(trait_ref.upcast(tcx));
837797
}
838798

@@ -934,7 +894,6 @@ pub fn provide(providers: &mut Providers) {
934894
specialization_enabled_in: specialize::specialization_enabled_in,
935895
instantiate_and_check_impossible_predicates,
936896
is_impossible_associated_item,
937-
check_constant_safe_to_evaluate,
938897
..*providers
939898
};
940899
}

compiler/rustc_ty_utils/src/instance.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ fn resolve_associated_item<'tcx>(
102102
) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> {
103103
debug!(?trait_item_id, ?typing_env, ?trait_id, ?rcvr_args, "resolve_associated_item");
104104

105-
let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_args);
105+
let trait_ref = ty::TraitRef::from_assoc_args(tcx, trait_id, rcvr_args);
106106

107107
let input = typing_env.as_query_input(trait_ref);
108108
let vtbl = match tcx.codegen_select_candidate(input) {
@@ -232,7 +232,7 @@ fn resolve_associated_item<'tcx>(
232232
Some(ty::Instance::new(leaf_def.item.def_id, args))
233233
}
234234
traits::ImplSource::Builtin(BuiltinImplSource::Object(_), _) => {
235-
let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_args);
235+
let trait_ref = ty::TraitRef::from_assoc_args(tcx, trait_id, rcvr_args);
236236
if trait_ref.has_non_region_infer() || trait_ref.has_non_region_param() {
237237
// We only resolve totally substituted vtable entries.
238238
None

compiler/rustc_type_ir/src/predicate.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ impl<I: Interner> TraitRef<I> {
7474
Self::new_from_args(interner, trait_def_id, args)
7575
}
7676

77-
pub fn from_method(interner: I, trait_id: I::DefId, args: I::GenericArgs) -> TraitRef<I> {
77+
pub fn from_assoc_args(interner: I, trait_id: I::DefId, args: I::GenericArgs) -> TraitRef<I> {
7878
let generics = interner.generics_of(trait_id);
7979
TraitRef::new(interner, trait_id, args.iter().take(generics.count()))
8080
}

tests/ui/const-generics/associated_const_equality/wf_before_evaluate.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@ fn ice<const N: u64, T: Trait<C<N> = { N }>>(_: T) {}
2020

2121
fn main() {
2222
ice::<128, _>(());
23-
//~^ ERROR: the constant `128` is not of type `u32`
23+
//~^ ERROR: type mismatch resolving `<() as Trait>::C<128> == 128`
2424
}

tests/ui/const-generics/associated_const_equality/wf_before_evaluate.stderr

+12-7
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,22 @@ note: required by a const generic parameter in `Trait::C`
1010
LL | const C<const N: u32>: u32;
1111
| ^^^^^^^^^^^^ required by this const generic parameter in `Trait::C`
1212

13-
error: the constant `128` is not of type `u32`
14-
--> $DIR/wf_before_evaluate.rs:22:5
13+
error[E0271]: type mismatch resolving `<() as Trait>::C<128> == 128`
14+
--> $DIR/wf_before_evaluate.rs:22:19
1515
|
1616
LL | ice::<128, _>(());
17-
| ^^^^^^^^^^^^^^^^^ expected `u32`, found `u64`
17+
| ------------- ^^ expected `128`, found `<() as Trait>::C::<128>`
18+
| |
19+
| required by a bound introduced by this call
1820
|
19-
note: required by a const generic parameter in `Trait::C`
20-
--> $DIR/wf_before_evaluate.rs:11:13
21+
= note: expected constant `128`
22+
found constant `<() as Trait>::C::<128>`
23+
note: required by a bound in `ice`
24+
--> $DIR/wf_before_evaluate.rs:18:31
2125
|
22-
LL | const C<const N: u32>: u32;
23-
| ^^^^^^^^^^^^ required by this const generic parameter in `Trait::C`
26+
LL | fn ice<const N: u64, T: Trait<C<N> = { N }>>(_: T) {}
27+
| ^^^^^^^^^^^^ required by this bound in `ice`
2428

2529
error: aborting due to 2 previous errors
2630

31+
For more information about this error, try `rustc --explain E0271`.

0 commit comments

Comments
 (0)