]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_borrowck/src/type_check/canonical.rs
New upstream version 1.64.0+dfsg1
[rustc.git] / compiler / rustc_borrowck / src / type_check / canonical.rs
CommitLineData
94222f64
XL
1use std::fmt;
2
3use rustc_infer::infer::canonical::Canonical;
4use rustc_infer::traits::query::NoSolution;
5use rustc_middle::mir::ConstraintCategory;
6use rustc_middle::ty::{self, ToPredicate, TypeFoldable};
c295e0f8 7use rustc_span::def_id::DefId;
94222f64
XL
8use rustc_span::Span;
9use rustc_trait_selection::traits::query::type_op::{self, TypeOpOutput};
10use rustc_trait_selection::traits::query::Fallible;
11
c295e0f8 12use crate::diagnostics::{ToUniverseInfo, UniverseInfo};
94222f64
XL
13
14use super::{Locations, NormalizeLocation, TypeChecker};
15
16impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
17 /// Given some operation `op` that manipulates types, proves
18 /// predicates, or otherwise uses the inference context, executes
19 /// `op` and then executes all the further obligations that `op`
20 /// returns. This will yield a set of outlives constraints amongst
21 /// regions which are extracted and stored as having occurred at
22 /// `locations`.
23 ///
24 /// **Any `rustc_infer::infer` operations that might generate region
25 /// constraints should occur within this method so that those
26 /// constraints can be properly localized!**
c295e0f8 27 #[instrument(skip(self, category, op), level = "trace")]
94222f64
XL
28 pub(super) fn fully_perform_op<R, Op>(
29 &mut self,
30 locations: Locations,
923072b8 31 category: ConstraintCategory<'tcx>,
94222f64
XL
32 op: Op,
33 ) -> Fallible<R>
34 where
35 Op: type_op::TypeOp<'tcx, Output = R>,
5e7ed085 36 Op::ErrorInfo: ToUniverseInfo<'tcx>,
94222f64
XL
37 {
38 let old_universe = self.infcx.universe();
39
5e7ed085 40 let TypeOpOutput { output, constraints, error_info } = op.fully_perform(self.infcx)?;
94222f64 41
064997fb 42 if let Some(data) = constraints {
94222f64
XL
43 self.push_region_constraints(locations, category, data);
44 }
45
46 let universe = self.infcx.universe();
47
48 if old_universe != universe {
5e7ed085
FG
49 let universe_info = match error_info {
50 Some(error_info) => error_info.to_universe_info(old_universe),
94222f64
XL
51 None => UniverseInfo::other(),
52 };
53 for u in old_universe..universe {
c295e0f8
XL
54 self.borrowck_context
55 .constraints
56 .universe_causes
57 .insert(u + 1, universe_info.clone());
94222f64
XL
58 }
59 }
60
61 Ok(output)
62 }
63
64 pub(super) fn instantiate_canonical_with_fresh_inference_vars<T>(
65 &mut self,
66 span: Span,
67 canonical: &Canonical<'tcx, T>,
68 ) -> T
69 where
70 T: TypeFoldable<'tcx>,
71 {
72 let (instantiated, _) =
73 self.infcx.instantiate_canonical_with_fresh_inference_vars(span, canonical);
74
c295e0f8 75 for u in 0..canonical.max_universe.as_u32() {
94222f64 76 let info = UniverseInfo::other();
c295e0f8
XL
77 self.borrowck_context
78 .constraints
79 .universe_causes
80 .insert(ty::UniverseIndex::from_u32(u), info);
94222f64
XL
81 }
82
83 instantiated
84 }
85
923072b8 86 #[instrument(skip(self), level = "debug")]
94222f64
XL
87 pub(super) fn prove_trait_ref(
88 &mut self,
89 trait_ref: ty::TraitRef<'tcx>,
90 locations: Locations,
923072b8 91 category: ConstraintCategory<'tcx>,
94222f64
XL
92 ) {
93 self.prove_predicates(
c295e0f8 94 Some(ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate {
94222f64
XL
95 trait_ref,
96 constness: ty::BoundConstness::NotConst,
3c0e092e 97 polarity: ty::ImplPolarity::Positive,
c295e0f8 98 }))),
94222f64
XL
99 locations,
100 category,
101 );
102 }
103
104 pub(super) fn normalize_and_prove_instantiated_predicates(
105 &mut self,
c295e0f8
XL
106 // Keep this parameter for now, in case we start using
107 // it in `ConstraintCategory` at some point.
108 _def_id: DefId,
94222f64
XL
109 instantiated_predicates: ty::InstantiatedPredicates<'tcx>,
110 locations: Locations,
111 ) {
c295e0f8
XL
112 for (predicate, span) in instantiated_predicates
113 .predicates
114 .into_iter()
115 .zip(instantiated_predicates.spans.into_iter())
116 {
923072b8 117 debug!(?predicate);
94222f64 118 let predicate = self.normalize(predicate, locations);
c295e0f8 119 self.prove_predicate(predicate, locations, ConstraintCategory::Predicate(span));
94222f64
XL
120 }
121 }
122
123 pub(super) fn prove_predicates(
124 &mut self,
125 predicates: impl IntoIterator<Item = impl ToPredicate<'tcx>>,
126 locations: Locations,
923072b8 127 category: ConstraintCategory<'tcx>,
94222f64
XL
128 ) {
129 for predicate in predicates {
130 let predicate = predicate.to_predicate(self.tcx());
131 debug!("prove_predicates(predicate={:?}, locations={:?})", predicate, locations,);
132
133 self.prove_predicate(predicate, locations, category);
134 }
135 }
136
c295e0f8 137 #[instrument(skip(self), level = "debug")]
94222f64
XL
138 pub(super) fn prove_predicate(
139 &mut self,
140 predicate: ty::Predicate<'tcx>,
141 locations: Locations,
923072b8 142 category: ConstraintCategory<'tcx>,
94222f64 143 ) {
94222f64
XL
144 let param_env = self.param_env;
145 self.fully_perform_op(
146 locations,
147 category,
148 param_env.and(type_op::prove_predicate::ProvePredicate::new(predicate)),
149 )
150 .unwrap_or_else(|NoSolution| {
151 span_mirbug!(self, NoSolution, "could not prove {:?}", predicate);
152 })
153 }
154
c295e0f8 155 #[instrument(skip(self), level = "debug")]
94222f64
XL
156 pub(super) fn normalize<T>(&mut self, value: T, location: impl NormalizeLocation) -> T
157 where
158 T: type_op::normalize::Normalizable<'tcx> + fmt::Display + Copy + 'tcx,
159 {
94222f64
XL
160 let param_env = self.param_env;
161 self.fully_perform_op(
162 location.to_locations(),
163 ConstraintCategory::Boring,
164 param_env.and(type_op::normalize::Normalize::new(value)),
165 )
166 .unwrap_or_else(|NoSolution| {
167 span_mirbug!(self, NoSolution, "failed to normalize `{:?}`", value);
168 value
169 })
170 }
171}