diff options
Diffstat (limited to 'compiler/rustc_trait_selection/src')
8 files changed, 54 insertions, 63 deletions
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 6ef64c3ed80..b7e2ed391cd 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -156,8 +156,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { (leaf_trait_predicate, &obligation) }; - let (main_trait_predicate, leaf_trait_predicate, predicate_constness) = self.get_effects_trait_pred_override(main_trait_predicate, leaf_trait_predicate, span); - let main_trait_ref = main_trait_predicate.to_poly_trait_ref(); let leaf_trait_ref = leaf_trait_predicate.to_poly_trait_ref(); @@ -228,7 +226,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let err_msg = self.get_standard_error_message( main_trait_predicate, message, - predicate_constness, + None, append_const_msg, post_message, ); @@ -289,13 +287,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ); } - if tcx.is_lang_item(leaf_trait_ref.def_id(), LangItem::Drop) - && matches!(predicate_constness, Some(ty::BoundConstness::ConstIfConst | ty::BoundConstness::Const)) - { - err.note("`~const Drop` was renamed to `~const Destruct`"); - err.note("See <https://github.com/rust-lang/rust/pull/94901> for more details"); - } - let explanation = get_explanation_based_on_obligation( self.tcx, &obligation, @@ -541,6 +532,29 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err } + ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(predicate)) => { + // FIXME(effects): We should recompute the predicate with `~const` + // if it's `const`, and if it holds, explain that this bound only + // *conditionally* holds. If that fails, we should also do selection + // to drill this down to an impl or built-in source, so we can + // point at it and explain that while the trait *is* implemented, + // that implementation is not const. + let err_msg = self.get_standard_error_message( + bound_predicate.rebind(ty::TraitPredicate { + trait_ref: predicate.trait_ref, + polarity: ty::PredicatePolarity::Positive, + }), + None, + Some(match predicate.host { + ty::HostPolarity::Maybe => ty::BoundConstness::ConstIfConst, + ty::HostPolarity::Const => ty::BoundConstness::Const, + }), + None, + String::new(), + ); + struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg) + } + ty::PredicateKind::Subtype(predicate) => { // Errors for Subtype predicates show up as // `FulfillmentErrorCode::SubtypeError`, @@ -2374,52 +2388,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }) } - /// For effects predicates such as `<u32 as Add>::Effects: Compat<host>`, pretend that the - /// predicate that failed was `u32: Add`. Return the constness of such predicate to later - /// print as `u32: ~const Add`. - fn get_effects_trait_pred_override( - &self, - p: ty::PolyTraitPredicate<'tcx>, - leaf: ty::PolyTraitPredicate<'tcx>, - span: Span, - ) -> (ty::PolyTraitPredicate<'tcx>, ty::PolyTraitPredicate<'tcx>, Option<ty::BoundConstness>) - { - let trait_ref = p.to_poly_trait_ref(); - if !self.tcx.is_lang_item(trait_ref.def_id(), LangItem::EffectsCompat) { - return (p, leaf, None); - } - - let Some(ty::Alias(ty::AliasTyKind::Projection, projection)) = - trait_ref.self_ty().no_bound_vars().map(Ty::kind) - else { - return (p, leaf, None); - }; - - let constness = trait_ref.skip_binder().args.const_at(1); - - let constness = if constness == self.tcx.consts.true_ || constness.is_ct_infer() { - None - } else if constness == self.tcx.consts.false_ { - Some(ty::BoundConstness::Const) - } else if matches!(constness.kind(), ty::ConstKind::Param(_)) { - Some(ty::BoundConstness::ConstIfConst) - } else { - self.dcx().span_bug(span, format!("Unknown constness argument: {constness:?}")); - }; - - let new_pred = p.map_bound(|mut trait_pred| { - trait_pred.trait_ref = projection.trait_ref(self.tcx); - trait_pred - }); - - let new_leaf = leaf.map_bound(|mut trait_pred| { - trait_pred.trait_ref = projection.trait_ref(self.tcx); - trait_pred - }); - - (new_pred, new_leaf, constness) - } - fn add_tuple_trait_message( &self, obligation_cause_code: &ObligationCauseCode<'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 12aeee0d02f..934fe9ec47c 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -806,7 +806,8 @@ impl<'tcx> AutoTraitFinder<'tcx> { | ty::PredicateKind::Subtype(..) // FIXME(generic_const_exprs): you can absolutely add this as a where clauses | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) - | ty::PredicateKind::Coerce(..) => {} + | ty::PredicateKind::Coerce(..) + | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => {} ty::PredicateKind::Ambiguous => return false, }; } diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index cc0450e0b05..a068f25fe35 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -245,6 +245,7 @@ fn predicate_references_self<'tcx>( | ty::ClauseKind::RegionOutlives(..) // FIXME(generic_const_exprs): this can mention `Self` | ty::ClauseKind::ConstEvaluatable(..) + | ty::ClauseKind::HostEffect(..) => None, } } @@ -284,7 +285,8 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool { | ty::ClauseKind::Projection(_) | ty::ClauseKind::ConstArgHasType(_, _) | ty::ClauseKind::WellFormed(_) - | ty::ClauseKind::ConstEvaluatable(_) => false, + | ty::ClauseKind::ConstEvaluatable(_) + | ty::ClauseKind::HostEffect(..) => false, }) } diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 2bdeb00bdac..1754418156d 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -372,7 +372,11 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { | ty::PredicateKind::Subtype(_) | ty::PredicateKind::Coerce(_) | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) - | ty::PredicateKind::ConstEquate(..) => { + | ty::PredicateKind::ConstEquate(..) + // FIXME(effects): We may need to do this using the higher-ranked + // pred instead of just instantiating it with placeholders b/c of + // higher-ranked implied bound issues in the old solver. + | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => { let pred = ty::Binder::dummy(infcx.enter_forall_and_leak_universe(binder)); let mut obligations = PredicateObligations::with_capacity(1); obligations.push(obligation.with(infcx.tcx, pred)); @@ -398,6 +402,10 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { ) } + ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => { + ProcessResult::Changed(Default::default()) + } + ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(data)) => { if infcx.considering_regions { infcx.region_outlives_predicate(&obligation.cause, Binder::dummy(data)); @@ -450,7 +458,6 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { ty::ConstKind::Infer(var) => { let var = match var { ty::InferConst::Var(vid) => TyOrConstInferVar::Const(vid), - ty::InferConst::EffectVar(vid) => TyOrConstInferVar::Effect(vid), ty::InferConst::Fresh(_) => { bug!("encountered fresh const in fulfill") } diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index dfd0cab6905..c6e41e57f0c 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs @@ -96,6 +96,7 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>( // FIXME(const_generics): Make sure that `<'a, 'b, const N: &'a &'b u32>` is sound // if we ever support that ty::PredicateKind::Clause(ty::ClauseKind::Trait(..)) + | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) | ty::PredicateKind::Subtype(..) | ty::PredicateKind::Coerce(..) @@ -200,6 +201,7 @@ pub fn compute_implied_outlives_bounds_compat_inner<'tcx>( // FIXME(const_generics): Make sure that `<'a, 'b, const N: &'a &'b u32>` is sound // if we ever support that ty::PredicateKind::Clause(ty::ClauseKind::Trait(..)) + | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) | ty::PredicateKind::Subtype(..) | ty::PredicateKind::Coerce(..) diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index c0122d3d552..47601b0c18d 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -546,7 +546,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } // Provide an impl for suitable functions, rejecting `#[target_feature]` functions (RFC 2396). - ty::FnDef(def_id, _args) => { + ty::FnDef(def_id, _) => { let tcx = self.tcx(); if tcx.fn_sig(def_id).skip_binder().is_fn_trait_compatible() && tcx.codegen_fn_attrs(def_id).target_features.is_empty() diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index d5b1c5a97da..ec4114fd9d7 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -645,6 +645,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.evaluate_trait_predicate_recursively(previous_stack, obligation) } + ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => { + // FIXME(effects): It should be relatively straightforward to implement + // old trait solver support for `HostEffect` bounds; or at least basic + // support for them. + todo!() + } + ty::PredicateKind::Subtype(p) => { let p = bound_predicate.rebind(p); // Does this code ever run? @@ -1821,8 +1828,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { |cand: ty::PolyTraitPredicate<'tcx>| cand.is_global() && !cand.has_bound_vars(); // (*) Prefer `BuiltinCandidate { has_nested: false }`, `PointeeCandidate`, - // `DiscriminantKindCandidate`, `ConstDestructCandidate` - // to anything else. + // or `DiscriminantKindCandidate` to anything else. // // This is a fix for #53123 and prevents winnowing from accidentally extending the // lifetime of a variable. diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 8904a9a6858..437343b569c 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -170,6 +170,10 @@ pub fn clause_obligations<'tcx>( ty::ClauseKind::Trait(t) => { wf.compute_trait_pred(t, Elaborate::None); } + ty::ClauseKind::HostEffect(..) => { + // Technically the well-formedness of this predicate is implied by + // the corresponding trait predicate it should've been generated beside. + } ty::ClauseKind::RegionOutlives(..) => {} ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, _reg)) => { wf.compute(ty.into()); @@ -1021,6 +1025,7 @@ pub(crate) fn required_region_bounds<'tcx>( } } ty::ClauseKind::Trait(_) + | ty::ClauseKind::HostEffect(..) | ty::ClauseKind::RegionOutlives(_) | ty::ClauseKind::Projection(_) | ty::ClauseKind::ConstArgHasType(_, _) |
