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:
commit
f1694eac74
@ -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;
|
||||
|
@ -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
|
||||
);
|
||||
|
@ -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)
|
||||
|
@ -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(
|
||||
|
@ -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))
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
);
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
@ -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),
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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" })
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
})
|
||||
}));
|
||||
|
@ -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 => {}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user