Skip to content

Commit d702227

Browse files
committed
transition to Fallible
1 parent 4ab5bcb commit d702227

File tree

9 files changed

+69
-46
lines changed

9 files changed

+69
-46
lines changed

src/librustc/traits/query/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
//! `librustc_traits`.
1717
1818
use infer::canonical::Canonical;
19+
use ty::error::TypeError;
1920
use ty::{self, Ty};
2021

2122
pub mod dropck_outlives;
@@ -49,4 +50,10 @@ pub struct NoSolution;
4950

5051
pub type Fallible<T> = Result<T, NoSolution>;
5152

53+
impl<'tcx> From<TypeError<'tcx>> for NoSolution {
54+
fn from(_: TypeError<'tcx>) -> NoSolution {
55+
NoSolution
56+
}
57+
}
58+
5259
impl_stable_hash_for!(struct NoSolution { });

src/librustc/traits/query/type_op/custom.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use infer::{InferCtxt, InferResult};
11+
use infer::{InferCtxt, InferOk};
12+
use traits::query::Fallible;
1213
use ty::TyCtxt;
1314
use std::fmt;
1415

@@ -20,7 +21,7 @@ pub struct CustomTypeOp<F, G> {
2021
impl<F, G> CustomTypeOp<F, G> {
2122
pub fn new<'gcx, 'tcx, R>(closure: F, description: G) -> Self
2223
where
23-
F: FnOnce(&InferCtxt<'_, 'gcx, 'tcx>) -> InferResult<'tcx, R>,
24+
F: FnOnce(&InferCtxt<'_, 'gcx, 'tcx>) -> Fallible<InferOk<'tcx, R>>,
2425
G: Fn() -> String,
2526
{
2627
CustomTypeOp {
@@ -32,7 +33,7 @@ impl<F, G> CustomTypeOp<F, G> {
3233

3334
impl<'gcx, 'tcx, F, R, G> super::TypeOp<'gcx, 'tcx> for CustomTypeOp<F, G>
3435
where
35-
F: for<'a, 'cx> FnOnce(&'a InferCtxt<'cx, 'gcx, 'tcx>) -> InferResult<'tcx, R>,
36+
F: for<'a, 'cx> FnOnce(&'a InferCtxt<'cx, 'gcx, 'tcx>) -> Fallible<InferOk<'tcx, R>>,
3637
G: Fn() -> String,
3738
{
3839
type Output = R;
@@ -41,8 +42,8 @@ where
4142
Err(self)
4243
}
4344

44-
fn perform(self, infcx: &InferCtxt<'_, 'gcx, 'tcx>) -> InferResult<'tcx, R> {
45-
(self.closure)(infcx)
45+
fn perform(self, infcx: &InferCtxt<'_, 'gcx, 'tcx>) -> Fallible<InferOk<'tcx, R>> {
46+
Ok((self.closure)(infcx)?)
4647
}
4748
}
4849

src/librustc/traits/query/type_op/eq.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// except according to those terms.
1010

1111
use infer::canonical::{Canonical, CanonicalizedQueryResult, QueryResult};
12+
use traits::query::Fallible;
1213
use ty::{self, ParamEnv, Ty, TyCtxt};
1314

1415
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
@@ -42,8 +43,8 @@ impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for Eq<'tcx> {
4243
fn perform_query(
4344
tcx: TyCtxt<'_, 'gcx, 'tcx>,
4445
canonicalized: Canonical<'gcx, Eq<'gcx>>,
45-
) -> CanonicalizedQueryResult<'gcx, ()> {
46-
tcx.type_op_eq(canonicalized).unwrap()
46+
) -> Fallible<CanonicalizedQueryResult<'gcx, ()>> {
47+
tcx.type_op_eq(canonicalized)
4748
}
4849

4950
fn upcast_result(

src/librustc/traits/query/type_op/mod.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ use infer::canonical::query_result;
1212
use infer::canonical::{
1313
Canonical, Canonicalized, CanonicalizedQueryResult, QueryRegionConstraint, QueryResult,
1414
};
15-
use infer::{InferCtxt, InferOk, InferResult};
15+
use infer::{InferCtxt, InferOk};
1616
use std::fmt;
1717
use std::rc::Rc;
1818
use syntax::codemap::DUMMY_SP;
19+
use traits::query::Fallible;
1920
use traits::{ObligationCause, TraitEngine};
20-
use ty::error::TypeError;
2121
use ty::fold::TypeFoldable;
2222
use ty::{Lift, ParamEnv, TyCtxt};
2323

@@ -42,15 +42,18 @@ pub trait TypeOp<'gcx, 'tcx>: Sized + fmt::Debug {
4242
/// should use `fully_perform`, which will take those resulting
4343
/// obligations and prove them, and then process the combined
4444
/// results into region obligations which are returned.
45-
fn perform(self, infcx: &InferCtxt<'_, 'gcx, 'tcx>) -> InferResult<'tcx, Self::Output>;
45+
fn perform(
46+
self,
47+
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
48+
) -> Fallible<InferOk<'tcx, Self::Output>>;
4649

4750
/// Processes the operation and all resulting obligations,
4851
/// returning the final result along with any region constraints
4952
/// (they will be given over to the NLL region solver).
5053
fn fully_perform(
5154
self,
5255
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
53-
) -> Result<(Self::Output, Option<Rc<Vec<QueryRegionConstraint<'tcx>>>>), TypeError<'tcx>> {
56+
) -> Fallible<(Self::Output, Option<Rc<Vec<QueryRegionConstraint<'tcx>>>>)> {
5457
match self.trivial_noop(infcx.tcx) {
5558
Ok(r) => Ok((r, None)),
5659
Err(op) => op.fully_perform_nontrivial(infcx),
@@ -62,7 +65,7 @@ pub trait TypeOp<'gcx, 'tcx>: Sized + fmt::Debug {
6265
fn fully_perform_nontrivial(
6366
self,
6467
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
65-
) -> Result<(Self::Output, Option<Rc<Vec<QueryRegionConstraint<'tcx>>>>), TypeError<'tcx>> {
68+
) -> Fallible<(Self::Output, Option<Rc<Vec<QueryRegionConstraint<'tcx>>>>)> {
6669
if cfg!(debug_assertions) {
6770
info!(
6871
"fully_perform_op_and_get_region_constraint_data({:?})",
@@ -112,7 +115,7 @@ pub trait QueryTypeOp<'gcx: 'tcx, 'tcx>: TypeFoldable<'tcx> + Lift<'gcx> {
112115
fn perform_query(
113116
tcx: TyCtxt<'_, 'gcx, 'tcx>,
114117
canonicalized: Canonicalized<'gcx, Self>,
115-
) -> CanonicalizedQueryResult<'gcx, Self::QueryResult>;
118+
) -> Fallible<CanonicalizedQueryResult<'gcx, Self::QueryResult>>;
116119

117120
/// "Upcasts" a lifted query result (which is in the gcx lifetime)
118121
/// into the tcx lifetime. This is always just an identity cast,
@@ -136,15 +139,18 @@ where
136139
QueryTypeOp::trivial_noop(self, tcx)
137140
}
138141

139-
fn perform(self, infcx: &InferCtxt<'_, 'gcx, 'tcx>) -> InferResult<'tcx, Self::Output> {
142+
fn perform(
143+
self,
144+
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
145+
) -> Fallible<InferOk<'tcx, Self::Output>> {
140146
let param_env = self.param_env();
141147

142148
// FIXME(#33684) -- We need to use
143149
// `canonicalize_hr_query_hack` here because of things like
144150
// the subtype query, which go awry around `'static`
145151
// otherwise.
146152
let (canonical_self, canonical_var_values) = infcx.canonicalize_hr_query_hack(&self);
147-
let canonical_result = Q::perform_query(infcx.tcx, canonical_self);
153+
let canonical_result = Q::perform_query(infcx.tcx, canonical_self)?;
148154

149155
// FIXME: This is not the most efficient setup. The
150156
// `instantiate_query_result_and_region_obligations` basically
@@ -155,11 +161,11 @@ where
155161
// `QueryRegionConstraint` and ultimately into NLL
156162
// constraints. We should cut out the middleman but that will
157163
// take a bit of refactoring.
158-
infcx.instantiate_query_result_and_region_obligations(
164+
Ok(infcx.instantiate_query_result_and_region_obligations(
159165
&ObligationCause::dummy(),
160166
param_env,
161167
&canonical_var_values,
162168
Q::upcast_result(&canonical_result),
163-
)
169+
)?)
164170
}
165171
}

src/librustc/traits/query/type_op/normalize.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResult, QueryResult};
1212
use std::fmt;
13+
use traits::query::Fallible;
1314
use ty::fold::TypeFoldable;
1415
use ty::{self, Lift, ParamEnv, Ty, TyCtxt};
1516

@@ -49,7 +50,7 @@ where
4950
fn perform_query(
5051
tcx: TyCtxt<'_, 'gcx, 'tcx>,
5152
canonicalized: Canonicalized<'gcx, Self>,
52-
) -> CanonicalizedQueryResult<'gcx, Self::QueryResult> {
53+
) -> Fallible<CanonicalizedQueryResult<'gcx, Self::QueryResult>> {
5354
T::type_op_method(tcx, canonicalized)
5455
}
5556

@@ -64,7 +65,7 @@ pub trait Normalizable<'gcx, 'tcx>: fmt::Debug + TypeFoldable<'tcx> + Lift<'gcx>
6465
fn type_op_method(
6566
tcx: TyCtxt<'_, 'gcx, 'tcx>,
6667
canonicalized: Canonicalized<'gcx, Normalize<'gcx, Self>>,
67-
) -> CanonicalizedQueryResult<'gcx, Self>;
68+
) -> Fallible<CanonicalizedQueryResult<'gcx, Self>>;
6869

6970
/// Convert from the `'gcx` (lifted) form of `Self` into the `tcx`
7071
/// form of `Self`.
@@ -80,8 +81,8 @@ where
8081
fn type_op_method(
8182
tcx: TyCtxt<'_, 'gcx, 'tcx>,
8283
canonicalized: Canonicalized<'gcx, Normalize<'gcx, Self>>,
83-
) -> CanonicalizedQueryResult<'gcx, Self> {
84-
tcx.type_op_normalize_ty(canonicalized).unwrap()
84+
) -> Fallible<CanonicalizedQueryResult<'gcx, Self>> {
85+
tcx.type_op_normalize_ty(canonicalized)
8586
}
8687

8788
fn upcast_result(
@@ -98,8 +99,8 @@ where
9899
fn type_op_method(
99100
tcx: TyCtxt<'_, 'gcx, 'tcx>,
100101
canonicalized: Canonicalized<'gcx, Normalize<'gcx, Self>>,
101-
) -> CanonicalizedQueryResult<'gcx, Self> {
102-
tcx.type_op_normalize_predicate(canonicalized).unwrap()
102+
) -> Fallible<CanonicalizedQueryResult<'gcx, Self>> {
103+
tcx.type_op_normalize_predicate(canonicalized)
103104
}
104105

105106
fn upcast_result(
@@ -116,8 +117,8 @@ where
116117
fn type_op_method(
117118
tcx: TyCtxt<'_, 'gcx, 'tcx>,
118119
canonicalized: Canonicalized<'gcx, Normalize<'gcx, Self>>,
119-
) -> CanonicalizedQueryResult<'gcx, Self> {
120-
tcx.type_op_normalize_poly_fn_sig(canonicalized).unwrap()
120+
) -> Fallible<CanonicalizedQueryResult<'gcx, Self>> {
121+
tcx.type_op_normalize_poly_fn_sig(canonicalized)
121122
}
122123

123124
fn upcast_result(
@@ -134,8 +135,8 @@ where
134135
fn type_op_method(
135136
tcx: TyCtxt<'_, 'gcx, 'tcx>,
136137
canonicalized: Canonicalized<'gcx, Normalize<'gcx, Self>>,
137-
) -> CanonicalizedQueryResult<'gcx, Self> {
138-
tcx.type_op_normalize_fn_sig(canonicalized).unwrap()
138+
) -> Fallible<CanonicalizedQueryResult<'gcx, Self>> {
139+
tcx.type_op_normalize_fn_sig(canonicalized)
139140
}
140141

141142
fn upcast_result(

src/librustc/traits/query/type_op/outlives.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use infer::{InferCtxt, InferResult};
11+
use infer::{InferCtxt, InferOk};
1212
use traits::query::dropck_outlives::trivial_dropck_outlives;
13+
use traits::query::Fallible;
1314
use traits::ObligationCause;
1415
use ty::subst::Kind;
1516
use ty::{ParamEnv, Ty, TyCtxt};
@@ -40,7 +41,10 @@ impl<'gcx, 'tcx> super::TypeOp<'gcx, 'tcx> for DropckOutlives<'tcx> {
4041
}
4142
}
4243

43-
fn perform(self, infcx: &InferCtxt<'_, 'gcx, 'tcx>) -> InferResult<'tcx, Self::Output> {
44+
fn perform(
45+
self,
46+
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
47+
) -> Fallible<InferOk<'tcx, Vec<Kind<'tcx>>>> {
4448
Ok(infcx
4549
.at(&ObligationCause::dummy(), self.param_env)
4650
.dropck_outlives(self.dropped_ty))

src/librustc/traits/query/type_op/prove_predicate.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// except according to those terms.
1010

1111
use infer::canonical::{Canonical, CanonicalizedQueryResult, QueryResult};
12+
use traits::query::Fallible;
1213
use ty::{ParamEnv, Predicate, TyCtxt};
1314

1415
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
@@ -40,8 +41,8 @@ impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for ProvePredicate<'tcx> {
4041
fn perform_query(
4142
tcx: TyCtxt<'_, 'gcx, 'tcx>,
4243
canonicalized: Canonical<'gcx, ProvePredicate<'gcx>>,
43-
) -> CanonicalizedQueryResult<'gcx, ()> {
44-
tcx.type_op_prove_predicate(canonicalized).unwrap()
44+
) -> Fallible<CanonicalizedQueryResult<'gcx, ()>> {
45+
tcx.type_op_prove_predicate(canonicalized)
4546
}
4647

4748
fn upcast_result(

src/librustc/traits/query/type_op/subtype.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// except according to those terms.
1010

1111
use infer::canonical::{Canonical, CanonicalizedQueryResult, QueryResult};
12+
use traits::query::Fallible;
1213
use ty::{ParamEnv, Ty, TyCtxt};
1314

1415
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
@@ -46,8 +47,8 @@ impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for Subtype<'tcx> {
4647
fn perform_query(
4748
tcx: TyCtxt<'_, 'gcx, 'tcx>,
4849
canonicalized: Canonical<'gcx, Subtype<'gcx>>,
49-
) -> CanonicalizedQueryResult<'gcx, ()> {
50-
tcx.type_op_subtype(canonicalized).unwrap()
50+
) -> Fallible<CanonicalizedQueryResult<'gcx, ()>> {
51+
tcx.type_op_subtype(canonicalized)
5152
}
5253

5354
fn upcast_result(

src/librustc_mir/borrow_check/nll/type_check/mod.rs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ use dataflow::MaybeInitializedPlaces;
2222
use rustc::hir::def_id::DefId;
2323
use rustc::infer::canonical::QueryRegionConstraint;
2424
use rustc::infer::region_constraints::GenericKind;
25-
use rustc::infer::{InferCtxt, LateBoundRegionConversionTime, UnitResult};
25+
use rustc::infer::{InferCtxt, LateBoundRegionConversionTime};
2626
use rustc::mir::interpret::EvalErrorKind::BoundsCheck;
2727
use rustc::mir::tcx::PlaceTy;
2828
use rustc::mir::visit::{PlaceContext, Visitor};
2929
use rustc::mir::*;
3030
use rustc::traits::query::type_op;
31+
use rustc::traits::query::{Fallible, NoSolution};
3132
use rustc::traits::ObligationCause;
32-
use rustc::ty::error::TypeError;
3333
use rustc::ty::fold::TypeFoldable;
3434
use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeVariants};
3535
use std::fmt;
@@ -733,7 +733,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
733733
&mut self,
734734
locations: Locations,
735735
op: impl type_op::TypeOp<'gcx, 'tcx, Output = R>,
736-
) -> Result<R, TypeError<'tcx>> {
736+
) -> Fallible<R> {
737737
let (r, opt_data) = op.fully_perform(self.infcx)?;
738738

739739
if let Some(data) = &opt_data {
@@ -775,15 +775,15 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
775775
sub: Ty<'tcx>,
776776
sup: Ty<'tcx>,
777777
locations: Locations,
778-
) -> UnitResult<'tcx> {
778+
) -> Fallible<()> {
779779
let param_env = self.param_env;
780780
self.fully_perform_op(
781781
locations,
782782
type_op::subtype::Subtype::new(param_env, sub, sup),
783783
)
784784
}
785785

786-
fn eq_types(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, locations: Locations) -> UnitResult<'tcx> {
786+
fn eq_types(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, locations: Locations) -> Fallible<()> {
787787
let param_env = self.param_env;
788788
self.fully_perform_op(locations, type_op::eq::Eq::new(param_env, b, a))
789789
}
@@ -1561,11 +1561,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
15611561
predicate, location,
15621562
);
15631563

1564-
let param_env = self.param_env;
1565-
self.fully_perform_op(
1566-
location.at_self(),
1567-
type_op::prove_predicate::ProvePredicate::new(param_env, predicate),
1568-
).unwrap()
1564+
self.prove_predicate(predicate, location);
15691565
}
15701566
}
15711567

@@ -1579,7 +1575,9 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
15791575
self.fully_perform_op(
15801576
location.at_self(),
15811577
type_op::prove_predicate::ProvePredicate::new(param_env, predicate),
1582-
).unwrap()
1578+
).unwrap_or_else(|NoSolution| {
1579+
span_mirbug!(self, NoSolution, "could not prove {:?}", predicate);
1580+
})
15831581
}
15841582

15851583
fn typeck_mir(&mut self, mir: &Mir<'tcx>) {
@@ -1610,14 +1608,17 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
16101608

16111609
fn normalize<T>(&mut self, value: T, location: impl ToLocations) -> T
16121610
where
1613-
T: type_op::normalize::Normalizable<'gcx, 'tcx>,
1611+
T: type_op::normalize::Normalizable<'gcx, 'tcx> + Copy,
16141612
{
16151613
debug!("normalize(value={:?}, location={:?})", value, location);
16161614
let param_env = self.param_env;
16171615
self.fully_perform_op(
16181616
location.to_locations(),
16191617
type_op::normalize::Normalize::new(param_env, value),
1620-
).unwrap()
1618+
).unwrap_or_else(|NoSolution| {
1619+
span_mirbug!(self, NoSolution, "failed to normalize `{:?}`", value);
1620+
value
1621+
})
16211622
}
16221623
}
16231624

0 commit comments

Comments
 (0)