diff options
Diffstat (limited to 'compiler/rustc_middle/src')
| -rw-r--r-- | compiler/rustc_middle/src/mir/interpret/error.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/traits/solve.rs | 30 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/_match.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/context.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/generics.rs | 24 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/layout.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/relate.rs | 95 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/sty.rs | 4 |
8 files changed, 88 insertions, 82 deletions
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index f344dd5a8c3..b85354e10f9 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -420,7 +420,6 @@ pub enum ValidationErrorKind<'tcx> { PartialPointer, PtrToUninhabited { ptr_kind: PointerKind, ty: Ty<'tcx> }, PtrToStatic { ptr_kind: PointerKind }, - MutableRefInConstOrStatic, ConstRefToMutable, ConstRefToExtern, MutableRefToImmutable, diff --git a/compiler/rustc_middle/src/traits/solve.rs b/compiler/rustc_middle/src/traits/solve.rs index 048df367bd6..0dc65126011 100644 --- a/compiler/rustc_middle/src/traits/solve.rs +++ b/compiler/rustc_middle/src/traits/solve.rs @@ -60,7 +60,6 @@ pub enum Certainty { impl Certainty { pub const AMBIGUOUS: Certainty = Certainty::Maybe(MaybeCause::Ambiguity); - pub const OVERFLOW: Certainty = Certainty::Maybe(MaybeCause::Overflow); /// Use this function to merge the certainty of multiple nested subgoals. /// @@ -79,16 +78,13 @@ impl Certainty { (Certainty::Yes, Certainty::Yes) => Certainty::Yes, (Certainty::Yes, Certainty::Maybe(_)) => other, (Certainty::Maybe(_), Certainty::Yes) => self, - (Certainty::Maybe(MaybeCause::Ambiguity), Certainty::Maybe(MaybeCause::Ambiguity)) => { - Certainty::Maybe(MaybeCause::Ambiguity) - } - (Certainty::Maybe(MaybeCause::Ambiguity), Certainty::Maybe(MaybeCause::Overflow)) - | (Certainty::Maybe(MaybeCause::Overflow), Certainty::Maybe(MaybeCause::Ambiguity)) - | (Certainty::Maybe(MaybeCause::Overflow), Certainty::Maybe(MaybeCause::Overflow)) => { - Certainty::Maybe(MaybeCause::Overflow) - } + (Certainty::Maybe(a), Certainty::Maybe(b)) => Certainty::Maybe(a.unify_with(b)), } } + + pub const fn overflow(suggest_increasing_limit: bool) -> Certainty { + Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit }) + } } /// Why we failed to evaluate a goal. @@ -99,7 +95,21 @@ pub enum MaybeCause { /// or we hit a case where we just don't bother, e.g. `?x: Trait` goals. Ambiguity, /// We gave up due to an overflow, most often by hitting the recursion limit. - Overflow, + Overflow { suggest_increasing_limit: bool }, +} + +impl MaybeCause { + fn unify_with(self, other: MaybeCause) -> MaybeCause { + match (self, other) { + (MaybeCause::Ambiguity, MaybeCause::Ambiguity) => MaybeCause::Ambiguity, + (MaybeCause::Ambiguity, MaybeCause::Overflow { .. }) => other, + (MaybeCause::Overflow { .. }, MaybeCause::Ambiguity) => self, + ( + MaybeCause::Overflow { suggest_increasing_limit: a }, + MaybeCause::Overflow { suggest_increasing_limit: b }, + ) => MaybeCause::Overflow { suggest_increasing_limit: a || b }, + } + } } #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, HashStable, TypeFoldable, TypeVisitable)] diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs index 425a2dbd890..e28e4d66faf 100644 --- a/compiler/rustc_middle/src/ty/_match.rs +++ b/compiler/rustc_middle/src/ty/_match.rs @@ -37,10 +37,6 @@ impl<'tcx> TypeRelation<'tcx> for MatchAgainstFreshVars<'tcx> { self.tcx } - fn a_is_expected(&self) -> bool { - true - } // irrelevant - fn relate_with_variance<T: Relate<'tcx>>( &mut self, _: ty::Variance, @@ -75,7 +71,7 @@ impl<'tcx> TypeRelation<'tcx> for MatchAgainstFreshVars<'tcx> { ) => Ok(a), (&ty::Infer(_), _) | (_, &ty::Infer(_)) => { - Err(TypeError::Sorts(relate::expected_found(self, a, b))) + Err(TypeError::Sorts(relate::expected_found(a, b))) } (&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(Ty::new_error(self.tcx(), guar)), @@ -100,7 +96,7 @@ impl<'tcx> TypeRelation<'tcx> for MatchAgainstFreshVars<'tcx> { } (ty::ConstKind::Infer(_), _) | (_, ty::ConstKind::Infer(_)) => { - return Err(TypeError::ConstMismatch(relate::expected_found(self, a, b))); + return Err(TypeError::ConstMismatch(relate::expected_found(a, b))); } _ => {} diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index c6359dae1ab..b2a7f5599b6 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -335,8 +335,10 @@ pub struct CommonTypes<'tcx> { pub u32: Ty<'tcx>, pub u64: Ty<'tcx>, pub u128: Ty<'tcx>, + pub f16: Ty<'tcx>, pub f32: Ty<'tcx>, pub f64: Ty<'tcx>, + pub f128: Ty<'tcx>, pub str_: Ty<'tcx>, pub never: Ty<'tcx>, pub self_param: Ty<'tcx>, @@ -416,8 +418,10 @@ impl<'tcx> CommonTypes<'tcx> { u32: mk(Uint(ty::UintTy::U32)), u64: mk(Uint(ty::UintTy::U64)), u128: mk(Uint(ty::UintTy::U128)), + f16: mk(Float(ty::FloatTy::F16)), f32: mk(Float(ty::FloatTy::F32)), f64: mk(Float(ty::FloatTy::F64)), + f128: mk(Float(ty::FloatTy::F128)), str_: mk(Str), self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })), diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index c81d9dfbc7d..2630b96869b 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -360,6 +360,30 @@ impl<'tcx> Generics { let own = &args[self.parent_count..][..self.params.len()]; if self.has_self && self.parent.is_none() { &own[1..] } else { own } } + + /// Returns true if a concrete type is specified after a default type. + /// For example, consider `struct T<W = usize, X = Vec<W>>(W, X)` + /// `T<usize, String>` will return true + /// `T<usize>` will return false + pub fn check_concrete_type_after_default( + &'tcx self, + tcx: TyCtxt<'tcx>, + args: &'tcx [ty::GenericArg<'tcx>], + ) -> bool { + let mut default_param_seen = false; + for param in self.params.iter() { + if let Some(inst) = + param.default_value(tcx).map(|default| default.instantiate(tcx, args)) + { + if inst == args[param.index as usize] { + default_param_seen = true; + } else if default_param_seen { + return true; + } + } + } + false + } } /// Bounds on generics. diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 62d5a8fa4df..529d847bfb0 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -116,8 +116,10 @@ impl Primitive { fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { match *self { Int(i, signed) => i.to_ty(tcx, signed), + F16 => tcx.types.f16, F32 => tcx.types.f32, F64 => tcx.types.f64, + F128 => tcx.types.f128, // FIXME(erikdesjardins): handle non-default addrspace ptr sizes Pointer(_) => Ty::new_mut_ptr(tcx, Ty::new_unit(tcx)), } @@ -134,7 +136,7 @@ impl Primitive { let signed = false; tcx.data_layout().ptr_sized_integer().to_ty(tcx, signed) } - F32 | F64 => bug!("floats do not have an int type"), + F16 | F32 | F64 | F128 => bug!("floats do not have an int type"), } } } diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 303f285b00c..990e78aff8a 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -15,28 +15,12 @@ use std::iter; pub type RelateResult<'tcx, T> = Result<T, TypeError<'tcx>>; -#[derive(Clone, Debug)] -pub enum Cause { - ExistentialRegionBound, // relating an existential region bound -} - pub trait TypeRelation<'tcx>: Sized { fn tcx(&self) -> TyCtxt<'tcx>; /// Returns a static string we can use for printouts. fn tag(&self) -> &'static str; - /// Returns `true` if the value `a` is the "expected" type in the - /// relation. Just affects error messages. - fn a_is_expected(&self) -> bool; - - fn with_cause<F, R>(&mut self, _cause: Cause, f: F) -> R - where - F: FnOnce(&mut Self) -> R, - { - f(self) - } - /// Generic relation routine suitable for most anything. fn relate<T: Relate<'tcx>>(&mut self, a: T, b: T) -> RelateResult<'tcx, T> { Relate::relate(self, a, b) @@ -178,11 +162,7 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> { let tcx = relation.tcx(); if a.c_variadic != b.c_variadic { - return Err(TypeError::VariadicMismatch(expected_found( - relation, - a.c_variadic, - b.c_variadic, - ))); + return Err(TypeError::VariadicMismatch(expected_found(a.c_variadic, b.c_variadic))); } let unsafety = relation.relate(a.unsafety, b.unsafety)?; let abi = relation.relate(a.abi, b.abi)?; @@ -227,39 +207,31 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> { impl<'tcx> Relate<'tcx> for ty::BoundConstness { fn relate<R: TypeRelation<'tcx>>( - relation: &mut R, + _relation: &mut R, a: ty::BoundConstness, b: ty::BoundConstness, ) -> RelateResult<'tcx, ty::BoundConstness> { - if a != b { - Err(TypeError::ConstnessMismatch(expected_found(relation, a, b))) - } else { - Ok(a) - } + if a != b { Err(TypeError::ConstnessMismatch(expected_found(a, b))) } else { Ok(a) } } } impl<'tcx> Relate<'tcx> for hir::Unsafety { fn relate<R: TypeRelation<'tcx>>( - relation: &mut R, + _relation: &mut R, a: hir::Unsafety, b: hir::Unsafety, ) -> RelateResult<'tcx, hir::Unsafety> { - if a != b { - Err(TypeError::UnsafetyMismatch(expected_found(relation, a, b))) - } else { - Ok(a) - } + if a != b { Err(TypeError::UnsafetyMismatch(expected_found(a, b))) } else { Ok(a) } } } impl<'tcx> Relate<'tcx> for abi::Abi { fn relate<R: TypeRelation<'tcx>>( - relation: &mut R, + _relation: &mut R, a: abi::Abi, b: abi::Abi, ) -> RelateResult<'tcx, abi::Abi> { - if a == b { Ok(a) } else { Err(TypeError::AbiMismatch(expected_found(relation, a, b))) } + if a == b { Ok(a) } else { Err(TypeError::AbiMismatch(expected_found(a, b))) } } } @@ -270,7 +242,7 @@ impl<'tcx> Relate<'tcx> for ty::AliasTy<'tcx> { b: ty::AliasTy<'tcx>, ) -> RelateResult<'tcx, ty::AliasTy<'tcx>> { if a.def_id != b.def_id { - Err(TypeError::ProjectionMismatched(expected_found(relation, a.def_id, b.def_id))) + Err(TypeError::ProjectionMismatched(expected_found(a.def_id, b.def_id))) } else { let args = match relation.tcx().def_kind(a.def_id) { DefKind::OpaqueTy => relate_args_with_variances( @@ -298,7 +270,7 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialProjection<'tcx> { b: ty::ExistentialProjection<'tcx>, ) -> RelateResult<'tcx, ty::ExistentialProjection<'tcx>> { if a.def_id != b.def_id { - Err(TypeError::ProjectionMismatched(expected_found(relation, a.def_id, b.def_id))) + Err(TypeError::ProjectionMismatched(expected_found(a.def_id, b.def_id))) } else { let term = relation.relate_with_variance( ty::Invariant, @@ -325,7 +297,7 @@ impl<'tcx> Relate<'tcx> for ty::TraitRef<'tcx> { ) -> RelateResult<'tcx, ty::TraitRef<'tcx>> { // Different traits cannot be related. if a.def_id != b.def_id { - Err(TypeError::Traits(expected_found(relation, a.def_id, b.def_id))) + Err(TypeError::Traits(expected_found(a.def_id, b.def_id))) } else { let args = relate_args_invariantly(relation, a.args, b.args)?; Ok(ty::TraitRef::new(relation.tcx(), a.def_id, args)) @@ -341,7 +313,7 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialTraitRef<'tcx> { ) -> RelateResult<'tcx, ty::ExistentialTraitRef<'tcx>> { // Different traits cannot be related. if a.def_id != b.def_id { - Err(TypeError::Traits(expected_found(relation, a.def_id, b.def_id))) + Err(TypeError::Traits(expected_found(a.def_id, b.def_id))) } else { let args = relate_args_invariantly(relation, a.args, b.args)?; Ok(ty::ExistentialTraitRef { def_id: a.def_id, args }) @@ -452,10 +424,12 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>( (&ty::Dynamic(a_obj, a_region, a_repr), &ty::Dynamic(b_obj, b_region, b_repr)) if a_repr == b_repr => { - let region_bound = relation.with_cause(Cause::ExistentialRegionBound, |relation| { - relation.relate(a_region, b_region) - })?; - Ok(Ty::new_dynamic(tcx, relation.relate(a_obj, b_obj)?, region_bound, a_repr)) + Ok(Ty::new_dynamic( + tcx, + relation.relate(a_obj, b_obj)?, + relation.relate(a_region, b_region)?, + a_repr, + )) } (&ty::Coroutine(a_id, a_args), &ty::Coroutine(b_id, b_args)) if a_id == b_id => { @@ -515,9 +489,9 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>( let sz_b = sz_b.try_to_target_usize(tcx); match (sz_a, sz_b) { - (Some(sz_a_val), Some(sz_b_val)) if sz_a_val != sz_b_val => Err( - TypeError::FixedArraySize(expected_found(relation, sz_a_val, sz_b_val)), - ), + (Some(sz_a_val), Some(sz_b_val)) if sz_a_val != sz_b_val => { + Err(TypeError::FixedArraySize(expected_found(sz_a_val, sz_b_val))) + } _ => Err(err), } } @@ -536,9 +510,9 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>( iter::zip(as_, bs).map(|(a, b)| relation.relate(a, b)), )?) } else if !(as_.is_empty() || bs.is_empty()) { - Err(TypeError::TupleSize(expected_found(relation, as_.len(), bs.len()))) + Err(TypeError::TupleSize(expected_found(as_.len(), bs.len()))) } else { - Err(TypeError::Sorts(expected_found(relation, a, b))) + Err(TypeError::Sorts(expected_found(a, b))) } } @@ -559,7 +533,7 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>( Ok(Ty::new_alias(tcx, a_kind, alias_ty)) } - _ => Err(TypeError::Sorts(expected_found(relation, a, b))), + _ => Err(TypeError::Sorts(expected_found(a, b))), } } @@ -657,13 +631,13 @@ pub fn structurally_relate_consts<'tcx, R: TypeRelation<'tcx>>( let related_args = tcx.mk_const_list(&related_args); Expr::FunctionCall(func, related_args) } - _ => return Err(TypeError::ConstMismatch(expected_found(r, a, b))), + _ => return Err(TypeError::ConstMismatch(expected_found(a, b))), }; return Ok(ty::Const::new_expr(tcx, expr, a.ty())); } _ => false, }; - if is_match { Ok(a) } else { Err(TypeError::ConstMismatch(expected_found(relation, a, b))) } + if is_match { Ok(a) } else { Err(TypeError::ConstMismatch(expected_found(a, b))) } } impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> { @@ -685,7 +659,7 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> { b_v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder())); b_v.dedup(); if a_v.len() != b_v.len() { - return Err(TypeError::ExistentialMismatch(expected_found(relation, a, b))); + return Err(TypeError::ExistentialMismatch(expected_found(a, b))); } let v = iter::zip(a_v, b_v).map(|(ep_a, ep_b)| { @@ -697,7 +671,7 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> { relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(), ))), (AutoTrait(a), AutoTrait(b)) if a == b => Ok(ep_a.rebind(AutoTrait(a))), - _ => Err(TypeError::ExistentialMismatch(expected_found(relation, a, b))), + _ => Err(TypeError::ExistentialMismatch(expected_found(a, b))), } }); tcx.mk_poly_existential_predicates_from_iter(v) @@ -797,15 +771,11 @@ impl<'tcx> Relate<'tcx> for GenericArg<'tcx> { impl<'tcx> Relate<'tcx> for ty::ImplPolarity { fn relate<R: TypeRelation<'tcx>>( - relation: &mut R, + _relation: &mut R, a: ty::ImplPolarity, b: ty::ImplPolarity, ) -> RelateResult<'tcx, ty::ImplPolarity> { - if a != b { - Err(TypeError::PolarityMismatch(expected_found(relation, a, b))) - } else { - Ok(a) - } + if a != b { Err(TypeError::PolarityMismatch(expected_found(a, b))) } else { Ok(a) } } } @@ -839,9 +809,6 @@ impl<'tcx> Relate<'tcx> for Term<'tcx> { /////////////////////////////////////////////////////////////////////////// // Error handling -pub fn expected_found<'tcx, R, T>(relation: &mut R, a: T, b: T) -> ExpectedFound<T> -where - R: TypeRelation<'tcx>, -{ - ExpectedFound::new(relation.a_is_expected(), a, b) +pub fn expected_found<T>(a: T, b: T) -> ExpectedFound<T> { + ExpectedFound::new(true, a, b) } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 06be8191dc4..53690cc5811 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1580,8 +1580,10 @@ impl<'tcx> Ty<'tcx> { pub fn new_float(tcx: TyCtxt<'tcx>, f: ty::FloatTy) -> Ty<'tcx> { use ty::FloatTy::*; match f { + F16 => tcx.types.f16, F32 => tcx.types.f32, F64 => tcx.types.f64, + F128 => tcx.types.f128, } } @@ -2539,8 +2541,10 @@ impl<'tcx> Ty<'tcx> { ty::Bool => Some(sym::bool), ty::Char => Some(sym::char), ty::Float(f) => match f { + ty::FloatTy::F16 => Some(sym::f16), ty::FloatTy::F32 => Some(sym::f32), ty::FloatTy::F64 => Some(sym::f64), + ty::FloatTy::F128 => Some(sym::f128), }, ty::Int(f) => match f { ty::IntTy::Isize => Some(sym::isize), |
