Rollup merge of #60742 - varkor:fn-const-array-parameter, r=eddyb
Allow const parameters in array sizes to be unified Fixes https://github.com/rust-lang/rust/issues/60632. Fixes https://github.com/rust-lang/rust/issues/60744. Fixes https://github.com/rust-lang/rust/pull/60923. (The last commit should probably be viewed in isolation, as it just renames things from `type` to `kind`.) r? @eddyb
This commit is contained in:
commit
d85e256a87
@ -652,7 +652,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
for sp in prior_arms {
|
||||
err.span_label(*sp, format!(
|
||||
"this is found to be of type `{}`",
|
||||
self.resolve_type_vars_if_possible(&last_ty),
|
||||
self.resolve_vars_if_possible(&last_ty),
|
||||
));
|
||||
}
|
||||
} else if let Some(sp) = prior_arms.last() {
|
||||
@ -1278,7 +1278,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
&self,
|
||||
exp_found: &ty::error::ExpectedFound<Ty<'tcx>>,
|
||||
) -> Option<(DiagnosticStyledString, DiagnosticStyledString)> {
|
||||
let exp_found = self.resolve_type_vars_if_possible(exp_found);
|
||||
let exp_found = self.resolve_vars_if_possible(exp_found);
|
||||
if exp_found.references_error() {
|
||||
return None;
|
||||
}
|
||||
@ -1291,7 +1291,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
&self,
|
||||
exp_found: &ty::error::ExpectedFound<T>,
|
||||
) -> Option<(DiagnosticStyledString, DiagnosticStyledString)> {
|
||||
let exp_found = self.resolve_type_vars_if_possible(exp_found);
|
||||
let exp_found = self.resolve_vars_if_possible(exp_found);
|
||||
if exp_found.references_error() {
|
||||
return None;
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ impl<'a, 'gcx, 'tcx> FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
|
||||
});
|
||||
match ty_opt {
|
||||
Some(ty) => {
|
||||
let ty = self.infcx.resolve_type_vars_if_possible(&ty);
|
||||
let ty = self.infcx.resolve_vars_if_possible(&ty);
|
||||
ty.walk().any(|inner_ty| {
|
||||
inner_ty == self.target_ty || match (&inner_ty.sty, &self.target_ty.sty) {
|
||||
(&Infer(TyVar(a_vid)), &Infer(TyVar(b_vid))) => {
|
||||
@ -94,7 +94,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
span: Span,
|
||||
ty: Ty<'tcx>
|
||||
) -> DiagnosticBuilder<'gcx> {
|
||||
let ty = self.resolve_type_vars_if_possible(&ty);
|
||||
let ty = self.resolve_vars_if_possible(&ty);
|
||||
let name = self.extract_type_name(&ty, None);
|
||||
|
||||
let mut err_span = span;
|
||||
@ -166,7 +166,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
span: Span,
|
||||
ty: Ty<'tcx>
|
||||
) -> DiagnosticBuilder<'gcx> {
|
||||
let ty = self.resolve_type_vars_if_possible(&ty);
|
||||
let ty = self.resolve_vars_if_possible(&ty);
|
||||
let name = self.extract_type_name(&ty, None);
|
||||
|
||||
let mut err = struct_span_err!(self.tcx.sess,
|
||||
|
@ -210,11 +210,11 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
|
||||
_ => (),
|
||||
}
|
||||
|
||||
let expected_trait_ref = self.infcx.resolve_type_vars_if_possible(&ty::TraitRef {
|
||||
let expected_trait_ref = self.infcx.resolve_vars_if_possible(&ty::TraitRef {
|
||||
def_id: trait_def_id,
|
||||
substs: expected_substs,
|
||||
});
|
||||
let actual_trait_ref = self.infcx.resolve_type_vars_if_possible(&ty::TraitRef {
|
||||
let actual_trait_ref = self.infcx.resolve_vars_if_possible(&ty::TraitRef {
|
||||
def_id: trait_def_id,
|
||||
substs: actual_substs,
|
||||
});
|
||||
|
@ -74,7 +74,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
let (mut fudger, value) = self.probe(|snapshot| {
|
||||
match f() {
|
||||
Ok(value) => {
|
||||
let value = self.resolve_type_vars_if_possible(&value);
|
||||
let value = self.resolve_vars_if_possible(&value);
|
||||
|
||||
// At this point, `value` could in principle refer
|
||||
// to inference variables that have been created during
|
||||
|
@ -1174,7 +1174,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
/// Process the region constraints and report any errors that
|
||||
/// result. After this, no more unification operations should be
|
||||
/// done -- or the compiler will panic -- but it is legal to use
|
||||
/// `resolve_type_vars_if_possible` as well as `fully_resolve`.
|
||||
/// `resolve_vars_if_possible` as well as `fully_resolve`.
|
||||
pub fn resolve_regions_and_report_errors(
|
||||
&self,
|
||||
region_context: DefId,
|
||||
@ -1262,7 +1262,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn ty_to_string(&self, t: Ty<'tcx>) -> String {
|
||||
self.resolve_type_vars_if_possible(&t).to_string()
|
||||
self.resolve_vars_if_possible(&t).to_string()
|
||||
}
|
||||
|
||||
pub fn tys_to_string(&self, ts: &[Ty<'tcx>]) -> String {
|
||||
@ -1271,7 +1271,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn trait_ref_to_string(&self, t: &ty::TraitRef<'tcx>) -> String {
|
||||
self.resolve_type_vars_if_possible(t).to_string()
|
||||
self.resolve_vars_if_possible(t).to_string()
|
||||
}
|
||||
|
||||
/// If `TyVar(vid)` resolves to a type, return that type. Else, return the
|
||||
@ -1297,20 +1297,20 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
self.type_variables.borrow_mut().root_var(var)
|
||||
}
|
||||
|
||||
/// Where possible, replaces type/int/float variables in
|
||||
/// Where possible, replaces type/const variables in
|
||||
/// `value` with their final value. Note that region variables
|
||||
/// are unaffected. If a type variable has not been unified, it
|
||||
/// are unaffected. If a type/const variable has not been unified, it
|
||||
/// is left as is. This is an idempotent operation that does
|
||||
/// not affect inference state in any way and so you can do it
|
||||
/// at will.
|
||||
pub fn resolve_type_vars_if_possible<T>(&self, value: &T) -> T
|
||||
pub fn resolve_vars_if_possible<T>(&self, value: &T) -> T
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
if !value.needs_infer() {
|
||||
return value.clone(); // avoid duplicated subst-folding
|
||||
}
|
||||
let mut r = resolve::OpportunisticTypeResolver::new(self);
|
||||
let mut r = resolve::OpportunisticVarResolver::new(self);
|
||||
value.fold_with(&mut r)
|
||||
}
|
||||
|
||||
@ -1318,7 +1318,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
/// process of visiting `T`, this will resolve (where possible)
|
||||
/// type variables in `T`, but it never constructs the final,
|
||||
/// resolved type, so it's more efficient than
|
||||
/// `resolve_type_vars_if_possible()`.
|
||||
/// `resolve_vars_if_possible()`.
|
||||
pub fn unresolved_type_vars<T>(&self, value: &T) -> Option<(Ty<'tcx>, Option<Span>)>
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
@ -1389,7 +1389,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
where
|
||||
M: FnOnce(String) -> DiagnosticBuilder<'tcx>,
|
||||
{
|
||||
let actual_ty = self.resolve_type_vars_if_possible(&actual_ty);
|
||||
let actual_ty = self.resolve_vars_if_possible(&actual_ty);
|
||||
debug!("type_error_struct_with_diag({:?}, {:?})", sp, actual_ty);
|
||||
|
||||
// Don't report an error if actual type is `Error`.
|
||||
@ -1446,7 +1446,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
ty: Ty<'tcx>,
|
||||
span: Span,
|
||||
) -> bool {
|
||||
let ty = self.resolve_type_vars_if_possible(&ty);
|
||||
let ty = self.resolve_vars_if_possible(&ty);
|
||||
|
||||
// Even if the type may have no inference variables, during
|
||||
// type-checking closure types are in local tables only.
|
||||
|
@ -286,7 +286,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
let tcx = self.tcx;
|
||||
|
||||
let concrete_ty = self.resolve_type_vars_if_possible(&opaque_defn.concrete_ty);
|
||||
let concrete_ty = self.resolve_vars_if_possible(&opaque_defn.concrete_ty);
|
||||
|
||||
debug!("constrain_opaque_type: concrete_ty={:?}", concrete_ty);
|
||||
|
||||
|
@ -168,7 +168,7 @@ impl<'a, 'gcx: 'tcx, 'tcx: 'a> OutlivesEnvironment<'tcx> {
|
||||
debug!("add_implied_bounds()");
|
||||
|
||||
for &ty in fn_sig_tys {
|
||||
let ty = infcx.resolve_type_vars_if_possible(&ty);
|
||||
let ty = infcx.resolve_vars_if_possible(&ty);
|
||||
debug!("add_implied_bounds: ty = {}", ty);
|
||||
let implied_bounds = infcx.implied_outlives_bounds(self.param_env, body_id, ty, span);
|
||||
self.add_outlives_bounds(Some(infcx), implied_bounds)
|
||||
|
@ -177,7 +177,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
||||
sup_type, sub_region, origin
|
||||
);
|
||||
|
||||
let sup_type = self.resolve_type_vars_if_possible(&sup_type);
|
||||
let sup_type = self.resolve_vars_if_possible(&sup_type);
|
||||
|
||||
if let Some(region_bound_pairs) = region_bound_pairs_map.get(&body_id) {
|
||||
let outlives = &mut TypeOutlives::new(
|
||||
@ -215,7 +215,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
||||
implicit_region_bound,
|
||||
param_env,
|
||||
);
|
||||
let ty = self.resolve_type_vars_if_possible(&ty);
|
||||
let ty = self.resolve_vars_if_possible(&ty);
|
||||
outlives.type_must_outlive(origin, ty, region);
|
||||
}
|
||||
}
|
||||
|
@ -1,28 +1,28 @@
|
||||
use super::{InferCtxt, FixupError, FixupResult, Span, type_variable::TypeVariableOrigin};
|
||||
use crate::mir::interpret::ConstValue;
|
||||
use crate::ty::{self, Ty, TyCtxt, TypeFoldable, InferConst};
|
||||
use crate::ty::{self, Ty, Const, TyCtxt, TypeFoldable, InferConst, TypeFlags};
|
||||
use crate::ty::fold::{TypeFolder, TypeVisitor};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// OPPORTUNISTIC TYPE RESOLVER
|
||||
// OPPORTUNISTIC VAR RESOLVER
|
||||
|
||||
/// The opportunistic type resolver can be used at any time. It simply replaces
|
||||
/// type variables that have been unified with the things they have
|
||||
/// The opportunistic resolver can be used at any time. It simply replaces
|
||||
/// type/const variables that have been unified with the things they have
|
||||
/// been unified with (similar to `shallow_resolve`, but deep). This is
|
||||
/// useful for printing messages etc but also required at various
|
||||
/// points for correctness.
|
||||
pub struct OpportunisticTypeResolver<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||
pub struct OpportunisticVarResolver<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> OpportunisticTypeResolver<'a, 'gcx, 'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> OpportunisticVarResolver<'a, 'gcx, 'tcx> {
|
||||
#[inline]
|
||||
pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>) -> Self {
|
||||
OpportunisticTypeResolver { infcx }
|
||||
OpportunisticVarResolver { infcx }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticTypeResolver<'a, 'gcx, 'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticVarResolver<'a, 'gcx, 'tcx> {
|
||||
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
@ -31,8 +31,17 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticTypeResolver<'a, 'g
|
||||
if !t.has_infer_types() {
|
||||
t // micro-optimize -- if there is nothing in this type that this fold affects...
|
||||
} else {
|
||||
let t0 = self.infcx.shallow_resolve(t);
|
||||
t0.super_fold_with(self)
|
||||
let t = self.infcx.shallow_resolve(t);
|
||||
t.super_fold_with(self)
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, ct: &'tcx Const<'tcx>) -> &'tcx Const<'tcx> {
|
||||
if !ct.has_type_flags(TypeFlags::HAS_CT_INFER) {
|
||||
ct // micro-optimize -- if there is nothing in this const that this fold affects...
|
||||
} else {
|
||||
let ct = self.infcx.shallow_resolve(ct);
|
||||
ct.super_fold_with(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -458,10 +458,10 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||
.unwrap_or(true)
|
||||
}
|
||||
|
||||
fn resolve_type_vars_if_possible<T>(&self, value: &T) -> T
|
||||
fn resolve_vars_if_possible<T>(&self, value: &T) -> T
|
||||
where T: TypeFoldable<'tcx>
|
||||
{
|
||||
self.infcx.map(|infcx| infcx.resolve_type_vars_if_possible(value))
|
||||
self.infcx.map(|infcx| infcx.resolve_vars_if_possible(value))
|
||||
.unwrap_or_else(|| value.clone())
|
||||
}
|
||||
|
||||
@ -475,7 +475,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||
-> McResult<Ty<'tcx>> {
|
||||
match ty {
|
||||
Some(ty) => {
|
||||
let ty = self.resolve_type_vars_if_possible(&ty);
|
||||
let ty = self.resolve_vars_if_possible(&ty);
|
||||
if ty.references_error() || ty.is_ty_var() {
|
||||
debug!("resolve_type_vars_or_error: error from {:?}", ty);
|
||||
Err(())
|
||||
@ -602,7 +602,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||
where F: FnOnce() -> McResult<cmt_<'tcx>>
|
||||
{
|
||||
debug!("cat_expr_adjusted_with({:?}): {:?}", adjustment, expr);
|
||||
let target = self.resolve_type_vars_if_possible(&adjustment.target);
|
||||
let target = self.resolve_vars_if_possible(&adjustment.target);
|
||||
match adjustment.kind {
|
||||
adjustment::Adjust::Deref(overloaded) => {
|
||||
// Equivalent to *expr or something similar.
|
||||
|
@ -307,9 +307,9 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Call infcx.resolve_type_vars_if_possible to see if we can
|
||||
// Call infcx.resolve_vars_if_possible to see if we can
|
||||
// get rid of any inference variables.
|
||||
let obligation = infcx.resolve_type_vars_if_possible(
|
||||
let obligation = infcx.resolve_vars_if_possible(
|
||||
&Obligation::new(dummy_cause.clone(), new_env, pred)
|
||||
);
|
||||
let result = select.select(&obligation);
|
||||
@ -642,7 +642,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
|
||||
fresh_preds.insert(self.clean_pred(select.infcx(), predicate));
|
||||
|
||||
// Resolve any inference variables that we can, to help selection succeed
|
||||
predicate = select.infcx().resolve_type_vars_if_possible(&predicate);
|
||||
predicate = select.infcx().resolve_vars_if_possible(&predicate);
|
||||
|
||||
// We only add a predicate as a user-displayable bound if
|
||||
// it involves a generic parameter, and doesn't contain
|
||||
|
@ -33,7 +33,7 @@ fn in_environment(
|
||||
obligation: PredicateObligation<'tcx>
|
||||
) -> InEnvironment<'tcx, PredicateObligation<'tcx>> {
|
||||
assert!(!infcx.is_in_snapshot());
|
||||
let obligation = infcx.resolve_type_vars_if_possible(&obligation);
|
||||
let obligation = infcx.resolve_vars_if_possible(&obligation);
|
||||
|
||||
let environment = match obligation.param_env.def_id {
|
||||
Some(def_id) => infcx.tcx.environment(def_id),
|
||||
|
@ -153,11 +153,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
bug!("Encountered errors `{:?}` resolving bounds after type-checking", errors);
|
||||
}
|
||||
|
||||
let result = self.resolve_type_vars_if_possible(result);
|
||||
let result = self.resolve_vars_if_possible(result);
|
||||
let result = self.tcx.erase_regions(&result);
|
||||
|
||||
self.tcx.lift_to_global(&result).unwrap_or_else(||
|
||||
bug!("Uninferred types/regions in `{:?}`", result)
|
||||
bug!("Uninferred types/regions/consts in `{:?}`", result)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ fn overlap_within_probe(
|
||||
a_impl_header.predicates
|
||||
.iter()
|
||||
.chain(&b_impl_header.predicates)
|
||||
.map(|p| infcx.resolve_type_vars_if_possible(p))
|
||||
.map(|p| infcx.resolve_vars_if_possible(p))
|
||||
.map(|p| Obligation { cause: ObligationCause::dummy(),
|
||||
param_env,
|
||||
recursion_depth: 0,
|
||||
@ -171,7 +171,7 @@ fn overlap_within_probe(
|
||||
return None
|
||||
}
|
||||
|
||||
let impl_header = selcx.infcx().resolve_type_vars_if_possible(&a_impl_header);
|
||||
let impl_header = selcx.infcx().resolve_vars_if_possible(&a_impl_header);
|
||||
let intercrate_ambiguity_causes = selcx.take_intercrate_ambiguity_causes();
|
||||
debug!("overlap: intercrate_ambiguity_causes={:#?}", intercrate_ambiguity_causes);
|
||||
|
||||
|
@ -186,7 +186,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
error: &MismatchedProjectionTypes<'tcx>)
|
||||
{
|
||||
let predicate =
|
||||
self.resolve_type_vars_if_possible(&obligation.predicate);
|
||||
self.resolve_vars_if_possible(&obligation.predicate);
|
||||
|
||||
if predicate.references_error() {
|
||||
return
|
||||
@ -531,7 +531,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
where T: fmt::Display + TypeFoldable<'tcx>
|
||||
{
|
||||
let predicate =
|
||||
self.resolve_type_vars_if_possible(&obligation.predicate);
|
||||
self.resolve_vars_if_possible(&obligation.predicate);
|
||||
let mut err = struct_span_err!(self.tcx.sess, obligation.cause.span, E0275,
|
||||
"overflow evaluating the requirement `{}`",
|
||||
predicate);
|
||||
@ -553,7 +553,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
/// we do not suggest increasing the overflow limit, which is not
|
||||
/// going to help).
|
||||
pub fn report_overflow_error_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> ! {
|
||||
let cycle = self.resolve_type_vars_if_possible(&cycle.to_owned());
|
||||
let cycle = self.resolve_vars_if_possible(&cycle.to_owned());
|
||||
assert!(cycle.len() > 0);
|
||||
|
||||
debug!("report_overflow_error_cycle: cycle={:?}", cycle);
|
||||
@ -589,7 +589,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
fn get_parent_trait_ref(&self, code: &ObligationCauseCode<'tcx>) -> Option<String> {
|
||||
match code {
|
||||
&ObligationCauseCode::BuiltinDerivedObligation(ref data) => {
|
||||
let parent_trait_ref = self.resolve_type_vars_if_possible(
|
||||
let parent_trait_ref = self.resolve_vars_if_possible(
|
||||
&data.parent_trait_ref);
|
||||
match self.get_parent_trait_ref(&data.parent_code) {
|
||||
Some(t) => Some(t),
|
||||
@ -625,7 +625,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
match obligation.predicate {
|
||||
ty::Predicate::Trait(ref trait_predicate) => {
|
||||
let trait_predicate =
|
||||
self.resolve_type_vars_if_possible(trait_predicate);
|
||||
self.resolve_vars_if_possible(trait_predicate);
|
||||
|
||||
if self.tcx.sess.has_errors() && trait_predicate.references_error() {
|
||||
return;
|
||||
@ -749,7 +749,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
ty::Predicate::RegionOutlives(ref predicate) => {
|
||||
let predicate = self.resolve_type_vars_if_possible(predicate);
|
||||
let predicate = self.resolve_vars_if_possible(predicate);
|
||||
let err = self.region_outlives_predicate(&obligation.cause,
|
||||
&predicate).err().unwrap();
|
||||
struct_span_err!(
|
||||
@ -761,7 +761,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
ty::Predicate::Projection(..) | ty::Predicate::TypeOutlives(..) => {
|
||||
let predicate =
|
||||
self.resolve_type_vars_if_possible(&obligation.predicate);
|
||||
self.resolve_vars_if_possible(&obligation.predicate);
|
||||
struct_span_err!(self.tcx.sess, span, E0280,
|
||||
"the requirement `{}` is not satisfied",
|
||||
predicate)
|
||||
@ -852,8 +852,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
OutputTypeParameterMismatch(ref found_trait_ref, ref expected_trait_ref, _) => {
|
||||
let found_trait_ref = self.resolve_type_vars_if_possible(&*found_trait_ref);
|
||||
let expected_trait_ref = self.resolve_type_vars_if_possible(&*expected_trait_ref);
|
||||
let found_trait_ref = self.resolve_vars_if_possible(&*found_trait_ref);
|
||||
let expected_trait_ref = self.resolve_vars_if_possible(&*expected_trait_ref);
|
||||
|
||||
if expected_trait_ref.self_ty().references_error() {
|
||||
return;
|
||||
@ -1345,7 +1345,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
// ambiguous impls. The latter *ought* to be a
|
||||
// coherence violation, so we don't report it here.
|
||||
|
||||
let predicate = self.resolve_type_vars_if_possible(&obligation.predicate);
|
||||
let predicate = self.resolve_vars_if_possible(&obligation.predicate);
|
||||
let span = obligation.cause.span;
|
||||
|
||||
debug!("maybe_report_ambiguity(predicate={:?}, obligation={:?})",
|
||||
@ -1617,7 +1617,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
err.note("shared static variables must have a type that implements `Sync`");
|
||||
}
|
||||
ObligationCauseCode::BuiltinDerivedObligation(ref data) => {
|
||||
let parent_trait_ref = self.resolve_type_vars_if_possible(&data.parent_trait_ref);
|
||||
let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref);
|
||||
let ty = parent_trait_ref.skip_binder().self_ty();
|
||||
err.note(&format!("required because it appears within the type `{}`", ty));
|
||||
obligated_types.push(ty);
|
||||
@ -1631,7 +1631,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
ObligationCauseCode::ImplDerivedObligation(ref data) => {
|
||||
let parent_trait_ref = self.resolve_type_vars_if_possible(&data.parent_trait_ref);
|
||||
let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref);
|
||||
err.note(
|
||||
&format!("required because of the requirements on the impl of `{}` for `{}`",
|
||||
parent_trait_ref,
|
||||
@ -1672,7 +1672,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
obligated_types: &mut Vec<&ty::TyS<'tcx>>,
|
||||
cause_code: &ObligationCauseCode<'tcx>) -> bool {
|
||||
if let ObligationCauseCode::BuiltinDerivedObligation(ref data) = cause_code {
|
||||
let parent_trait_ref = self.resolve_type_vars_if_possible(&data.parent_trait_ref);
|
||||
let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref);
|
||||
|
||||
if obligated_types.iter().any(|ot| ot == &parent_trait_ref.skip_binder().self_ty()) {
|
||||
return true;
|
||||
|
@ -178,7 +178,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
|
||||
{
|
||||
// this helps to reduce duplicate errors, as well as making
|
||||
// debug output much nicer to read and so on.
|
||||
let obligation = infcx.resolve_type_vars_if_possible(&obligation);
|
||||
let obligation = infcx.resolve_vars_if_possible(&obligation);
|
||||
|
||||
debug!("register_predicate_obligation(obligation={:?})", obligation);
|
||||
|
||||
@ -261,7 +261,7 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx,
|
||||
}) {
|
||||
debug!("process_predicate: pending obligation {:?} still stalled on {:?}",
|
||||
self.selcx.infcx()
|
||||
.resolve_type_vars_if_possible(&pending_obligation.obligation),
|
||||
.resolve_vars_if_possible(&pending_obligation.obligation),
|
||||
pending_obligation.stalled_on);
|
||||
return ProcessResult::Unchanged;
|
||||
}
|
||||
@ -272,7 +272,7 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx,
|
||||
|
||||
if obligation.predicate.has_infer_types() {
|
||||
obligation.predicate =
|
||||
self.selcx.infcx().resolve_type_vars_if_possible(&obligation.predicate);
|
||||
self.selcx.infcx().resolve_vars_if_possible(&obligation.predicate);
|
||||
}
|
||||
|
||||
debug!("process_obligation: obligation = {:?}", obligation);
|
||||
@ -318,7 +318,7 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx,
|
||||
trait_ref_type_vars(self.selcx, data.to_poly_trait_ref());
|
||||
|
||||
debug!("process_predicate: pending obligation {:?} now stalled on {:?}",
|
||||
self.selcx.infcx().resolve_type_vars_if_possible(obligation),
|
||||
self.selcx.infcx().resolve_vars_if_possible(obligation),
|
||||
pending_obligation.stalled_on);
|
||||
|
||||
ProcessResult::Unchanged
|
||||
@ -519,7 +519,7 @@ fn trait_ref_type_vars<'a, 'gcx, 'tcx>(selcx: &mut SelectionContext<'a, 'gcx, 't
|
||||
{
|
||||
t.skip_binder() // ok b/c this check doesn't care about regions
|
||||
.input_types()
|
||||
.map(|t| selcx.infcx().resolve_type_vars_if_possible(&t))
|
||||
.map(|t| selcx.infcx().resolve_vars_if_possible(&t))
|
||||
.filter(|t| t.has_infer_types())
|
||||
.flat_map(|t| t.walk())
|
||||
.filter(|t| match t.sty { ty::Infer(_) => true, _ => false })
|
||||
|
@ -927,7 +927,7 @@ pub fn fully_normalize<'a, 'gcx, 'tcx, T>(
|
||||
debug!("fully_normalize: select_all_or_error start");
|
||||
fulfill_cx.select_all_or_error(infcx)?;
|
||||
debug!("fully_normalize: select_all_or_error complete");
|
||||
let resolved_value = infcx.resolve_type_vars_if_possible(&normalized_value);
|
||||
let resolved_value = infcx.resolve_vars_if_possible(&normalized_value);
|
||||
debug!("fully_normalize: resolved_value={:?}", resolved_value);
|
||||
Ok(resolved_value)
|
||||
}
|
||||
|
@ -312,7 +312,7 @@ impl<'a, 'b, 'gcx, 'tcx> AssocTypeNormalizer<'a, 'b, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
fn fold<T:TypeFoldable<'tcx>>(&mut self, value: &T) -> T {
|
||||
let value = self.selcx.infcx().resolve_type_vars_if_possible(value);
|
||||
let value = self.selcx.infcx().resolve_vars_if_possible(value);
|
||||
|
||||
if !value.has_projections() {
|
||||
value
|
||||
@ -508,7 +508,7 @@ fn opt_normalize_projection_type<'a, 'b, 'gcx, 'tcx>(
|
||||
{
|
||||
let infcx = selcx.infcx();
|
||||
|
||||
let projection_ty = infcx.resolve_type_vars_if_possible(&projection_ty);
|
||||
let projection_ty = infcx.resolve_vars_if_possible(&projection_ty);
|
||||
let cache_key = ProjectionCacheKey { ty: projection_ty };
|
||||
|
||||
debug!("opt_normalize_projection_type(\
|
||||
@ -1614,7 +1614,7 @@ impl<'cx, 'gcx, 'tcx> ProjectionCacheKey<'tcx> {
|
||||
// from a specific call to `opt_normalize_projection_type` - if
|
||||
// there's no precise match, the original cache entry is "stranded"
|
||||
// anyway.
|
||||
ty: infcx.resolve_type_vars_if_possible(&predicate.projection_ty)
|
||||
ty: infcx.resolve_vars_if_possible(&predicate.projection_ty)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> {
|
||||
&orig_values,
|
||||
result)
|
||||
{
|
||||
let ty = self.infcx.resolve_type_vars_if_possible(&ty);
|
||||
let ty = self.infcx.resolve_vars_if_possible(&ty);
|
||||
let kinds = value.into_kinds_reporting_overflows(tcx, span, ty);
|
||||
return InferOk {
|
||||
value: kinds,
|
||||
|
@ -97,7 +97,7 @@ fn scrape_region_constraints<'gcx, 'tcx, R>(
|
||||
region_obligations
|
||||
.iter()
|
||||
.map(|(_, r_o)| (r_o.sup_type, r_o.sub_region))
|
||||
.map(|(ty, r)| (infcx.resolve_type_vars_if_possible(&ty), r)),
|
||||
.map(|(ty, r)| (infcx.resolve_vars_if_possible(&ty), r)),
|
||||
®ion_constraint_data,
|
||||
);
|
||||
|
||||
|
@ -1463,7 +1463,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
|
||||
let obligation = &stack.obligation;
|
||||
let predicate = self.infcx()
|
||||
.resolve_type_vars_if_possible(&obligation.predicate);
|
||||
.resolve_vars_if_possible(&obligation.predicate);
|
||||
|
||||
// OK to skip binder because of the nature of the
|
||||
// trait-ref-is-knowable check, which does not care about
|
||||
@ -1621,7 +1621,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
cause: obligation.cause.clone(),
|
||||
recursion_depth: obligation.recursion_depth,
|
||||
predicate: self.infcx()
|
||||
.resolve_type_vars_if_possible(&obligation.predicate),
|
||||
.resolve_vars_if_possible(&obligation.predicate),
|
||||
};
|
||||
|
||||
if obligation.predicate.skip_binder().self_ty().is_ty_var() {
|
||||
@ -1737,7 +1737,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
snapshot: &CombinedSnapshot<'_, 'tcx>,
|
||||
) -> bool {
|
||||
let poly_trait_predicate = self.infcx()
|
||||
.resolve_type_vars_if_possible(&obligation.predicate);
|
||||
.resolve_vars_if_possible(&obligation.predicate);
|
||||
let (placeholder_trait_predicate, placeholder_map) = self.infcx()
|
||||
.replace_bound_vars_with_placeholders(&poly_trait_predicate);
|
||||
debug!(
|
||||
|
@ -278,7 +278,7 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
||||
|
||||
// Now resolve the *substitution* we built for the target earlier, replacing
|
||||
// the inference variables inside with whatever we got from fulfillment.
|
||||
Ok(infcx.resolve_type_vars_if_possible(&target_substs))
|
||||
Ok(infcx.resolve_vars_if_possible(&target_substs))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -80,6 +80,12 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
|
||||
}
|
||||
};
|
||||
|
||||
macro_rules! pluralise {
|
||||
($x:expr) => {
|
||||
if $x != 1 { "s" } else { "" }
|
||||
};
|
||||
}
|
||||
|
||||
match *self {
|
||||
CyclicTy(_) => write!(f, "cyclic type of infinite size"),
|
||||
Mismatch => write!(f, "types differ"),
|
||||
@ -94,17 +100,21 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
|
||||
values.found)
|
||||
}
|
||||
Mutability => write!(f, "types differ in mutability"),
|
||||
FixedArraySize(values) => {
|
||||
write!(f, "expected an array with a fixed size of {} elements, \
|
||||
found one with {} elements",
|
||||
values.expected,
|
||||
values.found)
|
||||
}
|
||||
TupleSize(values) => {
|
||||
write!(f, "expected a tuple with {} elements, \
|
||||
found one with {} elements",
|
||||
write!(f, "expected a tuple with {} element{}, \
|
||||
found one with {} element{}",
|
||||
values.expected,
|
||||
values.found)
|
||||
pluralise!(values.expected),
|
||||
values.found,
|
||||
pluralise!(values.found))
|
||||
}
|
||||
FixedArraySize(values) => {
|
||||
write!(f, "expected an array with a fixed size of {} element{}, \
|
||||
found one with {} element{}",
|
||||
values.expected,
|
||||
pluralise!(values.expected),
|
||||
values.found,
|
||||
pluralise!(values.found))
|
||||
}
|
||||
ArgCount => {
|
||||
write!(f, "incorrect number of function parameters")
|
||||
@ -157,8 +167,9 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
|
||||
tcx.def_path_str(values.found))
|
||||
}),
|
||||
ProjectionBoundsLength(ref values) => {
|
||||
write!(f, "expected {} associated type bindings, found {}",
|
||||
write!(f, "expected {} associated type binding{}, found {}",
|
||||
values.expected,
|
||||
pluralise!(values.expected),
|
||||
values.found)
|
||||
},
|
||||
ExistentialMismatch(ref values) => {
|
||||
@ -166,7 +177,7 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
|
||||
&format!("trait `{}`", values.found))
|
||||
}
|
||||
ConstMismatch(ref values) => {
|
||||
write!(f, "expected `{:?}`, found `{:?}`", values.expected, values.found)
|
||||
write!(f, "expected `{}`, found `{}`", values.expected, values.found)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,9 +8,7 @@ use crate::hir::def_id::DefId;
|
||||
use crate::ty::subst::{Kind, UnpackedKind, SubstsRef};
|
||||
use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||
use crate::ty::error::{ExpectedFound, TypeError};
|
||||
use crate::mir::interpret::{GlobalId, ConstValue, Scalar};
|
||||
use crate::util::common::ErrorReported;
|
||||
use syntax_pos::DUMMY_SP;
|
||||
use crate::mir::interpret::{ConstValue, Scalar, GlobalId};
|
||||
use std::rc::Rc;
|
||||
use std::iter;
|
||||
use rustc_target::spec::abi;
|
||||
@ -474,55 +472,19 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
|
||||
(&ty::Array(a_t, sz_a), &ty::Array(b_t, sz_b)) =>
|
||||
{
|
||||
let t = relation.relate(&a_t, &b_t)?;
|
||||
let to_u64 = |x: ty::Const<'tcx>| -> Result<u64, ErrorReported> {
|
||||
match x.val {
|
||||
// FIXME(const_generics): this doesn't work right now,
|
||||
// because it tries to relate an `Infer` to a `Param`.
|
||||
ConstValue::Unevaluated(def_id, substs) => {
|
||||
// FIXME(eddyb) get the right param_env.
|
||||
let param_env = ty::ParamEnv::empty();
|
||||
if let Some(substs) = tcx.lift_to_global(&substs) {
|
||||
let instance = ty::Instance::resolve(
|
||||
tcx.global_tcx(),
|
||||
param_env,
|
||||
def_id,
|
||||
substs,
|
||||
);
|
||||
if let Some(instance) = instance {
|
||||
let cid = GlobalId {
|
||||
instance,
|
||||
promoted: None,
|
||||
};
|
||||
if let Some(s) = tcx.const_eval(param_env.and(cid))
|
||||
.ok()
|
||||
.map(|c| c.unwrap_usize(tcx)) {
|
||||
return Ok(s)
|
||||
}
|
||||
}
|
||||
match relation.relate(&sz_a, &sz_b) {
|
||||
Ok(sz) => Ok(tcx.mk_ty(ty::Array(t, sz))),
|
||||
Err(err) => {
|
||||
// Check whether the lengths are both concrete/known values,
|
||||
// but are unequal, for better diagnostics.
|
||||
match (sz_a.assert_usize(tcx), sz_b.assert_usize(tcx)) {
|
||||
(Some(sz_a_val), Some(sz_b_val)) => {
|
||||
Err(TypeError::FixedArraySize(
|
||||
expected_found(relation, &sz_a_val, &sz_b_val)
|
||||
))
|
||||
}
|
||||
tcx.sess.delay_span_bug(tcx.def_span(def_id),
|
||||
"array length could not be evaluated");
|
||||
Err(ErrorReported)
|
||||
_ => return Err(err),
|
||||
}
|
||||
_ => x.assert_usize(tcx).ok_or_else(|| {
|
||||
tcx.sess.delay_span_bug(DUMMY_SP,
|
||||
"array length could not be evaluated");
|
||||
ErrorReported
|
||||
})
|
||||
}
|
||||
};
|
||||
match (to_u64(*sz_a), to_u64(*sz_b)) {
|
||||
(Ok(sz_a_u64), Ok(sz_b_u64)) => {
|
||||
if sz_a_u64 == sz_b_u64 {
|
||||
Ok(tcx.mk_ty(ty::Array(t, sz_a)))
|
||||
} else {
|
||||
Err(TypeError::FixedArraySize(
|
||||
expected_found(relation, &sz_a_u64, &sz_b_u64)))
|
||||
}
|
||||
}
|
||||
// We reported an error or will ICE, so we can return Error.
|
||||
(Err(ErrorReported), _) | (_, Err(ErrorReported)) => {
|
||||
Ok(tcx.types.err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -598,11 +560,36 @@ where
|
||||
{
|
||||
let tcx = relation.tcx();
|
||||
|
||||
let eagerly_eval = |x: &'tcx ty::Const<'tcx>| {
|
||||
if let ConstValue::Unevaluated(def_id, substs) = x.val {
|
||||
// FIXME(eddyb) get the right param_env.
|
||||
let param_env = ty::ParamEnv::empty();
|
||||
if let Some(substs) = tcx.lift_to_global(&substs) {
|
||||
let instance = ty::Instance::resolve(
|
||||
tcx.global_tcx(),
|
||||
param_env,
|
||||
def_id,
|
||||
substs,
|
||||
);
|
||||
if let Some(instance) = instance {
|
||||
let cid = GlobalId {
|
||||
instance,
|
||||
promoted: None,
|
||||
};
|
||||
if let Ok(ct) = tcx.const_eval(param_env.and(cid)) {
|
||||
return ct.val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
x.val
|
||||
};
|
||||
|
||||
// Currently, the values that can be unified are those that
|
||||
// implement both `PartialEq` and `Eq`, corresponding to
|
||||
// `structural_match` types.
|
||||
// FIXME(const_generics): check for `structural_match` synthetic attribute.
|
||||
match (a.val, b.val) {
|
||||
match (eagerly_eval(a), eagerly_eval(b)) {
|
||||
(ConstValue::Infer(_), _) | (_, ConstValue::Infer(_)) => {
|
||||
// The caller should handle these cases!
|
||||
bug!("var types encountered in super_relate_consts: {:?} {:?}", a, b)
|
||||
@ -613,8 +600,13 @@ where
|
||||
(ConstValue::Placeholder(p1), ConstValue::Placeholder(p2)) if p1 == p2 => {
|
||||
Ok(a)
|
||||
}
|
||||
(ConstValue::Scalar(Scalar::Raw { .. }), _) if a == b => {
|
||||
Ok(a)
|
||||
(a_val @ ConstValue::Scalar(Scalar::Raw { .. }), b_val @ _)
|
||||
if a.ty == b.ty && a_val == b_val =>
|
||||
{
|
||||
Ok(tcx.mk_const(ty::Const {
|
||||
val: a_val,
|
||||
ty: a.ty,
|
||||
}))
|
||||
}
|
||||
(ConstValue::ByRef(..), _) => {
|
||||
bug!(
|
||||
@ -635,9 +627,7 @@ where
|
||||
}))
|
||||
}
|
||||
|
||||
_ => {
|
||||
Err(TypeError::ConstMismatch(expected_found(relation, &a, &b)))
|
||||
}
|
||||
_ => Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1263,7 +1263,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
||||
debug!(
|
||||
"eq_opaque_type_and_type: concrete_ty={:?}={:?} opaque_defn_ty={:?}",
|
||||
opaque_decl.concrete_ty,
|
||||
infcx.resolve_type_vars_if_possible(&opaque_decl.concrete_ty),
|
||||
infcx.resolve_vars_if_possible(&opaque_decl.concrete_ty),
|
||||
opaque_defn_ty
|
||||
);
|
||||
obligations.add(infcx
|
||||
|
@ -411,7 +411,7 @@ impl context::UnificationOps<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
|
||||
}
|
||||
|
||||
fn debug_ex_clause(&mut self, value: &'v ChalkExClause<'tcx>) -> Box<dyn Debug + 'v> {
|
||||
let string = format!("{:?}", self.infcx.resolve_type_vars_if_possible(value));
|
||||
let string = format!("{:?}", self.infcx.resolve_vars_if_possible(value));
|
||||
Box::new(string)
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ impl ChalkInferenceContext<'cx, 'gcx, 'tcx> {
|
||||
use rustc::traits::WhereClause::*;
|
||||
use rustc::infer::canonical::OriginalQueryValues;
|
||||
|
||||
let goal = self.infcx.resolve_type_vars_if_possible(goal);
|
||||
let goal = self.infcx.resolve_vars_if_possible(goal);
|
||||
|
||||
debug!("program_clauses(goal = {:?})", goal);
|
||||
|
||||
|
@ -111,8 +111,8 @@ impl context::ResolventOps<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
|
||||
) -> Fallible<ChalkExClause<'tcx>> {
|
||||
debug!(
|
||||
"apply_answer_subst(ex_clause = {:?}, selected_goal = {:?})",
|
||||
self.infcx.resolve_type_vars_if_possible(&ex_clause),
|
||||
self.infcx.resolve_type_vars_if_possible(selected_goal)
|
||||
self.infcx.resolve_vars_if_possible(&ex_clause),
|
||||
self.infcx.resolve_vars_if_possible(selected_goal)
|
||||
);
|
||||
|
||||
let (answer_subst, _) = self.infcx.instantiate_canonical_with_fresh_inference_vars(
|
||||
|
@ -121,7 +121,7 @@ fn compute_implied_outlives_bounds<'tcx>(
|
||||
ty::Predicate::TypeOutlives(ref data) => match data.no_bound_vars() {
|
||||
None => vec![],
|
||||
Some(ty::OutlivesPredicate(ty_a, r_b)) => {
|
||||
let ty_a = infcx.resolve_type_vars_if_possible(&ty_a);
|
||||
let ty_a = infcx.resolve_vars_if_possible(&ty_a);
|
||||
let mut components = smallvec![];
|
||||
tcx.push_outlives_components(ty_a, &mut components);
|
||||
implied_bounds_from_components(r_b, components)
|
||||
|
@ -36,7 +36,7 @@ fn normalize_ty_after_erasing_regions<'tcx>(
|
||||
None,
|
||||
);
|
||||
|
||||
let normalized_value = infcx.resolve_type_vars_if_possible(&normalized_value);
|
||||
let normalized_value = infcx.resolve_vars_if_possible(&normalized_value);
|
||||
let normalized_value = infcx.tcx.erase_regions(&normalized_value);
|
||||
tcx.lift_to_global(&normalized_value).unwrap()
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
// Now that we know the types can be unified we find the unified type and use
|
||||
// it to type the entire expression.
|
||||
let common_type = self.resolve_type_vars_if_possible(&lhs_ty);
|
||||
let common_type = self.resolve_vars_if_possible(&lhs_ty);
|
||||
|
||||
// subtyping doesn't matter here, as the value is some kind of scalar
|
||||
self.demand_eqtype_pat(pat.span, expected, lhs_ty, discrim_span);
|
||||
|
@ -98,7 +98,7 @@ impl<'a, 'gcx, 'tcx> Autoderef<'a, 'gcx, 'tcx> {
|
||||
body_id,
|
||||
param_env,
|
||||
steps: vec![],
|
||||
cur_ty: infcx.resolve_type_vars_if_possible(&base_ty),
|
||||
cur_ty: infcx.resolve_vars_if_possible(&base_ty),
|
||||
obligations: vec![],
|
||||
at_start: true,
|
||||
include_raw_pointers: false,
|
||||
@ -152,7 +152,7 @@ impl<'a, 'gcx, 'tcx> Autoderef<'a, 'gcx, 'tcx> {
|
||||
ty, normalized_ty, obligations);
|
||||
self.obligations.extend(obligations);
|
||||
|
||||
Some(self.infcx.resolve_type_vars_if_possible(&normalized_ty))
|
||||
Some(self.infcx.resolve_vars_if_possible(&normalized_ty))
|
||||
}
|
||||
|
||||
/// Returns the final type, generating an error if it is an
|
||||
@ -164,7 +164,7 @@ impl<'a, 'gcx, 'tcx> Autoderef<'a, 'gcx, 'tcx> {
|
||||
/// Returns the final type we ended up with, which may well be an
|
||||
/// inference variable (we will resolve it first, if possible).
|
||||
pub fn maybe_ambiguous_final_ty(&self) -> Ty<'tcx> {
|
||||
self.infcx.resolve_type_vars_if_possible(&self.cur_ty)
|
||||
self.infcx.resolve_vars_if_possible(&self.cur_ty)
|
||||
}
|
||||
|
||||
pub fn step_count(&self) -> usize {
|
||||
|
@ -82,7 +82,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
{
|
||||
debug!("pointer_kind({:?}, {:?})", t, span);
|
||||
|
||||
let t = self.resolve_type_vars_if_possible(&t);
|
||||
let t = self.resolve_vars_if_possible(&t);
|
||||
|
||||
if t.references_error() {
|
||||
return Err(ErrorReported);
|
||||
@ -334,7 +334,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
|
||||
let tstr = fcx.ty_to_string(self.cast_ty);
|
||||
let mut err = type_error_struct!(fcx.tcx.sess, self.span, self.expr_ty, E0620,
|
||||
"cast to unsized type: `{}` as `{}`",
|
||||
fcx.resolve_type_vars_if_possible(&self.expr_ty),
|
||||
fcx.resolve_vars_if_possible(&self.expr_ty),
|
||||
tstr);
|
||||
match self.expr_ty.sty {
|
||||
ty::Ref(_, _, mt) => {
|
||||
|
@ -282,7 +282,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
let input_tys = if is_fn {
|
||||
let arg_param_ty = trait_ref.skip_binder().substs.type_at(1);
|
||||
let arg_param_ty = self.resolve_type_vars_if_possible(&arg_param_ty);
|
||||
let arg_param_ty = self.resolve_vars_if_possible(&arg_param_ty);
|
||||
debug!("deduce_sig_from_projection: arg_param_ty={:?}", arg_param_ty);
|
||||
|
||||
match arg_param_ty.sty {
|
||||
@ -295,7 +295,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
};
|
||||
|
||||
let ret_param_ty = projection.skip_binder().ty;
|
||||
let ret_param_ty = self.resolve_type_vars_if_possible(&ret_param_ty);
|
||||
let ret_param_ty = self.resolve_vars_if_possible(&ret_param_ty);
|
||||
debug!("deduce_sig_from_projection: ret_param_ty={:?}", ret_param_ty);
|
||||
|
||||
let sig = self.tcx.mk_fn_sig(
|
||||
|
@ -575,7 +575,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
||||
// Uncertain or unimplemented.
|
||||
Ok(None) => {
|
||||
if trait_ref.def_id() == unsize_did {
|
||||
let trait_ref = self.resolve_type_vars_if_possible(&trait_ref);
|
||||
let trait_ref = self.resolve_vars_if_possible(&trait_ref);
|
||||
let self_ty = trait_ref.skip_binder().self_ty();
|
||||
let unsize_ty = trait_ref.skip_binder().input_types().nth(1).unwrap();
|
||||
debug!("coerce_unsized: ambiguous unsize case for {:?}", trait_ref);
|
||||
|
@ -48,7 +48,7 @@ impl<'a, 'gcx, 'tcx> InteriorVisitor<'a, 'gcx, 'tcx> {
|
||||
});
|
||||
|
||||
if let Some(yield_span) = live_across_yield {
|
||||
let ty = self.fcx.resolve_type_vars_if_possible(&ty);
|
||||
let ty = self.fcx.resolve_vars_if_possible(&ty);
|
||||
|
||||
debug!("type in expr = {:?}, scope = {:?}, type = {:?}, count = {}, yield_span = {:?}",
|
||||
expr, scope, ty, self.expr_count, yield_span);
|
||||
|
@ -511,7 +511,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
|
||||
|
||||
let base_ty = self.tables.borrow().expr_adjustments(base_expr).last()
|
||||
.map_or_else(|| self.node_ty(expr.hir_id), |adj| adj.target);
|
||||
let base_ty = self.resolve_type_vars_if_possible(&base_ty);
|
||||
let base_ty = self.resolve_vars_if_possible(&base_ty);
|
||||
|
||||
// Need to deref because overloaded place ops take self by-reference.
|
||||
let base_ty = base_ty.builtin_deref(false)
|
||||
|
@ -253,7 +253,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
scope: ProbeScope)
|
||||
-> probe::PickResult<'tcx> {
|
||||
let mode = probe::Mode::MethodCall;
|
||||
let self_ty = self.resolve_type_vars_if_possible(&self_ty);
|
||||
let self_ty = self.resolve_vars_if_possible(&self_ty);
|
||||
self.probe_for_name(span, mode, method_name, IsSuggestion(false),
|
||||
self_ty, call_expr.hir_id, scope)
|
||||
}
|
||||
|
@ -1338,7 +1338,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
||||
// and point at it rather than reporting the entire
|
||||
// trait-ref?
|
||||
result = ProbeResult::NoMatch;
|
||||
let trait_ref = self.resolve_type_vars_if_possible(&trait_ref);
|
||||
let trait_ref = self.resolve_vars_if_possible(&trait_ref);
|
||||
possibly_unsatisfied_predicates.push(trait_ref);
|
||||
}
|
||||
}
|
||||
@ -1351,7 +1351,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
||||
|
||||
// Evaluate those obligations to see if they might possibly hold.
|
||||
for o in candidate_obligations.into_iter().chain(sub_obligations) {
|
||||
let o = self.resolve_type_vars_if_possible(&o);
|
||||
let o = self.resolve_vars_if_possible(&o);
|
||||
if !self.predicate_may_hold(&o) {
|
||||
result = ProbeResult::NoMatch;
|
||||
if let &ty::Predicate::Trait(ref pred) = &o.predicate {
|
||||
@ -1364,7 +1364,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
||||
if let (Some(return_ty), Some(xform_ret_ty)) =
|
||||
(self.return_type, probe.xform_ret_ty)
|
||||
{
|
||||
let xform_ret_ty = self.resolve_type_vars_if_possible(&xform_ret_ty);
|
||||
let xform_ret_ty = self.resolve_vars_if_possible(&xform_ret_ty);
|
||||
debug!("comparing return_ty {:?} with xform ret ty {:?}",
|
||||
return_ty,
|
||||
probe.xform_ret_ty);
|
||||
|
@ -196,7 +196,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
}) => {
|
||||
let tcx = self.tcx;
|
||||
|
||||
let actual = self.resolve_type_vars_if_possible(&rcvr_ty);
|
||||
let actual = self.resolve_vars_if_possible(&rcvr_ty);
|
||||
let ty_str = self.ty_to_string(actual);
|
||||
let is_method = mode == Mode::MethodCall;
|
||||
let item_kind = if is_method {
|
||||
|
@ -330,13 +330,13 @@ impl<'a, 'gcx, 'tcx> Expectation<'tcx> {
|
||||
match self {
|
||||
NoExpectation => NoExpectation,
|
||||
ExpectCastableToType(t) => {
|
||||
ExpectCastableToType(fcx.resolve_type_vars_if_possible(&t))
|
||||
ExpectCastableToType(fcx.resolve_vars_if_possible(&t))
|
||||
}
|
||||
ExpectHasType(t) => {
|
||||
ExpectHasType(fcx.resolve_type_vars_if_possible(&t))
|
||||
ExpectHasType(fcx.resolve_vars_if_possible(&t))
|
||||
}
|
||||
ExpectRvalueLikeUnsized(t) => {
|
||||
ExpectRvalueLikeUnsized(fcx.resolve_type_vars_if_possible(&t))
|
||||
ExpectRvalueLikeUnsized(fcx.resolve_vars_if_possible(&t))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2067,7 +2067,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
/// Resolves type variables in `ty` if possible. Unlike the infcx
|
||||
/// version (resolve_type_vars_if_possible), this version will
|
||||
/// version (resolve_vars_if_possible), this version will
|
||||
/// also select obligations if it seems useful, in an effort
|
||||
/// to get more type information.
|
||||
fn resolve_type_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
@ -2080,7 +2080,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
// If `ty` is a type variable, see whether we already know what it is.
|
||||
ty = self.resolve_type_vars_if_possible(&ty);
|
||||
ty = self.resolve_vars_if_possible(&ty);
|
||||
if !ty.has_infer_types() {
|
||||
debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
|
||||
return ty;
|
||||
@ -2091,7 +2091,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
// indirect dependencies that don't seem worth tracking
|
||||
// precisely.
|
||||
self.select_obligations_where_possible(false);
|
||||
ty = self.resolve_type_vars_if_possible(&ty);
|
||||
ty = self.resolve_vars_if_possible(&ty);
|
||||
|
||||
debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
|
||||
ty
|
||||
@ -2127,7 +2127,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
#[inline]
|
||||
pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
|
||||
debug!("write_ty({:?}, {:?}) in fcx {}",
|
||||
id, self.resolve_type_vars_if_possible(&ty), self.tag());
|
||||
id, self.resolve_vars_if_possible(&ty), self.tag());
|
||||
self.tables.borrow_mut().node_types_mut().insert(id, ty);
|
||||
|
||||
if ty.references_error() {
|
||||
@ -2950,9 +2950,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
} else {
|
||||
// is the missing argument of type `()`?
|
||||
let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
|
||||
self.resolve_type_vars_if_possible(&expected_arg_tys[0]).is_unit()
|
||||
self.resolve_vars_if_possible(&expected_arg_tys[0]).is_unit()
|
||||
} else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
|
||||
self.resolve_type_vars_if_possible(&fn_inputs[0]).is_unit()
|
||||
self.resolve_vars_if_possible(&fn_inputs[0]).is_unit()
|
||||
} else {
|
||||
false
|
||||
};
|
||||
@ -3063,7 +3063,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
ty::FnDef(..) => {
|
||||
let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
|
||||
let ptr_ty = self.resolve_type_vars_if_possible(&ptr_ty);
|
||||
let ptr_ty = self.resolve_vars_if_possible(&ptr_ty);
|
||||
variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
|
||||
}
|
||||
_ => {}
|
||||
@ -3253,7 +3253,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
// Record all the argument types, with the substitutions
|
||||
// produced from the above subtyping unification.
|
||||
Ok(formal_args.iter().map(|ty| {
|
||||
self.resolve_type_vars_if_possible(ty)
|
||||
self.resolve_vars_if_possible(ty)
|
||||
}).collect())
|
||||
}).unwrap_or_default();
|
||||
debug!("expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
|
||||
@ -4333,9 +4333,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
// Find the type of `e`. Supply hints based on the type we are casting to,
|
||||
// if appropriate.
|
||||
let t_cast = self.to_ty_saving_user_provided_ty(t);
|
||||
let t_cast = self.resolve_type_vars_if_possible(&t_cast);
|
||||
let t_cast = self.resolve_vars_if_possible(&t_cast);
|
||||
let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
|
||||
let t_cast = self.resolve_type_vars_if_possible(&t_cast);
|
||||
let t_cast = self.resolve_vars_if_possible(&t_cast);
|
||||
|
||||
// Eagerly check for some obvious errors.
|
||||
if t_expr.references_error() || t_cast.references_error() {
|
||||
|
@ -618,7 +618,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
method.sig.output()
|
||||
}
|
||||
Err(()) => {
|
||||
let actual = self.resolve_type_vars_if_possible(&operand_ty);
|
||||
let actual = self.resolve_vars_if_possible(&operand_ty);
|
||||
if !actual.references_error() {
|
||||
let mut err = struct_span_err!(self.tcx.sess, ex.span, E0600,
|
||||
"cannot apply unary operator `{}` to type `{}`",
|
||||
|
@ -270,7 +270,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
||||
/// of b will be `&<R0>.i32` and then `*b` will require that `<R0>` be bigger than the let and
|
||||
/// the `*b` expression, so we will effectively resolve `<R0>` to be the block B.
|
||||
pub fn resolve_type(&self, unresolved_ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
self.resolve_type_vars_if_possible(&unresolved_ty)
|
||||
self.resolve_vars_if_possible(&unresolved_ty)
|
||||
}
|
||||
|
||||
/// Try to resolve the type for the given node.
|
||||
|
@ -138,7 +138,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
|
||||
hir::ExprKind::Unary(hir::UnNeg, ref inner)
|
||||
| hir::ExprKind::Unary(hir::UnNot, ref inner) => {
|
||||
let inner_ty = self.fcx.node_ty(inner.hir_id);
|
||||
let inner_ty = self.fcx.resolve_type_vars_if_possible(&inner_ty);
|
||||
let inner_ty = self.fcx.resolve_vars_if_possible(&inner_ty);
|
||||
|
||||
if inner_ty.is_scalar() {
|
||||
let mut tables = self.fcx.tables.borrow_mut();
|
||||
@ -149,10 +149,10 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
|
||||
hir::ExprKind::Binary(ref op, ref lhs, ref rhs)
|
||||
| hir::ExprKind::AssignOp(ref op, ref lhs, ref rhs) => {
|
||||
let lhs_ty = self.fcx.node_ty(lhs.hir_id);
|
||||
let lhs_ty = self.fcx.resolve_type_vars_if_possible(&lhs_ty);
|
||||
let lhs_ty = self.fcx.resolve_vars_if_possible(&lhs_ty);
|
||||
|
||||
let rhs_ty = self.fcx.node_ty(rhs.hir_id);
|
||||
let rhs_ty = self.fcx.resolve_type_vars_if_possible(&rhs_ty);
|
||||
let rhs_ty = self.fcx.resolve_vars_if_possible(&rhs_ty);
|
||||
|
||||
if lhs_ty.is_scalar() && rhs_ty.is_scalar() {
|
||||
let mut tables = self.fcx.tables.borrow_mut();
|
||||
@ -192,7 +192,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
|
||||
// All valid indexing looks like this; might encounter non-valid indexes at this point
|
||||
if let ty::Ref(_, base_ty, _) = tables.expr_ty_adjusted(&base).sty {
|
||||
let index_ty = tables.expr_ty_adjusted(&index);
|
||||
let index_ty = self.fcx.resolve_type_vars_if_possible(&index_ty);
|
||||
let index_ty = self.fcx.resolve_vars_if_possible(&index_ty);
|
||||
|
||||
if base_ty.builtin_index().is_some() && index_ty == self.fcx.tcx.types.usize {
|
||||
// Remove the method call record
|
||||
|
@ -1,9 +1,11 @@
|
||||
fn main() {
|
||||
loop {
|
||||
|_: [_; break]| {} //~ ERROR: `break` outside of loop
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
|
||||
loop {
|
||||
|_: [_; continue]| {} //~ ERROR: `continue` outside of loop
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
}
|
||||
|
@ -5,11 +5,30 @@ LL | |_: [_; break]| {}
|
||||
| ^^^^^ cannot break outside of a loop
|
||||
|
||||
error[E0268]: `continue` outside of loop
|
||||
--> $DIR/array-break-length.rs:7:17
|
||||
--> $DIR/array-break-length.rs:8:17
|
||||
|
|
||||
LL | |_: [_; continue]| {}
|
||||
| ^^^^^^^^ cannot break outside of a loop
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/array-break-length.rs:3:9
|
||||
|
|
||||
LL | |_: [_; break]| {}
|
||||
| ^^^^^^^^^^^^^^^^^^ expected (), found closure
|
||||
|
|
||||
= note: expected type `()`
|
||||
found type `[closure@$DIR/array-break-length.rs:3:9: 3:27]`
|
||||
|
||||
For more information about this error, try `rustc --explain E0268`.
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/array-break-length.rs:8:9
|
||||
|
|
||||
LL | |_: [_; continue]| {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ expected (), found closure
|
||||
|
|
||||
= note: expected type `()`
|
||||
found type `[closure@$DIR/array-break-length.rs:8:9: 8:30]`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0268, E0308.
|
||||
For more information about an error, try `rustc --explain E0268`.
|
||||
|
@ -2,6 +2,8 @@ fn main() {
|
||||
|_: [_; continue]| {}; //~ ERROR: `continue` outside of loop
|
||||
|
||||
while |_: [_; continue]| {} {} //~ ERROR: `continue` outside of loop
|
||||
//~^ ERROR mismatched types
|
||||
|
||||
while |_: [_; break]| {} {} //~ ERROR: `break` outside of loop
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
|
@ -11,11 +11,30 @@ LL | while |_: [_; continue]| {} {}
|
||||
| ^^^^^^^^ cannot break outside of a loop
|
||||
|
||||
error[E0268]: `break` outside of loop
|
||||
--> $DIR/closure-array-break-length.rs:6:19
|
||||
--> $DIR/closure-array-break-length.rs:7:19
|
||||
|
|
||||
LL | while |_: [_; break]| {} {}
|
||||
| ^^^^^ cannot break outside of a loop
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/closure-array-break-length.rs:4:11
|
||||
|
|
||||
LL | while |_: [_; continue]| {} {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ expected bool, found closure
|
||||
|
|
||||
= note: expected type `bool`
|
||||
found type `[closure@$DIR/closure-array-break-length.rs:4:11: 4:32]`
|
||||
|
||||
For more information about this error, try `rustc --explain E0268`.
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/closure-array-break-length.rs:7:11
|
||||
|
|
||||
LL | while |_: [_; break]| {} {}
|
||||
| ^^^^^^^^^^^^^^^^^^ expected bool, found closure
|
||||
|
|
||||
= note: expected type `bool`
|
||||
found type `[closure@$DIR/closure-array-break-length.rs:7:11: 7:29]`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0268, E0308.
|
||||
For more information about an error, try `rustc --explain E0268`.
|
||||
|
17
src/test/ui/const-generics/broken-mir-1.rs
Normal file
17
src/test/ui/const-generics/broken-mir-1.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// run-pass
|
||||
|
||||
#![feature(const_generics)]
|
||||
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||
|
||||
pub trait Foo {
|
||||
fn foo(&self);
|
||||
}
|
||||
|
||||
|
||||
impl<T, const N: usize> Foo for [T; N] {
|
||||
fn foo(&self) {
|
||||
let _ = &self;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
6
src/test/ui/const-generics/broken-mir-1.stderr
Normal file
6
src/test/ui/const-generics/broken-mir-1.stderr
Normal file
@ -0,0 +1,6 @@
|
||||
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||
--> $DIR/broken-mir-1.rs:3:12
|
||||
|
|
||||
LL | #![feature(const_generics)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
9
src/test/ui/const-generics/broken-mir-2.rs
Normal file
9
src/test/ui/const-generics/broken-mir-2.rs
Normal file
@ -0,0 +1,9 @@
|
||||
#![feature(const_generics)]
|
||||
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct S<T: Debug, const N: usize>([T; N]); //~ ERROR `[T; _]` doesn't implement `std::fmt::Debug`
|
||||
|
||||
fn main() {}
|
19
src/test/ui/const-generics/broken-mir-2.stderr
Normal file
19
src/test/ui/const-generics/broken-mir-2.stderr
Normal file
@ -0,0 +1,19 @@
|
||||
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||
--> $DIR/broken-mir-2.rs:1:12
|
||||
|
|
||||
LL | #![feature(const_generics)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error[E0277]: `[T; _]` doesn't implement `std::fmt::Debug`
|
||||
--> $DIR/broken-mir-2.rs:7:36
|
||||
|
|
||||
LL | struct S<T: Debug, const N: usize>([T; N]);
|
||||
| ^^^^^^ `[T; _]` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`
|
||||
|
|
||||
= help: the trait `std::fmt::Debug` is not implemented for `[T; _]`
|
||||
= note: required because of the requirements on the impl of `std::fmt::Debug` for `&[T; _]`
|
||||
= note: required for the cast to the object type `dyn std::fmt::Debug`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
@ -8,4 +8,5 @@ struct Foo<const NUM_BYTES: usize>(pub [u8; NUM_BYTES]);
|
||||
|
||||
fn main() {
|
||||
let _ = Foo::<3>([1, 2, 3]); //~ ERROR type annotations needed
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
|
@ -10,6 +10,16 @@ error[E0282]: type annotations needed
|
||||
LL | let _ = Foo::<3>([1, 2, 3]);
|
||||
| ^ cannot infer type for `{integer}`
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/cannot-infer-type-for-const-param.rs:10:22
|
||||
|
|
||||
LL | let _ = Foo::<3>([1, 2, 3]);
|
||||
| ^^^^^^^^^ expected `3`, found `3usize`
|
||||
|
|
||||
= note: expected type `[u8; _]`
|
||||
found type `[u8; 3]`
|
||||
|
||||
For more information about this error, try `rustc --explain E0282`.
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0282, E0308.
|
||||
For more information about an error, try `rustc --explain E0282`.
|
||||
|
16
src/test/ui/const-generics/fn-taking-const-generic-array.rs
Normal file
16
src/test/ui/const-generics/fn-taking-const-generic-array.rs
Normal file
@ -0,0 +1,16 @@
|
||||
// run-pass
|
||||
|
||||
#![feature(const_generics)]
|
||||
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||
|
||||
use std::fmt::Display;
|
||||
|
||||
fn print_slice<T: Display, const N: usize>(slice: &[T; N]) {
|
||||
for x in slice.iter() {
|
||||
println!("{}", x);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
print_slice(&[1, 2, 3]);
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||
--> $DIR/fn-taking-const-generic-array.rs:3:12
|
||||
|
|
||||
LL | #![feature(const_generics)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
@ -0,0 +1,18 @@
|
||||
// run-pass
|
||||
|
||||
#![feature(const_generics)]
|
||||
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||
|
||||
use std::fmt;
|
||||
|
||||
struct Array<T, const N: usize>([T; N]);
|
||||
|
||||
impl<T: fmt::Debug, const N: usize> fmt::Debug for Array<T, {N}> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_list().entries(self.0.iter()).finish()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(format!("{:?}", Array([1, 2, 3])), "[1, 2, 3]");
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||
--> $DIR/uninferred-consts-during-codegen-1.rs:3:12
|
||||
|
|
||||
LL | #![feature(const_generics)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
@ -0,0 +1,18 @@
|
||||
// run-pass
|
||||
|
||||
#![feature(const_generics)]
|
||||
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||
|
||||
use std::fmt;
|
||||
|
||||
struct Array<T>(T);
|
||||
|
||||
impl<T: fmt::Debug, const N: usize> fmt::Debug for Array<[T; N]> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_list().entries((&self.0 as &[T]).iter()).finish()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(format!("{:?}", Array([1, 2, 3])), "[1, 2, 3]");
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||
--> $DIR/uninferred-consts-during-codegen-2.rs:3:12
|
||||
|
|
||||
LL | #![feature(const_generics)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
@ -4,8 +4,12 @@ const ARR: [i32; 6] = [42, 43, 44, 45, 46, 47];
|
||||
const IDX: usize = 3;
|
||||
const VAL: i32 = ARR[IDX];
|
||||
const BONG: [i32; (ARR[0] - 41) as usize] = [5];
|
||||
const BLUB: [i32; (ARR[0] - 40) as usize] = [5]; //~ ERROR: mismatched types
|
||||
const BOO: [i32; (ARR[0] - 41) as usize] = [5, 99]; //~ ERROR: mismatched types
|
||||
const BLUB: [i32; (ARR[0] - 40) as usize] = [5];
|
||||
//~^ ERROR: mismatched types
|
||||
//~| expected an array with a fixed size of 2 elements, found one with 1 element
|
||||
const BOO: [i32; (ARR[0] - 41) as usize] = [5, 99];
|
||||
//~^ ERROR: mismatched types
|
||||
//~| expected an array with a fixed size of 1 element, found one with 2 elements
|
||||
|
||||
fn main() {
|
||||
let _ = VAL;
|
||||
|
@ -2,16 +2,16 @@ error[E0308]: mismatched types
|
||||
--> $DIR/const-array-oob-arith.rs:7:45
|
||||
|
|
||||
LL | const BLUB: [i32; (ARR[0] - 40) as usize] = [5];
|
||||
| ^^^ expected an array with a fixed size of 2 elements, found one with 1 elements
|
||||
| ^^^ expected an array with a fixed size of 2 elements, found one with 1 element
|
||||
|
|
||||
= note: expected type `[i32; 2]`
|
||||
found type `[i32; 1]`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/const-array-oob-arith.rs:8:44
|
||||
--> $DIR/const-array-oob-arith.rs:10:44
|
||||
|
|
||||
LL | const BOO: [i32; (ARR[0] - 41) as usize] = [5, 99];
|
||||
| ^^^^^^^ expected an array with a fixed size of 1 elements, found one with 2 elements
|
||||
| ^^^^^^^ expected an array with a fixed size of 1 element, found one with 2 elements
|
||||
|
|
||||
= note: expected type `[i32; 1]`
|
||||
found type `[i32; 2]`
|
||||
|
@ -13,5 +13,5 @@ fn main() {
|
||||
//~^ ERROR mismatched types
|
||||
//~| expected type `(isize, f64)`
|
||||
//~| found type `(isize,)`
|
||||
//~| expected a tuple with 2 elements, found one with 1 elements
|
||||
//~| expected a tuple with 2 elements, found one with 1 element
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/tuple-arity-mismatch.rs:12:20
|
||||
|
|
||||
LL | let y = first ((1,));
|
||||
| ^^^^ expected a tuple with 2 elements, found one with 1 elements
|
||||
| ^^^^ expected a tuple with 2 elements, found one with 1 element
|
||||
|
|
||||
= note: expected type `(isize, f64)`
|
||||
found type `(isize,)`
|
||||
|
@ -3,4 +3,5 @@ fn main() {
|
||||
const l: usize = v.count(); //~ ERROR attempt to use a non-constant value in a constant
|
||||
let s: [u32; l] = v.into_iter().collect();
|
||||
//~^ ERROR evaluation of constant value failed
|
||||
//~^^ ERROR a collection of type
|
||||
}
|
||||
|
@ -10,7 +10,15 @@ error[E0080]: evaluation of constant value failed
|
||||
LL | let s: [u32; l] = v.into_iter().collect();
|
||||
| ^ referenced constant has errors
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error[E0277]: a collection of type `[u32; _]` cannot be built from an iterator over elements of type `{integer}`
|
||||
--> $DIR/type-dependent-def-issue-49241.rs:4:37
|
||||
|
|
||||
LL | let s: [u32; l] = v.into_iter().collect();
|
||||
| ^^^^^^^ a collection of type `[u32; _]` cannot be built from `std::iter::Iterator<Item={integer}>`
|
||||
|
|
||||
= help: the trait `std::iter::FromIterator<{integer}>` is not implemented for `[u32; _]`
|
||||
|
||||
Some errors have detailed explanations: E0080, E0435.
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0080, E0277, E0435.
|
||||
For more information about an error, try `rustc --explain E0080`.
|
||||
|
Loading…
x
Reference in New Issue
Block a user