Auto merge of #54533 - ljedrz:cleanup_librustc_typeck_check, r=davidtwco

A few cleanups and minor improvements to typeck/check

- turn a `loop` into a `while let`
- turn a `push_back` loop into an `extend`
- turn a few `push` loops into collected iterators
- prefer `vec![x; n]` to `(0..n).map(|_| x).collect()`
- combine two loops doing the same thing on 2 data sets using `chain`
- use `unwrap_or` where applicable and readable
- add a `potentially_plural_count` helper function to simplify several `format!()` calls
- prefer `to_owned` to `to_string` for string literals
- change `match` to `if let` where only one branch matters
- a few other minor improvements
- whitespace fixes
This commit is contained in:
bors 2018-09-27 16:54:28 +00:00
commit f1694eac74
19 changed files with 443 additions and 574 deletions

View File

@ -81,35 +81,33 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
//
// See the examples in `run-pass/match-defbm*.rs`.
let mut pat_adjustments = vec![];
expected = loop {
while let ty::Ref(_, inner_ty, inner_mutability) = exp_ty.sty {
debug!("inspecting {:?} with type {:?}", exp_ty, exp_ty.sty);
match exp_ty.sty {
ty::Ref(_, inner_ty, inner_mutability) => {
debug!("current discriminant is Ref, inserting implicit deref");
// Preserve the reference type. We'll need it later during HAIR lowering.
pat_adjustments.push(exp_ty);
exp_ty = inner_ty;
def_bm = match def_bm {
// If default binding mode is by value, make it `ref` or `ref mut`
// (depending on whether we observe `&` or `&mut`).
ty::BindByValue(_) =>
ty::BindByReference(inner_mutability),
debug!("current discriminant is Ref, inserting implicit deref");
// Preserve the reference type. We'll need it later during HAIR lowering.
pat_adjustments.push(exp_ty);
// Once a `ref`, always a `ref`. This is because a `& &mut` can't mutate
// the underlying value.
ty::BindByReference(hir::Mutability::MutImmutable) =>
ty::BindByReference(hir::Mutability::MutImmutable),
exp_ty = inner_ty;
def_bm = match def_bm {
// If default binding mode is by value, make it `ref` or `ref mut`
// (depending on whether we observe `&` or `&mut`).
ty::BindByValue(_) =>
ty::BindByReference(inner_mutability),
// Once a `ref`, always a `ref`. This is because a `& &mut` can't mutate
// the underlying value.
ty::BindByReference(hir::Mutability::MutImmutable) =>
ty::BindByReference(hir::Mutability::MutImmutable),
// When `ref mut`, stay a `ref mut` (on `&mut`) or downgrade to `ref`
// (on `&`).
ty::BindByReference(hir::Mutability::MutMutable) =>
ty::BindByReference(inner_mutability),
};
}
expected = exp_ty;
// When `ref mut`, stay a `ref mut` (on `&mut`) or downgrade to `ref`
// (on `&`).
ty::BindByReference(hir::Mutability::MutMutable) =>
ty::BindByReference(inner_mutability),
};
},
_ => break exp_ty,
}
};
if pat_adjustments.len() > 0 {
debug!("default binding mode is now {:?}", def_bm);
self.inh.tables.borrow_mut()
@ -153,7 +151,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
if let ty::Ref(_, r_ty, _) = expected_ty.sty {
if let ty::Slice(_) = r_ty.sty {
pat_ty = tcx.mk_imm_ref(tcx.types.re_static,
tcx.mk_slice(tcx.types.u8))
tcx.mk_slice(tcx.types.u8))
}
}
}
@ -294,7 +292,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let element_tys_iter = (0..max_len).map(|_| self.next_ty_var(
// FIXME: MiscVariable for now, obtaining the span and name information
// from all tuple elements isn't trivial.
// from all tuple elements isn't trivial.
TypeVariableOrigin::TypeInference(pat.span)));
let element_tys = tcx.mk_type_list(element_tys_iter);
let pat_ty = tcx.mk_ty(ty::Tuple(element_tys));
@ -394,7 +392,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
tcx.sess, pat.span, E0527,
"pattern requires {} elements but array has {}",
min_len, size)
.span_label(pat.span, format!("expected {} elements",size))
.span_label(pat.span, format!("expected {} elements", size))
.emit();
}
(inner_ty, tcx.types.err)
@ -857,7 +855,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
subpats.len(), subpats_ending, def.kind_name(),
variant.fields.len(), fields_ending)
.span_label(pat.span, format!("expected {} field{}, found {}",
variant.fields.len(), fields_ending, subpats.len()))
variant.fields.len(), fields_ending, subpats.len()))
.emit();
on_error();
return tcx.types.err;

View File

@ -166,34 +166,31 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
None => continue,
};
match self.lookup_method_in_trait(call_expr.span,
method_name,
trait_def_id,
adjusted_ty,
None) {
None => continue,
Some(ok) => {
let method = self.register_infer_ok_obligations(ok);
let mut autoref = None;
if borrow {
if let ty::Ref(region, _, mutbl) = method.sig.inputs()[0].sty {
let mutbl = match mutbl {
hir::MutImmutable => AutoBorrowMutability::Immutable,
hir::MutMutable => AutoBorrowMutability::Mutable {
// For initial two-phase borrow
// deployment, conservatively omit
// overloaded function call ops.
allow_two_phase_borrow: AllowTwoPhase::No,
}
};
autoref = Some(Adjustment {
kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
target: method.sig.inputs()[0]
});
}
if let Some(ok) = self.lookup_method_in_trait(call_expr.span,
method_name,
trait_def_id,
adjusted_ty,
None) {
let method = self.register_infer_ok_obligations(ok);
let mut autoref = None;
if borrow {
if let ty::Ref(region, _, mutbl) = method.sig.inputs()[0].sty {
let mutbl = match mutbl {
hir::MutImmutable => AutoBorrowMutability::Immutable,
hir::MutMutable => AutoBorrowMutability::Mutable {
// For initial two-phase borrow
// deployment, conservatively omit
// overloaded function call ops.
allow_two_phase_borrow: AllowTwoPhase::No,
}
};
autoref = Some(Adjustment {
kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
target: method.sig.inputs()[0]
});
}
return Some((autoref, method));
}
return Some((autoref, method));
}
}
@ -238,7 +235,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
err.span_suggestion_with_applicability(
call_expr.span,
&format!("`{}` is a unit variant, you need to write it \
without the parenthesis", path),
without the parenthesis", path),
path.to_string(),
Applicability::MachineApplicable
);

View File

@ -219,11 +219,11 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
let cast_ty = fcx.ty_to_string(self.cast_ty);
err.span_label(error_span,
format!("cannot cast `{}` as `{}`",
fcx.ty_to_string(self.expr_ty),
cast_ty));
fcx.ty_to_string(self.expr_ty),
cast_ty));
if let Ok(snippet) = fcx.sess().source_map().span_to_snippet(self.expr.span) {
err.span_help(self.expr.span,
&format!("did you mean `*{}`?", snippet));
&format!("did you mean `*{}`?", snippet));
}
err.emit();
}
@ -267,16 +267,16 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
}
CastError::CastToChar => {
type_error_struct!(fcx.tcx.sess, self.span, self.expr_ty, E0604,
"only `u8` can be cast as `char`, not `{}`", self.expr_ty).emit();
"only `u8` can be cast as `char`, not `{}`", self.expr_ty).emit();
}
CastError::NonScalar => {
type_error_struct!(fcx.tcx.sess, self.span, self.expr_ty, E0605,
"non-primitive cast: `{}` as `{}`",
self.expr_ty,
fcx.ty_to_string(self.cast_ty))
.note("an `as` expression can only be used to convert between \
primitive types. Consider using the `From` trait")
.emit();
"non-primitive cast: `{}` as `{}`",
self.expr_ty,
fcx.ty_to_string(self.cast_ty))
.note("an `as` expression can only be used to convert between \
primitive types. Consider using the `From` trait")
.emit();
}
CastError::SizedUnsizedCast => {
use structured_errors::{SizedUnsizedCastError, StructuredDiagnostic};
@ -445,7 +445,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
self.expr_ty,
fcx.tcx.mk_fn_ptr(f),
AllowTwoPhase::No);
if !res.is_ok() {
if res.is_err() {
return Err(CastError::NonScalar);
}
(FnPtr, t_cast)

View File

@ -231,20 +231,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
obligation.predicate
);
match obligation.predicate {
if let ty::Predicate::Projection(ref proj_predicate) = obligation.predicate {
// Given a Projection predicate, we can potentially infer
// the complete signature.
ty::Predicate::Projection(ref proj_predicate) => {
let trait_ref = proj_predicate.to_poly_trait_ref(self.tcx);
self.self_type_matches_expected_vid(trait_ref, expected_vid)
.and_then(|_| {
self.deduce_sig_from_projection(
Some(obligation.cause.span),
proj_predicate,
)
})
}
_ => None,
let trait_ref = proj_predicate.to_poly_trait_ref(self.tcx);
self.self_type_matches_expected_vid(trait_ref, expected_vid)
.and_then(|_| {
self.deduce_sig_from_projection(
Some(obligation.cause.span),
proj_predicate
)
})
} else {
None
}
})
.next();
@ -318,9 +317,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let input_tys = match arg_param_ty.sty {
ty::Tuple(tys) => tys.into_iter(),
_ => {
return None;
}
_ => return None
};
let ret_param_ty = projection.skip_binder().ty;
@ -560,8 +557,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// The liberated version of this signature should be be a subtype
// of the liberated form of the expectation.
for ((hir_ty, &supplied_ty), expected_ty) in decl.inputs.iter()
.zip(*supplied_sig.inputs().skip_binder()) // binder moved to (*) below
.zip(expected_sigs.liberated_sig.inputs())
.zip(*supplied_sig.inputs().skip_binder()) // binder moved to (*) below
.zip(expected_sigs.liberated_sig.inputs())
// `liberated_sig` is E'.
{
// Instantiate (this part of..) S to S', i.e., with fresh variables.
@ -638,11 +635,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
self.tcx.types.err
});
match decl.output {
hir::Return(ref output) => {
astconv.ast_ty_to_ty(&output);
}
hir::DefaultReturn(_) => {}
if let hir::Return(ref output) = decl.output {
astconv.ast_ty_to_ty(&output);
}
let result = ty::Binder::bind(self.tcx.mk_fn_sig(

View File

@ -144,8 +144,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
fn unify(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> InferResult<'tcx, Ty<'tcx>> {
self.commit_if_ok(|_| {
if self.use_lub {
self.at(&self.cause, self.fcx.param_env)
.lub(b, a)
self.at(&self.cause, self.fcx.param_env).lub(b, a)
} else {
self.at(&self.cause, self.fcx.param_env)
.sup(b, a)
@ -256,8 +255,8 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
b: Ty<'tcx>,
r_b: ty::Region<'tcx>,
mt_b: TypeAndMut<'tcx>)
-> CoerceResult<'tcx> {
-> CoerceResult<'tcx>
{
debug!("coerce_borrowed_pointer(a={:?}, b={:?})", a, b);
// If we have a parameter of type `&M T_a` and the value
@ -591,9 +590,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
}
Ok(Some(vtable)) => {
for obligation in vtable.nested_obligations() {
queue.push_back(obligation);
}
queue.extend(vtable.nested_obligations())
}
}
}
@ -620,12 +617,11 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
G: FnOnce(Ty<'tcx>) -> Vec<Adjustment<'tcx>>
{
if let ty::FnPtr(fn_ty_b) = b.sty {
match (fn_ty_a.unsafety(), fn_ty_b.unsafety()) {
(hir::Unsafety::Normal, hir::Unsafety::Unsafe) => {
let unsafe_a = self.tcx.safe_to_unsafe_fn_ty(fn_ty_a);
return self.unify_and(unsafe_a, b, to_unsafe);
}
_ => {}
if let (hir::Unsafety::Normal, hir::Unsafety::Unsafe)
= (fn_ty_a.unsafety(), fn_ty_b.unsafety())
{
let unsafe_a = self.tcx.safe_to_unsafe_fn_ty(fn_ty_a);
return self.unify_and(unsafe_a, b, to_unsafe);
}
}
self.unify_and(a, b, normal)
@ -653,7 +649,6 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
-> CoerceResult<'tcx> {
//! Attempts to coerce from the type of a Rust function item
//! into a closure or a `proc`.
//!
let b = self.shallow_resolve(b);
debug!("coerce_from_fn_item(a={:?}, b={:?})", a, b);
@ -724,9 +719,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
let (is_ref, mt_a) = match a.sty {
ty::Ref(_, ty, mutbl) => (true, ty::TypeAndMut { ty, mutbl }),
ty::RawPtr(mt) => (false, mt),
_ => {
return self.unify_and(a, b, identity);
}
_ => return self.unify_and(a, b, identity)
};
// Check that the types which they point at are compatible.
@ -896,10 +889,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
};
if !noop {
return self.commit_if_ok(|_| {
return self.commit_if_ok(|_|
self.at(cause, self.param_env)
.lub(prev_ty, new_ty)
}).map(|ok| self.register_infer_ok_obligations(ok));
).map(|ok| self.register_infer_ok_obligations(ok));
}
}
@ -909,10 +902,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
if let Some(e) = first_error {
Err(e)
} else {
self.commit_if_ok(|_| {
self.commit_if_ok(|_|
self.at(cause, self.param_env)
.lub(prev_ty, new_ty)
}).map(|ok| self.register_infer_ok_obligations(ok))
).map(|ok| self.register_infer_ok_obligations(ok))
}
}
Ok(ok) => {
@ -1005,7 +998,7 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
/// needlessly cloning the slice.
pub fn with_coercion_sites(expected_ty: Ty<'tcx>,
coercion_sites: &'exprs [E])
-> Self {
-> Self {
Self::make(expected_ty, Expressions::UpFront(coercion_sites))
}

View File

@ -20,7 +20,7 @@ use errors::Applicability;
use syntax_pos::Span;
use super::{Inherited, FnCtxt};
use super::{Inherited, FnCtxt, potentially_plural_count};
/// Checks that a method from an impl conforms to the signature of
/// the same method as declared in the trait.
@ -209,8 +209,8 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
//
// We then register the obligations from the impl_m and check to see
// if all constraints hold.
hybrid_preds.predicates
.extend(trait_m_predicates.instantiate_own(tcx, trait_to_skol_substs).predicates);
hybrid_preds.predicates.extend(
trait_m_predicates.instantiate_own(tcx, trait_to_skol_substs).predicates);
// Construct trait parameter environment and then shift it into the skolemized viewpoint.
// The key step here is to update the caller_bounds's predicates to be
@ -320,12 +320,12 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
trait_m.ident);
if let TypeError::Mutability = terr {
if let Some(trait_err_span) = trait_err_span {
if let Ok(trait_err_str) = tcx.sess.source_map().
span_to_snippet(trait_err_span) {
if let Ok(trait_err_str) = tcx.sess.source_map()
.span_to_snippet(trait_err_span) {
diag.span_suggestion_with_applicability(
impl_err_span,
"consider change the type to match the mutability in trait",
format!("{}", trait_err_str),
trait_err_str.to_string(),
Applicability::MachineApplicable,
);
}
@ -334,7 +334,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
infcx.note_type_err(&mut diag,
&cause,
trait_err_span.map(|sp| (sp, "type in trait".to_string())),
trait_err_span.map(|sp| (sp, "type in trait".to_owned())),
Some(infer::ValuePairs::Types(ExpectedFound {
expected: trait_fty,
found: impl_fty,
@ -408,7 +408,7 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
return Err(ErrorReported);
}
return Ok(());
Ok(())
}
fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>,
@ -470,14 +470,14 @@ fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a
impl_iter.zip(trait_iter)
.zip(impl_m_iter)
.zip(trait_m_iter)
.filter_map(|(((&impl_arg_ty, &trait_arg_ty), impl_arg), trait_arg)| {
.filter_map(|(((&impl_arg_ty, &trait_arg_ty), impl_arg), trait_arg)|
match infcx.at(&cause, param_env).sub(trait_arg_ty, impl_arg_ty) {
Ok(_) => None,
Err(_) => Some((impl_arg.span, Some(trait_arg.span))),
}
})
)
.next()
.unwrap_or_else(|| {
.unwrap_or_else(||
if
infcx.at(&cause, param_env)
.sup(trait_sig.output(), impl_sig.output())
@ -487,7 +487,7 @@ fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a
} else {
(cause.span(&tcx), tcx.hir.span_if_local(trait_m.def_id))
}
})
)
} else {
(cause.span(&tcx), tcx.hir.span_if_local(trait_m.def_id))
}
@ -526,9 +526,9 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
);
let can_eq_self = |ty| infcx.can_eq(param_env, untransformed_self_ty, ty).is_ok();
match ExplicitSelf::determine(self_arg_ty, can_eq_self) {
ExplicitSelf::ByValue => "self".to_string(),
ExplicitSelf::ByReference(_, hir::MutImmutable) => "&self".to_string(),
ExplicitSelf::ByReference(_, hir::MutMutable) => "&mut self".to_string(),
ExplicitSelf::ByValue => "self".to_owned(),
ExplicitSelf::ByReference(_, hir::MutImmutable) => "&self".to_owned(),
ExplicitSelf::ByReference(_, hir::MutMutable) => "&mut self".to_owned(),
_ => format!("self: {}", self_arg_ty)
}
})
@ -591,6 +591,7 @@ fn compare_number_of_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let trait_m_generics = tcx.generics_of(trait_m.def_id);
let num_impl_m_type_params = impl_m_generics.own_counts().types;
let num_trait_m_type_params = trait_m_generics.own_counts().types;
if num_impl_m_type_params != num_trait_m_type_params {
let impl_m_node_id = tcx.hir.as_local_node_id(impl_m.def_id).unwrap();
let impl_m_item = tcx.hir.expect_impl_item(impl_m_node_id);
@ -600,43 +601,26 @@ fn compare_number_of_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
impl_m_item.generics.span
};
let mut err = struct_span_err!(tcx.sess,
span,
E0049,
"method `{}` has {} type parameter{} but its trait \
declaration has {} type parameter{}",
trait_m.ident,
num_impl_m_type_params,
if num_impl_m_type_params == 1 { "" } else { "s" },
num_trait_m_type_params,
if num_trait_m_type_params == 1 {
""
} else {
"s"
});
let mut err = struct_span_err!(tcx.sess, span, E0049,
"method `{}` has {} but its trait declaration has {}",
trait_m.ident,
potentially_plural_count(num_impl_m_type_params, "type parameter"),
potentially_plural_count(num_trait_m_type_params, "type parameter")
);
let mut suffix = None;
if let Some(span) = trait_item_span {
err.span_label(span,
format!("expected {}",
&if num_trait_m_type_params != 1 {
format!("{} type parameters", num_trait_m_type_params)
} else {
format!("{} type parameter", num_trait_m_type_params)
}));
err.span_label(span, format!("expected {}",
potentially_plural_count(num_trait_m_type_params, "type parameter")));
} else {
suffix = Some(format!(", expected {}", num_trait_m_type_params));
}
err.span_label(span,
format!("found {}{}",
&if num_impl_m_type_params != 1 {
format!("{} type parameters", num_impl_m_type_params)
} else {
"1 type parameter".to_string()
},
suffix.as_ref().map(|s| &s[..]).unwrap_or("")));
potentially_plural_count(num_impl_m_type_params, "type parameter"),
suffix.as_ref().map(|s| &s[..]).unwrap_or("")));
err.emit();
@ -694,33 +678,21 @@ fn compare_number_of_method_arguments<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let mut err = struct_span_err!(tcx.sess,
impl_span,
E0050,
"method `{}` has {} parameter{} but the declaration in \
"method `{}` has {} but the declaration in \
trait `{}` has {}",
trait_m.ident,
impl_number_args,
if impl_number_args == 1 { "" } else { "s" },
potentially_plural_count(impl_number_args, "parameter"),
tcx.item_path_str(trait_m.def_id),
trait_number_args);
if let Some(trait_span) = trait_span {
err.span_label(trait_span,
format!("trait requires {}",
&if trait_number_args != 1 {
format!("{} parameters", trait_number_args)
} else {
format!("{} parameter", trait_number_args)
}));
err.span_label(trait_span, format!("trait requires {}",
potentially_plural_count(trait_number_args, "parameter")));
} else {
err.note_trait_signature(trait_m.ident.to_string(),
trait_m.signature(&tcx));
}
err.span_label(impl_span,
format!("expected {}, found {}",
&if trait_number_args != 1 {
format!("{} parameters", trait_number_args)
} else {
format!("{} parameter", trait_number_args)
},
impl_number_args));
err.span_label(impl_span, format!("expected {}, found {}",
potentially_plural_count(trait_number_args, "parameter"), impl_number_args));
err.emit();
return Err(ErrorReported);
}
@ -750,8 +722,9 @@ fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
GenericParamDefKind::Lifetime => None,
}
});
for ((impl_def_id, impl_synthetic),
(trait_def_id, trait_synthetic)) in impl_m_type_params.zip(trait_m_type_params) {
for ((impl_def_id, impl_synthetic), (trait_def_id, trait_synthetic))
in impl_m_type_params.zip(trait_m_type_params)
{
if impl_synthetic != trait_synthetic {
let impl_node_id = tcx.hir.as_local_node_id(impl_def_id).unwrap();
let impl_span = tcx.hir.span(impl_node_id);
@ -831,15 +804,14 @@ fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
impl<'v> hir::intravisit::Visitor<'v> for Visitor {
fn visit_ty(&mut self, ty: &'v hir::Ty) {
hir::intravisit::walk_ty(self, ty);
match ty.node {
hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) => {
if let hir::def::Def::TyParam(def_id) = path.def {
if def_id == self.1 {
self.0 = Some(ty.span);
}
if let hir::TyKind::Path(
hir::QPath::Resolved(None, ref path)) = ty.node
{
if let hir::def::Def::TyParam(def_id) = path.def {
if def_id == self.1 {
self.0 = Some(ty.span);
}
},
_ => {}
}
}
}
fn nested_visit_map<'this>(
@ -975,7 +947,7 @@ pub fn compare_const_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
infcx.note_type_err(&mut diag,
&cause,
trait_c_span.map(|span| (span, "type in trait".to_string())),
trait_c_span.map(|span| (span, "type in trait".to_owned())),
Some(infer::ValuePairs::Types(ExpectedFound {
expected: trait_ty,
found: impl_ty,

View File

@ -115,19 +115,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// field is of the found type, suggest such variants. See Issue
// #42764.
if let ty::Adt(expected_adt, substs) = expected.sty {
let mut compatible_variants = vec![];
for variant in &expected_adt.variants {
if variant.fields.len() == 1 {
let sole_field = &variant.fields[0];
let sole_field_ty = sole_field.ty(self.tcx, substs);
if self.can_coerce(expr_ty, sole_field_ty) {
let mut variant_path = self.tcx.item_path_str(variant.did);
variant_path = variant_path.trim_left_matches("std::prelude::v1::")
.to_string();
compatible_variants.push(variant_path);
}
let compatible_variants = expected_adt.variants
.iter()
.filter(|variant| variant.fields.len() == 1)
.filter_map(|variant| {
let sole_field = &variant.fields[0];
let sole_field_ty = sole_field.ty(self.tcx, substs);
if self.can_coerce(expr_ty, sole_field_ty) {
let variant_path = self.tcx.item_path_str(variant.did);
Some(variant_path.trim_left_matches("std::prelude::v1::").to_string())
} else {
None
}
}
}).collect::<Vec<_>>();
if !compatible_variants.is_empty() {
let expr_text = print::to_string(print::NO_ANN, |s| s.print_expr(expr));
let suggestions = compatible_variants.iter()
@ -380,15 +381,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
expected_ty: Ty<'tcx>)
-> bool {
let parent_id = self.tcx.hir.get_parent_node(expr.id);
match self.tcx.hir.find(parent_id) {
Some(parent) => {
// Shouldn't suggest `.into()` on `const`s.
if let Node::Item(Item { node: ItemKind::Const(_, _), .. }) = parent {
// FIXME(estebank): modify once we decide to suggest `as` casts
return false;
}
if let Some(parent) = self.tcx.hir.find(parent_id) {
// Shouldn't suggest `.into()` on `const`s.
if let Node::Item(Item { node: ItemKind::Const(_, _), .. }) = parent {
// FIXME(estebank): modify once we decide to suggest `as` casts
return false;
}
None => {}
};
let will_truncate = "will truncate the source value";
@ -662,7 +660,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
expr.span,
&format!("{}, producing the floating point representation of the \
integer",
msg),
msg),
into_suggestion,
Applicability::MachineApplicable
);
@ -670,7 +668,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
err.span_suggestion_with_applicability(expr.span,
&format!("{}, producing the floating point representation of the \
integer, rounded if necessary",
msg),
msg),
cast_suggestion,
Applicability::MaybeIncorrect // lossy conversion
);
@ -684,7 +682,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
expr.span,
&format!("{}, producing the floating point representation of the \
integer",
msg),
msg),
into_suggestion,
Applicability::MachineApplicable
);
@ -693,7 +691,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
expr.span,
&format!("{}, producing the floating point representation of the \
integer, rounded if necessary",
msg),
msg),
cast_suggestion,
Applicability::MaybeIncorrect // lossy conversion
);

View File

@ -67,13 +67,8 @@ pub fn check_drop_impl<'a, 'tcx>(
// already checked by coherence, but compilation may
// not have been terminated.
let span = tcx.def_span(drop_impl_did);
tcx.sess.delay_span_bug(
span,
&format!(
"should have been rejected by coherence check: {}",
dtor_self_type
),
);
tcx.sess.delay_span_bug(span,
&format!("should have been rejected by coherence check: {}", dtor_self_type));
Err(ErrorReported)
}
}
@ -310,10 +305,8 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'gcx, 'tcx>(
body_id: ast::NodeId,
scope: region::Scope,
) -> Result<(), ErrorReported> {
debug!(
"check_safety_of_destructor_if_necessary typ: {:?} scope: {:?}",
ty, scope
);
debug!("check_safety_of_destructor_if_necessary typ: {:?} scope: {:?}",
ty, scope);
let parent_scope = match rcx.region_scope_tree.opt_encl_scope(scope) {
Some(parent_scope) => parent_scope,

View File

@ -48,7 +48,7 @@ impl<'a, 'gcx, 'tcx> InteriorVisitor<'a, 'gcx, 'tcx> {
// See the mega-comment at `yield_in_scope` for a proof.
debug!("comparing counts yield: {} self: {}, source_span = {:?}",
expr_count, self.expr_count, source_span);
expr_count, self.expr_count, source_span);
if expr_count >= self.expr_count {
Some(yield_span)

View File

@ -57,7 +57,7 @@ fn equate_intrinsic_type<'a, 'tcx>(
struct_span_err!(tcx.sess, span, E0094,
"intrinsic has wrong number of type \
parameters: found {}, expected {}",
parameters: found {}, expected {}",
i_n_tps, n_tps)
.span_label(span, format!("expected {} type parameter", n_tps))
.emit();
@ -83,7 +83,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let name = it.name.as_str();
let (n_tps, inputs, output, unsafety) = if name.starts_with("atomic_") {
let split : Vec<&str> = name.split('_').collect();
assert!(split.len() >= 2, "Atomic intrinsic not correct format");
assert!(split.len() >= 2, "Atomic intrinsic in an incorrect format");
//We only care about the operation here
let (n_tps, inputs, output) = match split[1] {
@ -127,8 +127,8 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
"size_of_val" | "min_align_of_val" => {
(1, vec![
tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::INNERMOST,
ty::BrAnon(0))),
param(0))
ty::BrAnon(0))),
param(0))
], tcx.types.usize)
}
"rustc_peek" => (1, vec![param(0)], param(0)),
@ -306,7 +306,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
"discriminant_value" => (1, vec![
tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::INNERMOST,
ty::BrAnon(0))),
ty::BrAnon(0))),
param(0))], tcx.types.u64),
"try" => {
@ -327,10 +327,10 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
ref other => {
struct_span_err!(tcx.sess, it.span, E0093,
"unrecognized intrinsic function: `{}`",
*other)
.span_label(it.span, "unrecognized intrinsic")
.emit();
"unrecognized intrinsic function: `{}`",
*other)
.span_label(it.span, "unrecognized intrinsic")
.emit();
return;
}
};

View File

@ -210,9 +210,6 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
target
}
///////////////////////////////////////////////////////////////////////////
//
/// Returns a set of substitutions for the method *receiver* where all type and region
/// parameters are instantiated with fresh variables. This substitution does not include any
/// parameters declared on the method itself.
@ -291,18 +288,18 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
self.fcx
.autoderef(self.span, self_ty)
.include_raw_pointers()
.filter_map(|(ty, _)| {
.filter_map(|(ty, _)|
match ty.sty {
ty::Dynamic(ref data, ..) => data.principal().map(|p| closure(self, ty, p)),
_ => None,
}
})
)
.next()
.unwrap_or_else(|| {
.unwrap_or_else(||
span_bug!(self.span,
"self-type `{}` for ObjectPick never dereferenced to an object",
self_ty)
})
)
}
fn instantiate_method_substs(
@ -373,9 +370,6 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
}
}
///////////////////////////////////////////////////////////////////////////
//
// NOTE: this returns the *unnormalized* predicates and method sig. Because of
// inference guessing, the predicates and method signature can't be normalized
// until we unify the `Self` type.
@ -444,11 +438,10 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
/// respectively.
fn convert_place_derefs_to_mutable(&self) {
// Gather up expressions we want to munge.
let mut exprs = Vec::new();
exprs.push(self.self_expr);
let mut exprs = vec![self.self_expr];
loop {
let last = exprs[exprs.len() - 1];
match last.node {
match exprs.last().unwrap().node {
hir::ExprKind::Field(ref expr, _) |
hir::ExprKind::Index(ref expr, _) |
hir::ExprKind::Unary(hir::UnDeref, ref expr) => exprs.push(&expr),

View File

@ -1255,9 +1255,8 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
{
// Do all probes correspond to the same trait?
let container = probes[0].0.item.container;
match container {
ty::TraitContainer(_) => {}
ty::ImplContainer(_) => return None,
if let ty::ImplContainer(_) = container {
return None
}
if probes[1..].iter().any(|&(p, _)| p.item.container != container) {
return None;
@ -1461,7 +1460,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
.filter(|x| {
let dist = lev_distance(&*name.as_str(), &x.ident.as_str());
Namespace::from(x.kind) == Namespace::Value && dist > 0
&& dist <= max_dist
&& dist <= max_dist
})
.collect()
} else {

View File

@ -88,7 +88,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
let report_candidates = |err: &mut DiagnosticBuilder, mut sources: Vec<CandidateSource>| {
sources.sort();
sources.dedup();
// Dynamic limit to avoid hiding just one candidate, which is silly.
@ -225,9 +224,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// ({integer}/{float}).
let mut candidates = all_traits(self.tcx)
.into_iter()
.filter(|info| {
self.associated_item(info.def_id, item_name, Namespace::Value).is_some()
});
.filter_map(|info|
self.associated_item(info.def_id, item_name, Namespace::Value)
);
if let (true, false, Some(expr), Some(_)) = (actual.is_numeric(),
actual.has_concrete_skeleton(),
rcvr_expr,
@ -247,9 +246,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
"f32"
};
match expr.node {
hir::ExprKind::Lit(ref lit) => { // numeric literal
hir::ExprKind::Lit(ref lit) => { // numeric literal
let snippet = tcx.sess.source_map().span_to_snippet(lit.span)
.unwrap_or("<numeric literal>".to_string());
.unwrap_or("<numeric literal>".to_owned());
err.span_suggestion_with_applicability(
lit.span,
@ -342,8 +341,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// give a helping note that it has to be called as (x.f)(...).
if let Some(expr) = rcvr_expr {
for (ty, _) in self.autoderef(span, rcvr_ty) {
match ty.sty {
ty::Adt(def, substs) if !def.is_enum() => {
if let ty::Adt(def, substs) = ty.sty {
if !def.is_enum() {
let variant = &def.non_enum_variant();
if let Some(index) = self.tcx.find_field_index(item_name, variant) {
let field = &variant.fields[index];
@ -377,7 +376,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
break;
}
}
_ => {}
}
}
} else {
@ -722,12 +720,9 @@ fn compute_all_traits<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Vec<DefId>
}
impl<'v, 'a, 'tcx> itemlikevisit::ItemLikeVisitor<'v> for Visitor<'a, 'tcx> {
fn visit_item(&mut self, i: &'v hir::Item) {
match i.node {
hir::ItemKind::Trait(..) => {
let def_id = self.map.local_def_id(i.id);
self.traits.push(def_id);
}
_ => {}
if let hir::ItemKind::Trait(..) = i.node {
let def_id = self.map.local_def_id(i.id);
self.traits.push(def_id);
}
}

View File

@ -662,7 +662,8 @@ impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
}
fn register_predicates<I>(&self, obligations: I)
where I: IntoIterator<Item = traits::PredicateObligation<'tcx>> {
where I: IntoIterator<Item = traits::PredicateObligation<'tcx>>
{
for obligation in obligations {
self.register_predicate(obligation);
}
@ -1150,19 +1151,16 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
if let Some(term_id) = fcx.tcx.lang_items().termination() {
if let Some((id, _, entry_type)) = *fcx.tcx.sess.entry_fn.borrow() {
if id == fn_id {
match entry_type {
config::EntryFnType::Main => {
let substs = fcx.tcx.mk_substs_trait(declared_ret_ty, &[]);
let trait_ref = ty::TraitRef::new(term_id, substs);
let return_ty_span = decl.output.span();
let cause = traits::ObligationCause::new(
return_ty_span, fn_id, ObligationCauseCode::MainFunctionType);
if let config::EntryFnType::Main = entry_type {
let substs = fcx.tcx.mk_substs_trait(declared_ret_ty, &[]);
let trait_ref = ty::TraitRef::new(term_id, substs);
let return_ty_span = decl.output.span();
let cause = traits::ObligationCause::new(
return_ty_span, fn_id, ObligationCauseCode::MainFunctionType);
inherited.register_predicate(
traits::Obligation::new(
cause, param_env, trait_ref.to_predicate()));
},
config::EntryFnType::Start => {},
inherited.register_predicate(
traits::Obligation::new(
cause, param_env, trait_ref.to_predicate()));
}
}
}
@ -1540,10 +1538,10 @@ fn check_impl_items_against_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
impl_trait_ref);
} else {
let mut err = struct_span_err!(tcx.sess, impl_item.span, E0323,
"item `{}` is an associated const, \
which doesn't match its trait `{}`",
ty_impl_item.ident,
impl_trait_ref);
"item `{}` is an associated const, \
which doesn't match its trait `{}`",
ty_impl_item.ident,
impl_trait_ref);
err.span_label(impl_item.span, "does not match trait");
// We can only get the spans from local trait definition
// Same for E0324 and E0325
@ -1564,10 +1562,10 @@ fn check_impl_items_against_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
trait_span);
} else {
let mut err = struct_span_err!(tcx.sess, impl_item.span, E0324,
"item `{}` is an associated method, \
which doesn't match its trait `{}`",
ty_impl_item.ident,
impl_trait_ref);
"item `{}` is an associated method, \
which doesn't match its trait `{}`",
ty_impl_item.ident,
impl_trait_ref);
err.span_label(impl_item.span, "does not match trait");
if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
err.span_label(trait_span, "item in trait");
@ -1583,10 +1581,10 @@ fn check_impl_items_against_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
} else {
let mut err = struct_span_err!(tcx.sess, impl_item.span, E0325,
"item `{}` is an associated type, \
which doesn't match its trait `{}`",
ty_impl_item.ident,
impl_trait_ref);
"item `{}` is an associated type, \
which doesn't match its trait `{}`",
ty_impl_item.ident,
impl_trait_ref);
err.span_label(impl_item.span, "does not match trait");
if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
err.span_label(trait_span, "item in trait");
@ -1624,8 +1622,8 @@ fn check_impl_items_against_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let mut err = struct_span_err!(tcx.sess, impl_span, E0046,
"not all trait items implemented, missing: `{}`",
missing_items.iter()
.map(|trait_item| trait_item.ident.to_string())
.collect::<Vec<_>>().join("`, `"));
.map(|trait_item| trait_item.ident.to_string())
.collect::<Vec<_>>().join("`, `"));
err.span_label(impl_span, format!("missing `{}` in implementation",
missing_items.iter()
.map(|trait_item| trait_item.ident.to_string())
@ -1683,8 +1681,8 @@ fn check_representable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
pub fn check_simd<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
let t = tcx.type_of(def_id);
match t.sty {
ty::Adt(def, substs) if def.is_struct() => {
if let ty::Adt(def, substs) = t.sty {
if def.is_struct() {
let fields = &def.non_enum_variant().fields;
if fields.is_empty() {
span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
@ -1699,7 +1697,7 @@ pub fn check_simd<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId
}
match e.sty {
ty::Param(_) => { /* struct<T>(T, T, T, T) is ok */ }
_ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
_ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
_ => {
span_err!(tcx.sess, sp, E0077,
"SIMD vector element type should be machine type");
@ -1707,7 +1705,6 @@ pub fn check_simd<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId
}
}
}
_ => ()
}
}
@ -1743,8 +1740,8 @@ fn check_packed_inner<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
debug!("check_packed_inner: {:?} is recursive", t);
return false;
}
match t.sty {
ty::Adt(def, substs) if def.is_struct() || def.is_union() => {
if let ty::Adt(def, substs) = t.sty {
if def.is_struct() || def.is_union() {
if tcx.adt_def(def.did).repr.align > 0 {
return true;
}
@ -1752,19 +1749,15 @@ fn check_packed_inner<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
stack.push(def_id);
for field in &def.non_enum_variant().fields {
let f = field.ty(tcx, substs);
match f.sty {
ty::Adt(def, _) => {
if check_packed_inner(tcx, def.did, stack) {
return true;
}
if let ty::Adt(def, _) = f.sty {
if check_packed_inner(tcx, def.did, stack) {
return true;
}
_ => ()
}
}
// only need to pop if not early out
stack.pop();
}
_ => ()
}
false
}
@ -1793,7 +1786,7 @@ fn check_transparent<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: De
let field_spans: Vec<_> = non_zst_fields.map(|(span, _zst, _align1)| *span).collect();
struct_span_err!(tcx.sess, sp, E0690,
"transparent struct needs exactly one non-zero-sized field, but has {}",
non_zst_count)
non_zst_count)
.span_note(field_spans, "non-zero-sized field")
.emit();
}
@ -1842,7 +1835,7 @@ pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
}
let mut disr_vals: Vec<Discr<'tcx>> = Vec::new();
let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
for (discr, v) in def.discriminants(tcx).zip(vs) {
// Check for duplicate discriminant values
if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
@ -2078,13 +2071,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> LocalTy<'tcx> {
match self.locals.borrow().get(&nid) {
Some(&t) => t,
None => {
span_bug!(span, "no type for local variable {}",
self.tcx.hir.node_to_string(nid));
}
}
self.locals.borrow().get(&nid).cloned().unwrap_or_else(||
span_bug!(span, "no type for local variable {}",
self.tcx.hir.node_to_string(nid))
)
}
#[inline]
@ -2373,8 +2363,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
/// Registers obligations that all types appearing in `substs` are well-formed.
pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
{
pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr) {
for ty in substs.types() {
self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
}
@ -2421,8 +2410,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
substs: &Substs<'tcx>)
-> Ty<'tcx>
{
self.normalize_associated_types_in(span,
&field.ty(self.tcx, substs))
self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
}
fn check_casts(&self) {
@ -2473,11 +2461,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
/// Select as many obligations as we can at present.
fn select_obligations_where_possible(&self, fallback_has_occurred: bool) {
match self.fulfillment_cx.borrow_mut().select_where_possible(self) {
Ok(()) => { }
Err(errors) => {
self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
},
if let Err(errors) = self.fulfillment_cx.borrow_mut().select_where_possible(self) {
self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
}
}
@ -2772,17 +2757,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let expected_arg_count = fn_inputs.len();
let param_count_error = |expected_count: usize,
arg_count: usize,
error_code: &str,
variadic: bool,
sugg_unit: bool| {
arg_count: usize,
error_code: &str,
variadic: bool,
sugg_unit: bool| {
let mut err = tcx.sess.struct_span_err_with_code(sp,
&format!("this function takes {}{} parameter{} but {} parameter{} supplied",
&format!("this function takes {}{} but {} {} supplied",
if variadic {"at least "} else {""},
expected_count,
if expected_count == 1 {""} else {"s"},
arg_count,
if arg_count == 1 {" was"} else {"s were"}),
potentially_plural_count(expected_count, "parameter"),
potentially_plural_count(arg_count, "parameter"),
if arg_count == 1 {"was"} else {"were"}),
DiagnosticId::Error(error_code.to_owned()));
if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().def_span(sp)) {
@ -2798,10 +2782,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
String::from("()"),
Applicability::MachineApplicable);
} else {
err.span_label(sp, format!("expected {}{} parameter{}",
if variadic {"at least "} else {""},
expected_count,
if expected_count == 1 {""} else {"s"}));
err.span_label(sp, format!("expected {}{}",
if variadic {"at least "} else {""},
potentially_plural_count(expected_count, "parameter")));
}
err.emit();
};
@ -2967,7 +2950,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
(0..len).map(|_| self.tcx.types.err).collect()
vec![self.tcx.types.err; len]
}
// AST fragment checking
@ -2982,7 +2965,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
ast::LitKind::Str(..) => tcx.mk_static_str(),
ast::LitKind::ByteStr(ref v) => {
tcx.mk_imm_ref(tcx.types.re_static,
tcx.mk_array(tcx.types.u8, v.len() as u64))
tcx.mk_array(tcx.types.u8, v.len() as u64))
}
ast::LitKind::Byte(_) => tcx.types.u8,
ast::LitKind::Char(_) => tcx.types.char,
@ -3051,23 +3034,22 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
if let Some(mut err) = self.demand_suptype_diag(expr.span, expected_ty, ty) {
// Add help to type error if this is an `if` condition with an assignment
match (expected, &expr.node) {
(ExpectIfCondition, &hir::ExprKind::Assign(ref lhs, ref rhs)) => {
let msg = "try comparing for equality";
if let (Ok(left), Ok(right)) = (
self.tcx.sess.source_map().span_to_snippet(lhs.span),
self.tcx.sess.source_map().span_to_snippet(rhs.span))
{
err.span_suggestion_with_applicability(
expr.span,
msg,
format!("{} == {}", left, right),
Applicability::MaybeIncorrect);
} else {
err.help(msg);
}
if let (ExpectIfCondition, &hir::ExprKind::Assign(ref lhs, ref rhs))
= (expected, &expr.node)
{
let msg = "try comparing for equality";
if let (Ok(left), Ok(right)) = (
self.tcx.sess.source_map().span_to_snippet(lhs.span),
self.tcx.sess.source_map().span_to_snippet(rhs.span))
{
err.span_suggestion_with_applicability(
expr.span,
msg,
format!("{} == {}", left, right),
Applicability::MaybeIncorrect);
} else {
err.help(msg);
}
_ => (),
}
err.emit();
}
@ -3355,8 +3337,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
self.tcx().types.err
} else if self.method_exists(field, expr_t, expr.id, true) {
type_error_struct!(self.tcx().sess, field.span, expr_t, E0615,
"attempted to take value of method `{}` on type `{}`",
field, expr_t)
"attempted to take value of method `{}` on type `{}`",
field, expr_t)
.help("maybe a `()` to call it is missing?")
.emit();
self.tcx().types.err
@ -3441,14 +3423,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
fn available_field_names(&self, variant: &'tcx ty::VariantDef) -> Vec<ast::Name> {
let mut available = Vec::new();
for field in variant.fields.iter() {
variant.fields.iter().filter(|field| {
let def_scope = self.tcx.adjust_ident(field.ident, variant.did, self.body_id).1;
if field.vis.is_accessible_from(def_scope, self.tcx) {
available.push(field.ident.name);
}
}
available
field.vis.is_accessible_from(def_scope, self.tcx)
})
.map(|field| field.ident.name)
.collect()
}
fn name_series_display(&self, names: Vec<ast::Name>) -> String {
@ -3480,13 +3460,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|actual| match ty.sty {
ty::Adt(adt, ..) if adt.is_enum() => {
struct_span_err!(self.tcx.sess, field.ident.span, E0559,
"{} `{}::{}` has no field named `{}`",
kind_name, actual, variant.name, field.ident)
"{} `{}::{}` has no field named `{}`",
kind_name, actual, variant.name, field.ident)
}
_ => {
struct_span_err!(self.tcx.sess, field.ident.span, E0560,
"{} `{}` has no field named `{}`",
kind_name, actual, field.ident)
"{} `{}` has no field named `{}`",
kind_name, actual, field.ident)
}
},
ty);
@ -3571,10 +3551,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
error_happened = true;
if let Some(prev_span) = seen_fields.get(&ident) {
let mut err = struct_span_err!(self.tcx.sess,
field.ident.span,
E0062,
"field `{}` specified more than once",
ident);
field.ident.span,
E0062,
"field `{}` specified more than once",
ident);
err.span_label(field.ident.span, "used more than once");
err.span_label(*prev_span, format!("first use of `{}`", ident));
@ -3638,11 +3618,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
for field in fields {
self.check_expr(&field.expr);
}
match *base_expr {
Some(ref base) => {
self.check_expr(&base);
},
None => {}
if let Some(ref base) = *base_expr {
self.check_expr(&base);
}
}
@ -3972,11 +3949,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
ty
}
hir::ExprKind::InlineAsm(_, ref outputs, ref inputs) => {
for output in outputs {
self.check_expr(output);
}
for input in inputs {
self.check_expr(input);
for expr in outputs.iter().chain(inputs.iter()) {
self.check_expr(expr);
}
tcx.mk_unit()
}
@ -4075,7 +4049,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
hir::ExprKind::Ret(ref expr_opt) => {
if self.ret_coercion.is_none() {
struct_span_err!(self.tcx.sess, expr.span, E0572,
"return statement outside of function body").emit();
"return statement outside of function body").emit();
} else if let Some(ref e) = *expr_opt {
self.check_return_expr(e);
} else {
@ -4393,7 +4367,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
if needs_note {
err.help("to access tuple elements, use tuple indexing \
syntax (e.g. `tuple.0`)");
syntax (e.g. `tuple.0`)");
}
}
err.emit();
@ -4409,7 +4383,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
None => {
struct_span_err!(self.tcx.sess, expr.span, E0627,
"yield statement outside of generator literal").emit();
"yield statement outside of generator literal").emit();
}
}
tcx.mk_unit()
@ -4523,7 +4497,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
}
pub fn check_decl_local(&self, local: &'gcx hir::Local) {
pub fn check_decl_local(&self, local: &'gcx hir::Local) {
let t = self.local_ty(local.span, local.id).decl_ty;
self.write_ty(local.hir_id, t);
@ -4547,11 +4521,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// Don't do all the complex logic below for DeclItem.
match stmt.node {
hir::StmtKind::Decl(ref decl, _) => {
match decl.node {
hir::DeclKind::Local(_) => {}
hir::DeclKind::Item(_) => {
return;
}
if let hir::DeclKind::Item(_) = decl.node {
return
}
}
hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
@ -4809,7 +4780,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
Some(format!("{}{}", receiver, method_call))
}
}
}) .collect::<Vec<_>>();
}).collect::<Vec<_>>();
if !suggestions.is_empty() {
err.span_suggestions_with_applicability(
expr.span,
@ -5286,18 +5257,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// If our calling expression is indeed the function itself, we're good!
// If not, generate an error that this can only be called directly.
match self.tcx.hir.get(self.tcx.hir.get_parent_node(node_id)) {
Node::Expr(expr) => {
match expr.node {
hir::ExprKind::Call(ref callee, ..) => {
if callee.id == node_id {
return
}
}
_ => {}
if let Node::Expr(expr) = self.tcx.hir.get(self.tcx.hir.get_parent_node(node_id)) {
if let hir::ExprKind::Call(ref callee, ..) = expr.node {
if callee.id == node_id {
return
}
}
_ => {}
}
self.tcx.sess.span_err(span, "this function can only be invoked \
@ -5323,8 +5288,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
fn with_breakable_ctxt<F: FnOnce() -> R, R>(&self, id: ast::NodeId,
ctxt: BreakableCtxt<'gcx, 'tcx>, f: F)
-> (BreakableCtxt<'gcx, 'tcx>, R) {
ctxt: BreakableCtxt<'gcx, 'tcx>, f: F)
-> (BreakableCtxt<'gcx, 'tcx>, R) {
let index;
{
let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
@ -5398,3 +5363,7 @@ fn fatally_break_rust(sess: &Session) {
::session::config::host_triple(),
));
}
fn potentially_plural_count(count: usize, word: &str) -> String {
format!("{} {}{}", count, word, if count == 1 { "" } else { "s" })
}

View File

@ -311,7 +311,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
hir::BinOpKind::BitOr => Some("std::ops::BitOrAssign"),
hir::BinOpKind::Shl => Some("std::ops::ShlAssign"),
hir::BinOpKind::Shr => Some("std::ops::ShrAssign"),
_ => None
_ => None
};
if let Some(missing_trait) = missing_trait {
if op.node == hir::BinOpKind::Add &&
@ -338,15 +338,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
IsAssign::No => {
let mut err = struct_span_err!(self.tcx.sess, expr.span, E0369,
"binary operation `{}` cannot be applied to type `{}`",
op.node.as_str(),
lhs_ty);
"binary operation `{}` cannot be applied to type `{}`",
op.node.as_str(),
lhs_ty);
let mut suggested_deref = false;
if let Ref(_, mut rty, _) = lhs_ty.sty {
if {
!self.infcx.type_moves_by_default(self.param_env,
rty,
lhs_expr.span) &&
rty,
lhs_expr.span) &&
self.lookup_op_method(rty,
&[rhs_ty],
Op::Binary(op, is_assign))

View File

@ -947,8 +947,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
}
fn check_safety_of_rvalue_destructor_if_necessary(&mut self, cmt: &mc::cmt_<'tcx>, span: Span) {
match cmt.cat {
Categorization::Rvalue(region) => match *region {
if let Categorization::Rvalue(region) = cmt.cat {
match *region {
ty::ReScope(rvalue_scope) => {
let typ = self.resolve_type(cmt.ty);
let body_id = self.body_id;
@ -969,8 +969,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
region
);
}
},
_ => {}
}
}
}
@ -1118,25 +1117,22 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
);
ignore_err!(self.with_mc(|mc| {
mc.cat_pattern(discr_cmt, root_pat, |sub_cmt, sub_pat| {
match sub_pat.node {
// `ref x` pattern
PatKind::Binding(..) => {
if let Some(&bm) = mc.tables.pat_binding_modes().get(sub_pat.hir_id) {
if let ty::BindByReference(mutbl) = bm {
self.link_region_from_node_type(
sub_pat.span,
sub_pat.hir_id,
mutbl,
&sub_cmt,
);
}
} else {
self.tcx
.sess
.delay_span_bug(sub_pat.span, "missing binding mode");
// `ref x` pattern
if let PatKind::Binding(..) = sub_pat.node {
if let Some(&bm) = mc.tables.pat_binding_modes().get(sub_pat.hir_id) {
if let ty::BindByReference(mutbl) = bm {
self.link_region_from_node_type(
sub_pat.span,
sub_pat.hir_id,
mutbl,
&sub_cmt,
);
}
} else {
self.tcx
.sess
.delay_span_bug(sub_pat.span, "missing binding mode");
}
_ => {}
}
})
}));

View File

@ -73,15 +73,11 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for InferBorrowKindVisitor<'a, 'gcx, 'tcx> {
}
fn visit_expr(&mut self, expr: &'gcx hir::Expr) {
match expr.node {
hir::ExprKind::Closure(cc, _, body_id, _, _) => {
let body = self.fcx.tcx.hir.body(body_id);
self.visit_body(body);
self.fcx
.analyze_closure(expr.id, expr.hir_id, expr.span, body, cc);
}
_ => {}
if let hir::ExprKind::Closure(cc, _, body_id, _, _) = expr.node {
let body = self.fcx.tcx.hir.body(body_id);
self.visit_body(body);
self.fcx
.analyze_closure(expr.id, expr.hir_id, expr.span, body, cc);
}
intravisit::walk_expr(self, expr);
@ -335,49 +331,46 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> {
"adjust_upvar_borrow_kind_for_consume: guarantor.cat={:?}",
guarantor.cat
);
match guarantor.cat {
Categorization::Deref(_, mc::BorrowedPtr(..)) => {
debug!(
"adjust_upvar_borrow_kind_for_consume: found deref with note {:?}",
cmt.note
);
match guarantor.note {
mc::NoteUpvarRef(upvar_id) => {
debug!(
"adjust_upvar_borrow_kind_for_consume: \
setting upvar_id={:?} to by value",
upvar_id
);
if let Categorization::Deref(_, mc::BorrowedPtr(..)) = guarantor.cat {
debug!(
"adjust_upvar_borrow_kind_for_consume: found deref with note {:?}",
cmt.note
);
match guarantor.note {
mc::NoteUpvarRef(upvar_id) => {
debug!(
"adjust_upvar_borrow_kind_for_consume: \
setting upvar_id={:?} to by value",
upvar_id
);
// to move out of an upvar, this must be a FnOnce closure
self.adjust_closure_kind(
upvar_id.closure_expr_id,
ty::ClosureKind::FnOnce,
guarantor.span,
var_name(tcx, upvar_id.var_id),
);
// to move out of an upvar, this must be a FnOnce closure
self.adjust_closure_kind(
upvar_id.closure_expr_id,
ty::ClosureKind::FnOnce,
guarantor.span,
var_name(tcx, upvar_id.var_id),
);
self.adjust_upvar_captures
.insert(upvar_id, ty::UpvarCapture::ByValue);
}
mc::NoteClosureEnv(upvar_id) => {
// we get just a closureenv ref if this is a
// `move` closure, or if the upvar has already
// been inferred to by-value. In any case, we
// must still adjust the kind of the closure
// to be a FnOnce closure to permit moves out
// of the environment.
self.adjust_closure_kind(
upvar_id.closure_expr_id,
ty::ClosureKind::FnOnce,
guarantor.span,
var_name(tcx, upvar_id.var_id),
);
}
mc::NoteIndex | mc::NoteNone => {}
self.adjust_upvar_captures
.insert(upvar_id, ty::UpvarCapture::ByValue);
}
mc::NoteClosureEnv(upvar_id) => {
// we get just a closureenv ref if this is a
// `move` closure, or if the upvar has already
// been inferred to by-value. In any case, we
// must still adjust the kind of the closure
// to be a FnOnce closure to permit moves out
// of the environment.
self.adjust_closure_kind(
upvar_id.closure_expr_id,
ty::ClosureKind::FnOnce,
guarantor.span,
var_name(tcx, upvar_id.var_id),
);
}
mc::NoteIndex | mc::NoteNone => {}
}
_ => {}
}
}

View File

@ -77,8 +77,8 @@ pub fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: Def
let item = tcx.hir.expect_item(node_id);
debug!("check_item_well_formed(it.id={}, it.name={})",
item.id,
tcx.item_path_str(def_id));
item.id,
tcx.item_path_str(def_id));
match item.node {
// Right now we check that every default trait implementation
@ -110,8 +110,8 @@ pub fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: Def
// FIXME(#27579) what amount of WF checking do we need for neg impls?
if trait_ref.is_some() && !is_auto {
span_err!(tcx.sess, item.span, E0192,
"negative impls are only allowed for \
auto traits (e.g., `Send` and `Sync`)")
"negative impls are only allowed for \
auto traits (e.g., `Send` and `Sync`)")
}
}
}
@ -175,9 +175,9 @@ pub fn check_impl_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
}
fn check_associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
item_id: ast::NodeId,
span: Span,
sig_if_method: Option<&hir::MethodSig>) {
item_id: ast::NodeId,
span: Span,
sig_if_method: Option<&hir::MethodSig>) {
let code = ObligationCauseCode::MiscObligation;
for_id(tcx, item_id, span).with_fcx(|fcx, tcx| {
let item = fcx.tcx.associated_item(fcx.tcx.hir.local_def_id(item_id));
@ -185,7 +185,7 @@ fn check_associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let (mut implied_bounds, self_ty) = match item.container {
ty::TraitContainer(_) => (vec![], fcx.tcx.mk_self_type()),
ty::ImplContainer(def_id) => (fcx.impl_implied_bounds(def_id, span),
fcx.tcx.type_of(def_id))
fcx.tcx.type_of(def_id))
};
match item.kind {
@ -199,7 +199,7 @@ fn check_associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let sig = fcx.tcx.fn_sig(item.def_id);
let sig = fcx.normalize_associated_types_in(span, &sig);
check_fn_or_method(tcx, fcx, span, sig,
item.def_id, &mut implied_bounds);
item.def_id, &mut implied_bounds);
let sig_if_method = sig_if_method.expect("bad signature for method");
check_method_receiver(fcx, sig_if_method, &item, self_ty);
}
@ -220,12 +220,12 @@ fn check_associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
fn for_item<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, item: &hir::Item)
-> CheckWfFcxBuilder<'a, 'gcx, 'tcx> {
-> CheckWfFcxBuilder<'a, 'gcx, 'tcx> {
for_id(tcx, item.id, item.span)
}
fn for_id<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, id: ast::NodeId, span: Span)
-> CheckWfFcxBuilder<'a, 'gcx, 'tcx> {
-> CheckWfFcxBuilder<'a, 'gcx, 'tcx> {
let def_id = tcx.hir.local_def_id(id);
CheckWfFcxBuilder {
inherited: Inherited::build(tcx, def_id),
@ -330,14 +330,12 @@ fn check_item_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) {
let sig = fcx.normalize_associated_types_in(item.span, &sig);
let mut implied_bounds = vec![];
check_fn_or_method(tcx, fcx, item.span, sig,
def_id, &mut implied_bounds);
def_id, &mut implied_bounds);
implied_bounds
})
}
fn check_item_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
item: &hir::Item)
{
fn check_item_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) {
debug!("check_item_type: {:?}", item);
for_item(tcx, item).with_fcx(|fcx, _this| {
@ -351,9 +349,9 @@ fn check_item_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
item: &hir::Item,
ast_self_ty: &hir::Ty,
ast_trait_ref: &Option<hir::TraitRef>)
item: &hir::Item,
ast_self_ty: &hir::Ty,
ast_trait_ref: &Option<hir::TraitRef>)
{
debug!("check_impl: {:?}", item);
@ -484,11 +482,8 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(
let substituted_pred = pred.subst(fcx.tcx, substs);
// Don't check non-defaulted params, dependent defaults (including lifetimes)
// or preds with multiple params.
if {
substituted_pred.references_error() || param_count.params.len() > 1
|| has_region
} {
None
if substituted_pred.references_error() || param_count.params.len() > 1 || has_region {
None
} else if predicates.predicates.contains(&substituted_pred) {
// Avoid duplication of predicates that contain no parameters, for example.
None
@ -535,11 +530,11 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(
}
fn check_fn_or_method<'a, 'fcx, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
span: Span,
sig: ty::PolyFnSig<'tcx>,
def_id: DefId,
implied_bounds: &mut Vec<Ty<'tcx>>)
fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
span: Span,
sig: ty::PolyFnSig<'tcx>,
def_id: DefId,
implied_bounds: &mut Vec<Ty<'tcx>>)
{
let sig = fcx.normalize_associated_types_in(span, &sig);
let sig = fcx.tcx.liberate_late_bound_regions(def_id, &sig);
@ -702,7 +697,7 @@ fn check_method_receiver<'fcx, 'gcx, 'tcx>(fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
{
// check that the method has a valid receiver type, given the type `Self`
debug!("check_method_receiver({:?}, self_ty={:?})",
method, self_ty);
method, self_ty);
if !method.method_has_self_argument {
return;
@ -806,14 +801,14 @@ fn check_variances_for_type_defn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let mut constrained_parameters: FxHashSet<_> =
variances.iter().enumerate()
.filter(|&(_, &variance)| variance != ty::Bivariant)
.map(|(index, _)| Parameter(index as u32))
.collect();
.filter(|&(_, &variance)| variance != ty::Bivariant)
.map(|(index, _)| Parameter(index as u32))
.collect();
identify_constrained_type_params(tcx,
ty_predicates.predicates.as_slice(),
None,
&mut constrained_parameters);
ty_predicates.predicates.as_slice(),
None,
&mut constrained_parameters);
for (index, _) in variances.iter().enumerate() {
if constrained_parameters.contains(&Parameter(index as u32)) {
@ -826,22 +821,17 @@ fn check_variances_for_type_defn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
fn report_bivariance<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
span: Span,
param_name: ast::Name)
span: Span,
param_name: ast::Name)
{
let mut err = error_392(tcx, span, param_name);
let suggested_marker_id = tcx.lang_items().phantom_data();
match suggested_marker_id {
Some(def_id) => {
err.help(
&format!("consider removing `{}` or using a marker such as `{}`",
param_name,
tcx.item_path_str(def_id)));
}
None => {
// no lang items, no help!
}
// help is available only in presence of lang items
if let Some(def_id) = suggested_marker_id {
err.help(&format!("consider removing `{}` or using a marker such as `{}`",
param_name,
tcx.item_path_str(def_id)));
}
err.emit();
}
@ -855,11 +845,10 @@ fn reject_shadowing_parameters(tcx: TyCtxt, def_id: DefId) {
}).collect();
for method_param in &generics.params {
match method_param.kind {
// Shadowing is checked in resolve_lifetime.
GenericParamDefKind::Lifetime => continue,
_ => {},
};
// Shadowing is checked in resolve_lifetime.
if let GenericParamDefKind::Lifetime = method_param.kind {
continue
}
if impl_params.contains_key(&method_param.name) {
// Tighten up the span to focus on only the shadowing type
let type_span = tcx.def_span(method_param.def_id);
@ -876,10 +865,10 @@ fn reject_shadowing_parameters(tcx: TyCtxt, def_id: DefId) {
/// Feature gates RFC 2056 - trivial bounds, checking for global bounds that
/// aren't true.
fn check_false_global_bounds<'a, 'gcx, 'tcx>(
fcx: &FnCtxt<'a, 'gcx, 'tcx>,
span: Span,
id: ast::NodeId,
) {
fcx: &FnCtxt<'a, 'gcx, 'tcx>,
span: Span,
id: ast::NodeId)
{
use rustc::ty::TypeFoldable;
let empty_env = ty::ParamEnv::empty();
@ -963,15 +952,13 @@ struct AdtField<'tcx> {
impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
fn non_enum_variant(&self, struct_def: &hir::VariantData) -> AdtVariant<'tcx> {
let fields =
struct_def.fields().iter()
.map(|field| {
let field_ty = self.tcx.type_of(self.tcx.hir.local_def_id(field.id));
let field_ty = self.normalize_associated_types_in(field.span,
&field_ty);
AdtField { ty: field_ty, span: field.span }
})
.collect();
let fields = struct_def.fields().iter().map(|field| {
let field_ty = self.tcx.type_of(self.tcx.hir.local_def_id(field.id));
let field_ty = self.normalize_associated_types_in(field.span,
&field_ty);
AdtField { ty: field_ty, span: field.span }
})
.collect();
AdtVariant { fields: fields }
}
@ -1010,8 +997,8 @@ fn error_392<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span, param_name: ast:
fn error_194(tcx: TyCtxt, span: Span, trait_decl_span: Span, name: &str) {
struct_span_err!(tcx.sess, span, E0194,
"type parameter `{}` shadows another type parameter of the same name",
name)
"type parameter `{}` shadows another type parameter of the same name",
name)
.span_label(span, "shadows another type parameter")
.span_label(trait_decl_span, format!("first `{}` declared here", name))
.emit();

View File

@ -178,39 +178,34 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
if let hir::ExprKind::Index(ref base, ref index) = e.node {
let mut tables = self.fcx.tables.borrow_mut();
match tables.expr_ty_adjusted(&base).sty {
// All valid indexing looks like this
ty::Ref(_, base_ty, _) => {
let index_ty = tables.expr_ty_adjusted(&index);
let index_ty = self.fcx.resolve_type_vars_if_possible(&index_ty);
// 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);
if base_ty.builtin_index().is_some() && index_ty == self.fcx.tcx.types.usize {
// Remove the method call record
tables.type_dependent_defs_mut().remove(e.hir_id);
tables.node_substs_mut().remove(e.hir_id);
if base_ty.builtin_index().is_some() && index_ty == self.fcx.tcx.types.usize {
// Remove the method call record
tables.type_dependent_defs_mut().remove(e.hir_id);
tables.node_substs_mut().remove(e.hir_id);
tables.adjustments_mut().get_mut(base.hir_id).map(|a| {
// Discard the need for a mutable borrow
match a.pop() {
// Extra adjustment made when indexing causes a drop
// of size information - we need to get rid of it
// Since this is "after" the other adjustment to be
// discarded, we do an extra `pop()`
Some(Adjustment {
kind: Adjust::Unsize,
..
}) => {
// So the borrow discard actually happens here
a.pop();
}
_ => {}
tables.adjustments_mut().get_mut(base.hir_id).map(|a| {
// Discard the need for a mutable borrow
match a.pop() {
// Extra adjustment made when indexing causes a drop
// of size information - we need to get rid of it
// Since this is "after" the other adjustment to be
// discarded, we do an extra `pop()`
Some(Adjustment {
kind: Adjust::Unsize,
..
}) => {
// So the borrow discard actually happens here
a.pop();
}
});
}
_ => {}
}
});
}
// Might encounter non-valid indexes at this point, so there
// has to be a fall-through
_ => {}
}
}
}
@ -445,7 +440,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
span,
&format!(
"type parameter `{}` is part of concrete type but not used \
in parameter list for existential type",
in parameter list for existential type",
ty,
),
)
@ -767,10 +762,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Resolver<'cx, 'gcx, 'tcx> {
// FIXME This should be carefully checked
// We could use `self.report_error` but it doesn't accept a ty::Region, right now.
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
match self.infcx.fully_resolve(&r) {
Ok(r) => r,
Err(_) => self.tcx.types.re_static,
}
self.infcx.fully_resolve(&r).unwrap_or(self.tcx.types.re_static)
}
}