Auto merge of #60329 - Centril:rollup-wv8g1ex, r=Centril
Rollup of 5 pull requests Successful merges: - #60292 (Replace the `&'tcx List<Ty<'tcx>>` in `TyKind::Tuple` with `SubstsRef<'tcx>`) - #60307 (Make "Implementations on Foreign Types" items in sidebar link to specific impls) - #60309 (Add 1.34.1 release notes) - #60315 (bootstrap: use correct version numbers for llvm-tools and lldb) - #60316 (Use "capacity" as parameter name in with_capacity() methods) Failed merges: r? @ghost
This commit is contained in:
commit
c751c7a4f4
11
RELEASES.md
11
RELEASES.md
@ -1,3 +1,14 @@
|
||||
Version 1.34.1 (2019-04-25)
|
||||
===========================
|
||||
|
||||
* [Fix false positives for the `redundant_closure` Clippy lint][clippy/3821]
|
||||
* [Fix false positives for the `missing_const_for_fn` Clippy lint][clippy/3844]
|
||||
* [Fix Clippy panic when checking some macros][clippy/3805]
|
||||
|
||||
[clippy/3821]: https://github.com/rust-lang/rust-clippy/pull/3821
|
||||
[clippy/3844]: https://github.com/rust-lang/rust-clippy/pull/3844
|
||||
[clippy/3805]: https://github.com/rust-lang/rust-clippy/pull/3805
|
||||
|
||||
Version 1.34.0 (2019-04-11)
|
||||
==========================
|
||||
|
||||
|
@ -1049,7 +1049,7 @@ impl Build {
|
||||
}
|
||||
|
||||
fn llvm_tools_package_vers(&self) -> String {
|
||||
self.package_vers(&self.rust_version())
|
||||
self.package_vers(channel::CFG_RELEASE_NUM)
|
||||
}
|
||||
|
||||
fn llvm_tools_vers(&self) -> String {
|
||||
@ -1057,7 +1057,7 @@ impl Build {
|
||||
}
|
||||
|
||||
fn lldb_package_vers(&self) -> String {
|
||||
self.package_vers(&self.rust_version())
|
||||
self.package_vers(channel::CFG_RELEASE_NUM)
|
||||
}
|
||||
|
||||
fn lldb_vers(&self) -> String {
|
||||
|
@ -369,7 +369,7 @@ impl<T> VecDeque<T> {
|
||||
VecDeque::with_capacity(INITIAL_CAPACITY)
|
||||
}
|
||||
|
||||
/// Creates an empty `VecDeque` with space for at least `n` elements.
|
||||
/// Creates an empty `VecDeque` with space for at least `capacity` elements.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -379,10 +379,10 @@ impl<T> VecDeque<T> {
|
||||
/// let vector: VecDeque<u32> = VecDeque::with_capacity(10);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn with_capacity(n: usize) -> VecDeque<T> {
|
||||
pub fn with_capacity(capacity: usize) -> VecDeque<T> {
|
||||
// +1 since the ringbuffer always leaves one space empty
|
||||
let cap = cmp::max(n + 1, MINIMUM_CAPACITY + 1).next_power_of_two();
|
||||
assert!(cap > n, "capacity overflow");
|
||||
let cap = cmp::max(capacity + 1, MINIMUM_CAPACITY + 1).next_power_of_two();
|
||||
assert!(cap > capacity, "capacity overflow");
|
||||
|
||||
VecDeque {
|
||||
tail: 0,
|
||||
|
@ -47,7 +47,7 @@ impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> {
|
||||
let field_def = &variant_def.fields[f.index()];
|
||||
field_def.ty(tcx, substs)
|
||||
}
|
||||
ty::Tuple(ref tys) => tys[f.index()],
|
||||
ty::Tuple(ref tys) => tys[f.index()].expect_ty(),
|
||||
_ => bug!("extracting field of non-tuple non-adt: {:?}", self),
|
||||
};
|
||||
debug!("field_ty self: {:?} f: {:?} yields: {:?}", self, f, answer);
|
||||
|
@ -875,7 +875,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
let expected_ty = expected_trait_ref.skip_binder().substs.type_at(1);
|
||||
let expected = match expected_ty.sty {
|
||||
ty::Tuple(ref tys) => tys.iter()
|
||||
.map(|t| ArgKind::from_expected_ty(t, Some(span))).collect(),
|
||||
.map(|t| ArgKind::from_expected_ty(t.expect_ty(), Some(span))).collect(),
|
||||
_ => vec![ArgKind::Arg("_".to_owned(), expected_ty.to_string())],
|
||||
};
|
||||
|
||||
@ -1247,7 +1247,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
let inputs = trait_ref.substs.type_at(1);
|
||||
let sig = if let ty::Tuple(inputs) = inputs.sty {
|
||||
tcx.mk_fn_sig(
|
||||
inputs.iter().cloned(),
|
||||
inputs.iter().map(|k| k.expect_ty()),
|
||||
tcx.mk_infer(ty::TyVar(ty::TyVid { index: 0 })),
|
||||
false,
|
||||
hir::Unsafety::Normal,
|
||||
|
@ -217,7 +217,7 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'_, '_, 'tcx>, ty: Ty<'tcx>) ->
|
||||
|
||||
// (T1..Tn) and closures have same properties as T1..Tn --
|
||||
// check if *any* of those are trivial.
|
||||
ty::Tuple(ref tys) => tys.iter().all(|t| trivial_dropck_outlives(tcx, t)),
|
||||
ty::Tuple(ref tys) => tys.iter().all(|t| trivial_dropck_outlives(tcx, t.expect_ty())),
|
||||
ty::Closure(def_id, ref substs) => substs
|
||||
.upvar_tys(def_id, tcx)
|
||||
.all(|t| trivial_dropck_outlives(tcx, t)),
|
||||
|
@ -2429,7 +2429,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
|
||||
ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => None,
|
||||
|
||||
ty::Tuple(tys) => Where(ty::Binder::bind(tys.last().into_iter().cloned().collect())),
|
||||
ty::Tuple(tys) => {
|
||||
Where(ty::Binder::bind(tys.last().into_iter().map(|k| k.expect_ty()).collect()))
|
||||
}
|
||||
|
||||
ty::Adt(def, substs) => {
|
||||
let sized_crit = def.sized_constraint(self.tcx());
|
||||
@ -2503,7 +2505,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
|
||||
ty::Tuple(tys) => {
|
||||
// (*) binder moved here
|
||||
Where(ty::Binder::bind(tys.to_vec()))
|
||||
Where(ty::Binder::bind(tys.iter().map(|k| k.expect_ty()).collect()))
|
||||
}
|
||||
|
||||
ty::Closure(def_id, substs) => {
|
||||
@ -2590,7 +2592,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
|
||||
ty::Tuple(ref tys) => {
|
||||
// (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
|
||||
tys.to_vec()
|
||||
tys.iter().map(|k| k.expect_ty()).collect()
|
||||
}
|
||||
|
||||
ty::Closure(def_id, ref substs) => substs.upvar_tys(def_id, self.tcx()).collect(),
|
||||
@ -3495,7 +3497,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
|
||||
// Check that the source tuple with the target's
|
||||
// last element is equal to the target.
|
||||
let new_tuple = tcx.mk_tup(a_mid.iter().cloned().chain(iter::once(b_last)));
|
||||
let new_tuple = tcx.mk_tup(
|
||||
a_mid.iter().map(|k| k.expect_ty()).chain(iter::once(b_last.expect_ty())),
|
||||
);
|
||||
let InferOk { obligations, .. } = self.infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
.eq(target, new_tuple)
|
||||
@ -3508,7 +3512,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
obligation.cause.clone(),
|
||||
obligation.predicate.def_id(),
|
||||
obligation.recursion_depth + 1,
|
||||
a_last,
|
||||
a_last.expect_ty(),
|
||||
&[b_last.into()],
|
||||
));
|
||||
}
|
||||
|
@ -2431,7 +2431,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
let converted_sig = sig.map_bound(|s| {
|
||||
let params_iter = match s.inputs()[0].sty {
|
||||
ty::Tuple(params) => {
|
||||
params.into_iter().cloned()
|
||||
params.into_iter().map(|k| k.expect_ty())
|
||||
}
|
||||
_ => bug!(),
|
||||
};
|
||||
@ -2573,11 +2573,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
#[inline]
|
||||
pub fn intern_tup(self, ts: &[Ty<'tcx>]) -> Ty<'tcx> {
|
||||
self.mk_ty(Tuple(self.intern_type_list(ts)))
|
||||
let kinds: Vec<_> = ts.into_iter().map(|&t| Kind::from(t)).collect();
|
||||
self.mk_ty(Tuple(self.intern_substs(&kinds)))
|
||||
}
|
||||
|
||||
pub fn mk_tup<I: InternAs<[Ty<'tcx>], Ty<'tcx>>>(self, iter: I) -> I::Output {
|
||||
iter.intern_with(|ts| self.mk_ty(Tuple(self.intern_type_list(ts))))
|
||||
iter.intern_with(|ts| {
|
||||
let kinds: Vec<_> = ts.into_iter().map(|&t| Kind::from(t)).collect();
|
||||
self.mk_ty(Tuple(self.intern_substs(&kinds)))
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -195,8 +195,8 @@ impl FlagComputation {
|
||||
self.add_ty(ty);
|
||||
}
|
||||
|
||||
&ty::Tuple(ref ts) => {
|
||||
self.add_tys(&ts[..]);
|
||||
&ty::Tuple(ref substs) => {
|
||||
self.add_substs(substs);
|
||||
}
|
||||
|
||||
&ty::FnDef(_, substs) => {
|
||||
|
@ -181,7 +181,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
||||
|
||||
Tuple(ref tys) => {
|
||||
DefIdForest::union(tcx, tys.iter().map(|ty| {
|
||||
ty.uninhabited_from(tcx)
|
||||
ty.expect_ty().uninhabited_from(tcx)
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -626,8 +626,9 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
|
||||
StructKind::MaybeUnsized
|
||||
};
|
||||
|
||||
univariant(&tys.iter().map(|ty| self.layout_of(ty)).collect::<Result<Vec<_>, _>>()?,
|
||||
&ReprOptions::default(), kind)?
|
||||
univariant(&tys.iter().map(|k| {
|
||||
self.layout_of(k.expect_ty())
|
||||
}).collect::<Result<Vec<_>, _>>()?, &ReprOptions::default(), kind)?
|
||||
}
|
||||
|
||||
// SIMD vector types.
|
||||
@ -1723,7 +1724,7 @@ impl<'a, 'tcx, C> TyLayoutMethods<'tcx, C> for Ty<'tcx>
|
||||
substs.field_tys(def_id, tcx).nth(i).unwrap()
|
||||
}
|
||||
|
||||
ty::Tuple(tys) => tys[i],
|
||||
ty::Tuple(tys) => tys[i].expect_ty(),
|
||||
|
||||
// SIMD vector types.
|
||||
ty::Adt(def, ..) if def.repr.simd() => {
|
||||
|
@ -2501,7 +2501,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
|
||||
Tuple(ref tys) => {
|
||||
match tys.last() {
|
||||
None => vec![],
|
||||
Some(ty) => self.sized_constraint_for_ty(tcx, ty)
|
||||
Some(ty) => self.sized_constraint_for_ty(tcx, ty.expect_ty()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -264,7 +264,7 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
|
||||
ty::Ref(_, ty, _) => characteristic_def_id_of_type(ty),
|
||||
|
||||
ty::Tuple(ref tys) => tys.iter()
|
||||
.filter_map(|ty| characteristic_def_id_of_type(ty))
|
||||
.filter_map(|ty| characteristic_def_id_of_type(ty.expect_ty()))
|
||||
.next(),
|
||||
|
||||
ty::FnDef(def_id, _) |
|
||||
|
@ -701,7 +701,8 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>:
|
||||
if let ty::Tuple(ref args) = principal.substs.type_at(0).sty {
|
||||
let mut projections = predicates.projection_bounds();
|
||||
if let (Some(proj), None) = (projections.next(), projections.next()) {
|
||||
p!(pretty_fn_sig(args, false, proj.ty));
|
||||
let tys: Vec<_> = args.iter().map(|k| k.expect_ty()).collect();
|
||||
p!(pretty_fn_sig(&tys, false, proj.ty));
|
||||
resugared = true;
|
||||
}
|
||||
}
|
||||
|
@ -526,7 +526,9 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
|
||||
(&ty::Tuple(as_), &ty::Tuple(bs)) =>
|
||||
{
|
||||
if as_.len() == bs.len() {
|
||||
Ok(tcx.mk_tup(as_.iter().zip(bs).map(|(a, b)| relation.relate(a, b)))?)
|
||||
Ok(tcx.mk_tup(as_.iter().zip(bs).map(|(a, b)| {
|
||||
relation.relate(&a.expect_ty(), &b.expect_ty())
|
||||
}))?)
|
||||
} else if !(as_.is_empty() || bs.is_empty()) {
|
||||
Err(TypeError::TupleSize(
|
||||
expected_found(relation, &as_.len(), &bs.len())))
|
||||
|
@ -171,7 +171,7 @@ pub enum TyKind<'tcx> {
|
||||
Never,
|
||||
|
||||
/// A tuple type. For example, `(i32, bool)`.
|
||||
Tuple(&'tcx List<Ty<'tcx>>),
|
||||
Tuple(SubstsRef<'tcx>),
|
||||
|
||||
/// The projection of an associated type. For example,
|
||||
/// `<T as Trait<..>>::N`.
|
||||
@ -1651,7 +1651,9 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
||||
})
|
||||
})
|
||||
}
|
||||
ty::Tuple(tys) => tys.iter().any(|ty| ty.conservative_is_privately_uninhabited(tcx)),
|
||||
ty::Tuple(tys) => tys.iter().any(|ty| {
|
||||
ty.expect_ty().conservative_is_privately_uninhabited(tcx)
|
||||
}),
|
||||
ty::Array(ty, len) => {
|
||||
match len.assert_usize(tcx) {
|
||||
// If the array is definitely non-empty, it's uninhabited if
|
||||
@ -2087,8 +2089,9 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
||||
ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) =>
|
||||
false,
|
||||
|
||||
ty::Tuple(tys) =>
|
||||
tys.iter().all(|ty| ty.is_trivially_sized(tcx)),
|
||||
ty::Tuple(tys) => {
|
||||
tys.iter().all(|ty| ty.expect_ty().is_trivially_sized(tcx))
|
||||
}
|
||||
|
||||
ty::Adt(def, _substs) =>
|
||||
def.sized_constraint(tcx).is_empty(),
|
||||
|
@ -123,6 +123,16 @@ impl<'tcx> Kind<'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Unpack the `Kind` as a type when it is known certainly to be a type.
|
||||
/// This is true in cases where `Substs` is used in places where the kinds are known
|
||||
/// to be limited (e.g. in tuples, where the only parameters are type parameters).
|
||||
pub fn expect_ty(self) -> Ty<'tcx> {
|
||||
match self.unpack() {
|
||||
UnpackedKind::Type(ty) => ty,
|
||||
_ => bug!("expected a type, but found another kind"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Lift<'tcx> for Kind<'a> {
|
||||
@ -174,8 +184,7 @@ pub type SubstsRef<'tcx> = &'tcx InternalSubsts<'tcx>;
|
||||
|
||||
impl<'a, 'gcx, 'tcx> InternalSubsts<'tcx> {
|
||||
/// Creates a `InternalSubsts` that maps each generic parameter to itself.
|
||||
pub fn identity_for_item(tcx: TyCtxt<'a, 'gcx, 'tcx>, def_id: DefId)
|
||||
-> SubstsRef<'tcx> {
|
||||
pub fn identity_for_item(tcx: TyCtxt<'a, 'gcx, 'tcx>, def_id: DefId) -> SubstsRef<'tcx> {
|
||||
Self::for_item(tcx, def_id, |param, _| {
|
||||
tcx.mk_param_from_def(param)
|
||||
})
|
||||
|
@ -278,7 +278,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
ty::Tuple(tys) => {
|
||||
if let Some((&last_ty, _)) = tys.split_last() {
|
||||
ty = last_ty;
|
||||
ty = last_ty.expect_ty();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@ -316,8 +316,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
(&Tuple(a_tys), &Tuple(b_tys))
|
||||
if a_tys.len() == b_tys.len() => {
|
||||
if let Some(a_last) = a_tys.last() {
|
||||
a = a_last;
|
||||
b = b_tys.last().unwrap();
|
||||
a = a_last.expect_ty();
|
||||
b = b_tys.last().unwrap().expect_ty();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@ -795,7 +795,13 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
|
||||
Tuple(ref ts) => {
|
||||
// Find non representable
|
||||
fold_repr(ts.iter().map(|ty| {
|
||||
is_type_structurally_recursive(tcx, sp, seen, representable_cache, ty)
|
||||
is_type_structurally_recursive(
|
||||
tcx,
|
||||
sp,
|
||||
seen,
|
||||
representable_cache,
|
||||
ty.expect_ty(),
|
||||
)
|
||||
}))
|
||||
}
|
||||
// Fixed-length vectors.
|
||||
@ -1048,7 +1054,7 @@ fn needs_drop_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
// state transformation pass
|
||||
ty::Generator(..) => true,
|
||||
|
||||
ty::Tuple(ref tys) => tys.iter().cloned().any(needs_drop),
|
||||
ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).any(needs_drop),
|
||||
|
||||
// unions don't have destructors because of the child types,
|
||||
// only if they manually implement `Drop` (handled above).
|
||||
|
@ -120,7 +120,7 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) {
|
||||
stack.extend(ts.skip_binder().iter().cloned().rev());
|
||||
}
|
||||
ty::Tuple(ts) => {
|
||||
stack.extend(ts.iter().cloned().rev());
|
||||
stack.extend(ts.iter().map(|k| k.expect_ty()).rev());
|
||||
}
|
||||
ty::FnDef(_, substs) => {
|
||||
stack.extend(substs.types().rev());
|
||||
|
@ -265,7 +265,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
|
||||
ty::Tuple(ref tys) => {
|
||||
if let Some((_last, rest)) = tys.split_last() {
|
||||
for elem in rest {
|
||||
self.require_sized(elem, traits::TupleElem);
|
||||
self.require_sized(elem.expect_ty(), traits::TupleElem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -426,9 +426,9 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
|
||||
assert!(!sig.c_variadic && extra_args.is_empty());
|
||||
|
||||
match sig.inputs().last().unwrap().sty {
|
||||
ty::Tuple(ref tupled_arguments) => {
|
||||
ty::Tuple(tupled_arguments) => {
|
||||
inputs = &sig.inputs()[0..sig.inputs().len() - 1];
|
||||
tupled_arguments
|
||||
tupled_arguments.iter().map(|k| k.expect_ty()).collect()
|
||||
}
|
||||
_ => {
|
||||
bug!("argument to function with \"rust-call\" ABI \
|
||||
@ -437,7 +437,7 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
|
||||
}
|
||||
} else {
|
||||
assert!(sig.c_variadic || extra_args.is_empty());
|
||||
extra_args
|
||||
extra_args.to_vec()
|
||||
};
|
||||
|
||||
let target = &cx.sess().target.target;
|
||||
@ -587,7 +587,7 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
|
||||
|
||||
let mut fn_ty = FnType {
|
||||
ret: arg_of(sig.output(), None),
|
||||
args: inputs.iter().chain(extra_args).enumerate().map(|(i, ty)| {
|
||||
args: inputs.iter().cloned().chain(extra_args).enumerate().map(|(i, ty)| {
|
||||
arg_of(ty, Some(i))
|
||||
}).collect(),
|
||||
c_variadic: sig.c_variadic,
|
||||
|
@ -722,9 +722,10 @@ pub fn type_metadata(
|
||||
}
|
||||
},
|
||||
ty::Tuple(ref elements) => {
|
||||
let tys: Vec<_> = elements.iter().map(|k| k.expect_ty()).collect();
|
||||
prepare_tuple_metadata(cx,
|
||||
t,
|
||||
&elements[..],
|
||||
&tys,
|
||||
unique_type_id,
|
||||
usage_site_span).finalize(cx)
|
||||
}
|
||||
|
@ -392,7 +392,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
if let ty::Tuple(args) = sig.inputs()[sig.inputs().len() - 1].sty {
|
||||
signature.extend(
|
||||
args.iter().map(|argument_type| {
|
||||
Some(type_metadata(cx, argument_type, syntax_pos::DUMMY_SP))
|
||||
Some(type_metadata(cx, argument_type.expect_ty(), syntax_pos::DUMMY_SP))
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
ty::Tuple(component_types) => {
|
||||
output.push('(');
|
||||
for &component_type in component_types {
|
||||
push_debuginfo_type_name(tcx, component_type, true, output, visited);
|
||||
push_debuginfo_type_name(tcx, component_type.expect_ty(), true, output, visited);
|
||||
output.push_str(", ");
|
||||
}
|
||||
if !component_types.is_empty() {
|
||||
|
@ -607,8 +607,8 @@ impl<T: Idx> GrowableBitSet<T> {
|
||||
GrowableBitSet { bit_set: BitSet::new_empty(0) }
|
||||
}
|
||||
|
||||
pub fn with_capacity(bits: usize) -> GrowableBitSet<T> {
|
||||
GrowableBitSet { bit_set: BitSet::new_empty(bits) }
|
||||
pub fn with_capacity(capacity: usize) -> GrowableBitSet<T> {
|
||||
GrowableBitSet { bit_set: BitSet::new_empty(capacity) }
|
||||
}
|
||||
|
||||
/// Returns `true` if the set has changed.
|
||||
|
@ -2213,7 +2213,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
// Closure arguments are wrapped in a tuple, so we need to get the first
|
||||
// from that.
|
||||
if let ty::Tuple(elems) = argument_ty.sty {
|
||||
let argument_ty = elems.first()?;
|
||||
let argument_ty = elems.first()?.expect_ty();
|
||||
if let ty::Ref(_, _, _) = argument_ty.sty {
|
||||
return Some(AnnotatedBorrowFnSignature::Closure {
|
||||
argument_ty,
|
||||
|
@ -515,7 +515,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
// just worry about trying to match up the rustc type
|
||||
// with the HIR types:
|
||||
(ty::Tuple(elem_tys), hir::TyKind::Tup(elem_hir_tys)) => {
|
||||
search_stack.extend(elem_tys.iter().cloned().zip(elem_hir_tys));
|
||||
search_stack.extend(elem_tys.iter().map(|k| k.expect_ty()).zip(elem_hir_tys));
|
||||
}
|
||||
|
||||
(ty::Slice(elem_ty), hir::TyKind::Slice(elem_hir_ty))
|
||||
|
@ -779,7 +779,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
|
||||
}
|
||||
ty::Tuple(tys) => {
|
||||
return match tys.get(field.index()) {
|
||||
Some(&ty) => Ok(ty),
|
||||
Some(&ty) => Ok(ty.expect_ty()),
|
||||
None => Err(FieldAccessError::OutOfRange {
|
||||
field_count: tys.len(),
|
||||
}),
|
||||
|
@ -580,7 +580,7 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> {
|
||||
|
||||
tcx.mk_type_list(
|
||||
iter::once(closure_ty)
|
||||
.chain(inputs.iter().cloned())
|
||||
.chain(inputs.iter().map(|k| k.expect_ty()))
|
||||
.chain(iter::once(output)),
|
||||
)
|
||||
},
|
||||
|
@ -1359,7 +1359,7 @@ fn constructor_sub_pattern_tys<'a, 'tcx: 'a>(cx: &MatchCheckCtxt<'a, 'tcx>,
|
||||
{
|
||||
debug!("constructor_sub_pattern_tys({:#?}, {:?})", ctor, ty);
|
||||
match ty.sty {
|
||||
ty::Tuple(ref fs) => fs.into_iter().map(|t| *t).collect(),
|
||||
ty::Tuple(ref fs) => fs.into_iter().map(|t| t.expect_ty()).collect(),
|
||||
ty::Slice(ty) | ty::Array(ty, _) => match *ctor {
|
||||
Slice(length) => (0..length).map(|_| ty).collect(),
|
||||
ConstantValue(_) => vec![],
|
||||
|
@ -272,7 +272,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
|
||||
ty::Tuple(component_types) => {
|
||||
output.push('(');
|
||||
for &component_type in component_types {
|
||||
self.push_type_name(component_type, output, debug);
|
||||
self.push_type_name(component_type.expect_ty(), output, debug);
|
||||
output.push_str(", ");
|
||||
}
|
||||
if !component_types.is_empty() {
|
||||
|
@ -331,7 +331,7 @@ fn build_clone_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
substs.upvar_tys(def_id, tcx)
|
||||
)
|
||||
}
|
||||
ty::Tuple(tys) => builder.tuple_like_shim(dest, src, tys.iter().cloned()),
|
||||
ty::Tuple(tys) => builder.tuple_like_shim(dest, src, tys.iter().map(|k| k.expect_ty())),
|
||||
_ => {
|
||||
bug!("clone shim for `{:?}` which is not `Copy` and is not an aggregate", self_ty)
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ fn may_have_reference<'a, 'gcx, 'tcx>(ty: Ty<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>)
|
||||
ty::Array(ty, ..) | ty::Slice(ty) =>
|
||||
may_have_reference(ty, tcx),
|
||||
ty::Tuple(tys) =>
|
||||
tys.iter().any(|ty| may_have_reference(ty, tcx)),
|
||||
tys.iter().any(|ty| may_have_reference(ty.expect_ty(), tcx)),
|
||||
ty::Adt(adt, substs) =>
|
||||
adt.variants.iter().any(|v| v.fields.iter().any(|f|
|
||||
may_have_reference(f.ty(tcx, substs), tcx)
|
||||
|
@ -575,7 +575,10 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
||||
let tuple_tmp_args =
|
||||
tuple_tys.iter().enumerate().map(|(i, ty)| {
|
||||
// This is e.g., `tuple_tmp.0` in our example above.
|
||||
let tuple_field = Operand::Move(tuple.clone().field(Field::new(i), ty));
|
||||
let tuple_field = Operand::Move(tuple.clone().field(
|
||||
Field::new(i),
|
||||
ty.expect_ty(),
|
||||
));
|
||||
|
||||
// Spill to a local to make e.g., `tmp0`.
|
||||
self.create_temp_if_necessary(tuple_field, callsite, caller_mir)
|
||||
|
@ -797,7 +797,8 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
|
||||
self.open_drop_for_tuple(&tys)
|
||||
}
|
||||
ty::Tuple(tys) => {
|
||||
self.open_drop_for_tuple(tys)
|
||||
let tys: Vec<_> = tys.iter().map(|k| k.expect_ty()).collect();
|
||||
self.open_drop_for_tuple(&tys)
|
||||
}
|
||||
ty::Adt(def, substs) => {
|
||||
if def.is_box() {
|
||||
|
@ -5,7 +5,7 @@ use rustc::traits::{
|
||||
ProgramClauseCategory,
|
||||
};
|
||||
use rustc::ty;
|
||||
use rustc::ty::subst::{InternalSubsts, Subst};
|
||||
use rustc::ty::subst::{Kind, InternalSubsts, Subst};
|
||||
use rustc::hir;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use crate::lowering::Lower;
|
||||
@ -17,7 +17,7 @@ use crate::generic_types;
|
||||
fn builtin_impl_clause(
|
||||
tcx: ty::TyCtxt<'_, '_, 'tcx>,
|
||||
ty: ty::Ty<'tcx>,
|
||||
nested: &[ty::Ty<'tcx>],
|
||||
nested: &[Kind<'tcx>],
|
||||
trait_def_id: DefId
|
||||
) -> ProgramClause<'tcx> {
|
||||
ProgramClause {
|
||||
@ -32,7 +32,7 @@ fn builtin_impl_clause(
|
||||
.cloned()
|
||||
.map(|nested_ty| ty::TraitRef {
|
||||
def_id: trait_def_id,
|
||||
substs: tcx.mk_substs_trait(nested_ty, &[]),
|
||||
substs: tcx.mk_substs_trait(nested_ty.expect_ty(), &[]),
|
||||
})
|
||||
.map(|trait_ref| ty::TraitPredicate { trait_ref })
|
||||
.map(|pred| GoalKind::DomainGoal(pred.lower()))
|
||||
@ -124,7 +124,7 @@ crate fn assemble_builtin_sized_impls<'tcx>(
|
||||
ty: ty::Ty<'tcx>,
|
||||
clauses: &mut Vec<Clause<'tcx>>
|
||||
) {
|
||||
let mut push_builtin_impl = |ty: ty::Ty<'tcx>, nested: &[ty::Ty<'tcx>]| {
|
||||
let mut push_builtin_impl = |ty: ty::Ty<'tcx>, nested: &[Kind<'tcx>]| {
|
||||
let clause = builtin_impl_clause(tcx, ty, nested, sized_def_id);
|
||||
// Bind innermost bound vars that may exist in `ty` and `nested`.
|
||||
clauses.push(Clause::ForAll(ty::Binder::bind(clause)));
|
||||
@ -176,7 +176,7 @@ crate fn assemble_builtin_sized_impls<'tcx>(
|
||||
// `Sized` if the last type is `Sized` (because else we will get a WF error anyway).
|
||||
&ty::Tuple(type_list) => {
|
||||
let type_list = generic_types::type_list(tcx, type_list.len());
|
||||
push_builtin_impl(tcx.mk_ty(ty::Tuple(type_list)), &**type_list);
|
||||
push_builtin_impl(tcx.mk_ty(ty::Tuple(type_list)), &type_list);
|
||||
}
|
||||
|
||||
// Struct def
|
||||
@ -185,7 +185,7 @@ crate fn assemble_builtin_sized_impls<'tcx>(
|
||||
let adt = tcx.mk_ty(ty::Adt(adt_def, substs));
|
||||
let sized_constraint = adt_def.sized_constraint(tcx)
|
||||
.iter()
|
||||
.map(|ty| ty.subst(tcx, substs))
|
||||
.map(|ty| Kind::from(ty.subst(tcx, substs)))
|
||||
.collect::<Vec<_>>();
|
||||
push_builtin_impl(adt, &sized_constraint);
|
||||
}
|
||||
@ -228,7 +228,7 @@ crate fn assemble_builtin_copy_clone_impls<'tcx>(
|
||||
ty: ty::Ty<'tcx>,
|
||||
clauses: &mut Vec<Clause<'tcx>>
|
||||
) {
|
||||
let mut push_builtin_impl = |ty: ty::Ty<'tcx>, nested: &[ty::Ty<'tcx>]| {
|
||||
let mut push_builtin_impl = |ty: ty::Ty<'tcx>, nested: &[Kind<'tcx>]| {
|
||||
let clause = builtin_impl_clause(tcx, ty, nested, trait_def_id);
|
||||
// Bind innermost bound vars that may exist in `ty` and `nested`.
|
||||
clauses.push(Clause::ForAll(ty::Binder::bind(clause)));
|
||||
@ -253,7 +253,10 @@ crate fn assemble_builtin_copy_clone_impls<'tcx>(
|
||||
// These implement `Copy`/`Clone` if their element types do.
|
||||
&ty::Array(_, length) => {
|
||||
let element_ty = generic_types::bound(tcx, 0);
|
||||
push_builtin_impl(tcx.mk_ty(ty::Array(element_ty, length)), &[element_ty]);
|
||||
push_builtin_impl(
|
||||
tcx.mk_ty(ty::Array(element_ty, length)),
|
||||
&[Kind::from(element_ty)],
|
||||
);
|
||||
}
|
||||
&ty::Tuple(type_list) => {
|
||||
let type_list = generic_types::type_list(tcx, type_list.len());
|
||||
@ -262,7 +265,9 @@ crate fn assemble_builtin_copy_clone_impls<'tcx>(
|
||||
&ty::Closure(def_id, ..) => {
|
||||
let closure_ty = generic_types::closure(tcx, def_id);
|
||||
let upvar_tys: Vec<_> = match &closure_ty.sty {
|
||||
ty::Closure(_, substs) => substs.upvar_tys(def_id, tcx).collect(),
|
||||
ty::Closure(_, substs) => {
|
||||
substs.upvar_tys(def_id, tcx).map(|ty| Kind::from(ty)).collect()
|
||||
},
|
||||
_ => bug!(),
|
||||
};
|
||||
push_builtin_impl(closure_ty, &upvar_tys);
|
||||
|
@ -131,7 +131,7 @@ crate fn wf_clause_for_tuple<'tcx>(
|
||||
let sized_implemented = type_list[0 .. std::cmp::max(arity, 1) - 1].iter()
|
||||
.map(|ty| ty::TraitRef {
|
||||
def_id: sized_trait,
|
||||
substs: tcx.mk_substs_trait(*ty, ty::List::empty()),
|
||||
substs: tcx.mk_substs_trait(ty.expect_ty(), ty::List::empty()),
|
||||
})
|
||||
.map(|trait_ref| ty::TraitPredicate { trait_ref })
|
||||
.map(|predicate| predicate.lower());
|
||||
|
@ -190,7 +190,7 @@ fn dtorck_constraint_for_ty<'a, 'gcx, 'tcx>(
|
||||
}
|
||||
|
||||
ty::Tuple(tys) => tys.iter()
|
||||
.map(|ty| dtorck_constraint_for_ty(tcx, span, for_ty, depth + 1, ty))
|
||||
.map(|ty| dtorck_constraint_for_ty(tcx, span, for_ty, depth + 1, ty.expect_ty()))
|
||||
.collect(),
|
||||
|
||||
ty::Closure(def_id, substs) => substs
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Utilities for creating generic types with bound vars in place of parameter values.
|
||||
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::subst::InternalSubsts;
|
||||
use rustc::ty::subst::{Kind, SubstsRef, InternalSubsts};
|
||||
use rustc::hir;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc_target::spec::abi;
|
||||
@ -44,11 +44,12 @@ crate fn fn_ptr(
|
||||
tcx.mk_fn_ptr(fn_sig)
|
||||
}
|
||||
|
||||
crate fn type_list(tcx: ty::TyCtxt<'_, '_, 'tcx>, arity: usize) -> &'tcx ty::List<Ty<'tcx>> {
|
||||
tcx.mk_type_list(
|
||||
crate fn type_list(tcx: ty::TyCtxt<'_, '_, 'tcx>, arity: usize) -> SubstsRef<'tcx> {
|
||||
tcx.mk_substs(
|
||||
(0..arity).into_iter()
|
||||
.map(|i| ty::BoundVar::from(i))
|
||||
.map(|var| tcx.mk_ty(ty::Bound(ty::INNERMOST, var.into())))
|
||||
.map(|ty| Kind::from(ty))
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ use rustc::infer;
|
||||
use rustc::infer::type_variable::TypeVariableOrigin;
|
||||
use rustc::traits::ObligationCauseCode;
|
||||
use rustc::ty::{self, Ty, TypeFoldable};
|
||||
use rustc::ty::subst::Kind;
|
||||
use syntax::ast;
|
||||
use syntax::source_map::Spanned;
|
||||
use syntax::ptr::P;
|
||||
@ -304,11 +305,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
let max_len = cmp::max(expected_len, elements.len());
|
||||
|
||||
let element_tys_iter = (0..max_len).map(|_| self.next_ty_var(
|
||||
let element_tys_iter = (0..max_len).map(|_| {
|
||||
// FIXME: `MiscVariable` for now -- obtaining the span and name information
|
||||
// from all tuple elements isn't trivial.
|
||||
TypeVariableOrigin::TypeInference(pat.span)));
|
||||
let element_tys = tcx.mk_type_list(element_tys_iter);
|
||||
Kind::from(self.next_ty_var(TypeVariableOrigin::TypeInference(pat.span)))
|
||||
});
|
||||
let element_tys = tcx.mk_substs(element_tys_iter);
|
||||
let pat_ty = tcx.mk_ty(ty::Tuple(element_tys));
|
||||
if let Some(mut err) = self.demand_eqtype_diag(pat.span, expected, pat_ty) {
|
||||
err.emit();
|
||||
@ -321,7 +323,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
tcx.mk_tup(element_tys_iter)
|
||||
} else {
|
||||
for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
|
||||
self.check_pat_walk(elem, &element_tys[i], def_bm, match_discrim_span);
|
||||
self.check_pat_walk(
|
||||
elem,
|
||||
&element_tys[i].expect_ty(),
|
||||
def_bm,
|
||||
match_discrim_span,
|
||||
);
|
||||
}
|
||||
pat_ty
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
ty::Tuple(fields) => match fields.last() {
|
||||
None => Some(PointerKind::Thin),
|
||||
Some(f) => self.pointer_kind(f, span)?
|
||||
Some(f) => self.pointer_kind(f.expect_ty(), span)?
|
||||
},
|
||||
|
||||
// Pointers to foreign types are thin, despite being unsized
|
||||
|
@ -274,8 +274,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
);
|
||||
|
||||
let input_tys = match arg_param_ty.sty {
|
||||
ty::Tuple(tys) => tys.into_iter(),
|
||||
_ => return None
|
||||
ty::Tuple(tys) => tys.into_iter().map(|k| k.expect_ty()),
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
let ret_param_ty = projection.skip_binder().ty;
|
||||
@ -286,7 +286,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
);
|
||||
|
||||
let sig = self.tcx.mk_fn_sig(
|
||||
input_tys.cloned(),
|
||||
input_tys,
|
||||
ret_param_ty,
|
||||
false,
|
||||
hir::Unsafety::Normal,
|
||||
|
@ -2859,7 +2859,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
sp: Span,
|
||||
expr_sp: Span,
|
||||
fn_inputs: &[Ty<'tcx>],
|
||||
mut expected_arg_tys: &[Ty<'tcx>],
|
||||
expected_arg_tys: &[Ty<'tcx>],
|
||||
args: &'gcx [hir::Expr],
|
||||
c_variadic: bool,
|
||||
tuple_arguments: TupleArgumentsFlag,
|
||||
@ -2915,29 +2915,31 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
err.emit();
|
||||
};
|
||||
|
||||
let mut expected_arg_tys = expected_arg_tys.to_vec();
|
||||
|
||||
let formal_tys = if tuple_arguments == TupleArguments {
|
||||
let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
|
||||
match tuple_type.sty {
|
||||
ty::Tuple(arg_types) if arg_types.len() != args.len() => {
|
||||
param_count_error(arg_types.len(), args.len(), "E0057", false, false);
|
||||
expected_arg_tys = &[];
|
||||
expected_arg_tys = vec![];
|
||||
self.err_args(args.len())
|
||||
}
|
||||
ty::Tuple(arg_types) => {
|
||||
expected_arg_tys = match expected_arg_tys.get(0) {
|
||||
Some(&ty) => match ty.sty {
|
||||
ty::Tuple(ref tys) => &tys,
|
||||
_ => &[]
|
||||
ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
|
||||
_ => vec![],
|
||||
},
|
||||
None => &[]
|
||||
None => vec![],
|
||||
};
|
||||
arg_types.to_vec()
|
||||
arg_types.iter().map(|k| k.expect_ty()).collect()
|
||||
}
|
||||
_ => {
|
||||
span_err!(tcx.sess, sp, E0059,
|
||||
"cannot use call notation; the first type parameter \
|
||||
for the function trait is neither a tuple nor unit");
|
||||
expected_arg_tys = &[];
|
||||
expected_arg_tys = vec![];
|
||||
self.err_args(args.len())
|
||||
}
|
||||
}
|
||||
@ -2948,7 +2950,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
fn_inputs.to_vec()
|
||||
} else {
|
||||
param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
|
||||
expected_arg_tys = &[];
|
||||
expected_arg_tys = vec![];
|
||||
self.err_args(supplied_arg_count)
|
||||
}
|
||||
} else {
|
||||
@ -2962,19 +2964,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
};
|
||||
param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
|
||||
|
||||
expected_arg_tys = &[];
|
||||
expected_arg_tys = vec![];
|
||||
self.err_args(supplied_arg_count)
|
||||
};
|
||||
// If there is no expectation, expect formal_tys.
|
||||
let expected_arg_tys = if !expected_arg_tys.is_empty() {
|
||||
expected_arg_tys
|
||||
} else {
|
||||
&formal_tys
|
||||
};
|
||||
|
||||
debug!("check_argument_types: formal_tys={:?}",
|
||||
formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>());
|
||||
|
||||
// If there is no expectation, expect formal_tys.
|
||||
let expected_arg_tys = if !expected_arg_tys.is_empty() {
|
||||
expected_arg_tys
|
||||
} else {
|
||||
formal_tys.clone()
|
||||
};
|
||||
|
||||
// Check the arguments.
|
||||
// We do this in a pretty awful way: first we type-check any arguments
|
||||
// that are not closures, then we type-check the closures. This is so
|
||||
@ -3560,7 +3563,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
autoderef.finalize(self);
|
||||
|
||||
self.write_field_index(expr.hir_id, index);
|
||||
return field_ty;
|
||||
return field_ty.expect_ty();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4630,7 +4633,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
let elt_ts_iter = elts.iter().enumerate().map(|(i, e)| {
|
||||
let t = match flds {
|
||||
Some(ref fs) if i < fs.len() => {
|
||||
let ety = fs[i];
|
||||
let ety = fs[i].expect_ty();
|
||||
self.check_expr_coercable_to_type(&e, ety);
|
||||
ety
|
||||
}
|
||||
|
@ -288,7 +288,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||
|
||||
ty::Tuple(subtys) => {
|
||||
for &subty in subtys {
|
||||
self.add_constraints_from_ty(current, subty, variance);
|
||||
self.add_constraints_from_ty(current, subty.expect_ty(), variance);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1136,7 +1136,7 @@ fn external_generic_args(
|
||||
Some(did) if cx.tcx.lang_items().fn_trait_kind(did).is_some() => {
|
||||
assert!(ty_sty.is_some());
|
||||
let inputs = match ty_sty {
|
||||
Some(ty::Tuple(ref tys)) => tys.iter().map(|t| t.clean(cx)).collect(),
|
||||
Some(ty::Tuple(ref tys)) => tys.iter().map(|t| t.expect_ty().clean(cx)).collect(),
|
||||
_ => return GenericArgs::AngleBracketed { args, bindings },
|
||||
};
|
||||
let output = None;
|
||||
@ -1181,7 +1181,7 @@ impl<'a, 'tcx> Clean<GenericBound> for (&'a ty::TraitRef<'tcx>, Vec<TypeBinding>
|
||||
for ty_s in trait_ref.input_types().skip(1) {
|
||||
if let ty::Tuple(ts) = ty_s.sty {
|
||||
for &ty_s in ts {
|
||||
if let ty::Ref(ref reg, _, _) = ty_s.sty {
|
||||
if let ty::Ref(ref reg, _, _) = ty_s.expect_ty().sty {
|
||||
if let &ty::RegionKind::ReLateBound(..) = *reg {
|
||||
debug!(" hit an ReLateBound {:?}", reg);
|
||||
if let Some(Lifetime(name)) = reg.clean(cx) {
|
||||
@ -3066,7 +3066,9 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
||||
is_generic: false,
|
||||
}
|
||||
}
|
||||
ty::Tuple(ref t) => Tuple(t.clean(cx)),
|
||||
ty::Tuple(ref t) => {
|
||||
Tuple(t.iter().map(|t| t.expect_ty()).collect::<Vec<_>>().clean(cx))
|
||||
}
|
||||
|
||||
ty::Projection(ref data) => data.clean(cx),
|
||||
|
||||
|
@ -3060,7 +3060,7 @@ fn render_implementor(cx: &Context, implementor: &Impl, w: &mut fmt::Formatter<'
|
||||
_ => false,
|
||||
};
|
||||
render_impl(w, cx, implementor, AssocItemLink::Anchor(None), RenderMode::Normal,
|
||||
implementor.impl_item.stable_since(), false, Some(use_absolute))?;
|
||||
implementor.impl_item.stable_since(), false, Some(use_absolute), false)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -3071,7 +3071,7 @@ fn render_impls(cx: &Context, w: &mut fmt::Formatter<'_>,
|
||||
let did = i.trait_did().unwrap();
|
||||
let assoc_link = AssocItemLink::GotoSource(did, &i.inner_impl().provided_trait_methods);
|
||||
render_impl(w, cx, i, assoc_link,
|
||||
RenderMode::Normal, containing_item.stable_since(), true, None)?;
|
||||
RenderMode::Normal, containing_item.stable_since(), true, None, false)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -3301,7 +3301,7 @@ fn item_trait(
|
||||
);
|
||||
render_impl(w, cx, &implementor, assoc_link,
|
||||
RenderMode::Normal, implementor.impl_item.stable_since(), false,
|
||||
None)?;
|
||||
None, true)?;
|
||||
}
|
||||
write_loading_content(w, "")?;
|
||||
}
|
||||
@ -3958,7 +3958,7 @@ fn render_assoc_items(w: &mut fmt::Formatter<'_>,
|
||||
};
|
||||
for i in &non_trait {
|
||||
render_impl(w, cx, i, AssocItemLink::Anchor(None), render_mode,
|
||||
containing_item.stable_since(), true, None)?;
|
||||
containing_item.stable_since(), true, None, false)?;
|
||||
}
|
||||
}
|
||||
if let AssocItemRender::DerefFor { .. } = what {
|
||||
@ -4138,11 +4138,15 @@ fn spotlight_decl(decl: &clean::FnDecl) -> Result<String, fmt::Error> {
|
||||
}
|
||||
|
||||
fn render_impl(w: &mut fmt::Formatter<'_>, cx: &Context, i: &Impl, link: AssocItemLink<'_>,
|
||||
render_mode: RenderMode, outer_version: Option<&str>,
|
||||
show_def_docs: bool, use_absolute: Option<bool>) -> fmt::Result {
|
||||
render_mode: RenderMode, outer_version: Option<&str>, show_def_docs: bool,
|
||||
use_absolute: Option<bool>, is_on_foreign_type: bool) -> fmt::Result {
|
||||
if render_mode == RenderMode::Normal {
|
||||
let id = cx.derive_id(match i.inner_impl().trait_ {
|
||||
Some(ref t) => format!("impl-{}", small_url_encode(&format!("{:#}", t))),
|
||||
Some(ref t) => if is_on_foreign_type {
|
||||
get_id_for_impl_on_foreign_type(&i.inner_impl().for_, t)
|
||||
} else {
|
||||
format!("impl-{}", small_url_encode(&format!("{:#}", t)))
|
||||
},
|
||||
None => "impl".to_string(),
|
||||
});
|
||||
if let Some(use_absolute) = use_absolute {
|
||||
@ -4688,11 +4692,15 @@ fn sidebar_struct(fmt: &mut fmt::Formatter<'_>, it: &clean::Item,
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_id_for_impl_on_foreign_type(for_: &clean::Type, trait_: &clean::Type) -> String {
|
||||
small_url_encode(&format!("impl-{:#}-for-{:#}", trait_, for_))
|
||||
}
|
||||
|
||||
fn extract_for_impl_name(item: &clean::Item) -> Option<(String, String)> {
|
||||
match item.inner {
|
||||
clean::ItemEnum::ImplItem(ref i) => {
|
||||
if let Some(ref trait_) = i.trait_ {
|
||||
Some((format!("{:#}", i.for_), format!("{:#}", trait_)))
|
||||
Some((format!("{:#}", i.for_), get_id_for_impl_on_foreign_type(&i.for_, trait_)))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -4788,9 +4796,9 @@ fn sidebar_trait(fmt: &mut fmt::Formatter<'_>, it: &clean::Item,
|
||||
.map_or(false, |d| !c.paths.contains_key(&d)))
|
||||
.filter_map(|i| {
|
||||
match extract_for_impl_name(&i.impl_item) {
|
||||
Some((ref name, ref url)) => {
|
||||
Some(format!("<a href=\"#impl-{}\">{}</a>",
|
||||
small_url_encode(url),
|
||||
Some((ref name, ref id)) => {
|
||||
Some(format!("<a href=\"#{}\">{}</a>",
|
||||
id,
|
||||
Escape(name)))
|
||||
}
|
||||
_ => None,
|
||||
|
@ -92,10 +92,10 @@ impl<R: Read> BufReader<R> {
|
||||
/// }
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn with_capacity(cap: usize, inner: R) -> BufReader<R> {
|
||||
pub fn with_capacity(capacity: usize, inner: R) -> BufReader<R> {
|
||||
unsafe {
|
||||
let mut buffer = Vec::with_capacity(cap);
|
||||
buffer.set_len(cap);
|
||||
let mut buffer = Vec::with_capacity(capacity);
|
||||
buffer.set_len(capacity);
|
||||
inner.initializer().initialize(&mut buffer);
|
||||
BufReader {
|
||||
inner,
|
||||
@ -477,10 +477,10 @@ impl<W: Write> BufWriter<W> {
|
||||
/// let mut buffer = BufWriter::with_capacity(100, stream);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn with_capacity(cap: usize, inner: W) -> BufWriter<W> {
|
||||
pub fn with_capacity(capacity: usize, inner: W) -> BufWriter<W> {
|
||||
BufWriter {
|
||||
inner: Some(inner),
|
||||
buf: Vec::with_capacity(cap),
|
||||
buf: Vec::with_capacity(capacity),
|
||||
panicked: false,
|
||||
}
|
||||
}
|
||||
@ -851,9 +851,9 @@ impl<W: Write> LineWriter<W> {
|
||||
/// }
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn with_capacity(cap: usize, inner: W) -> LineWriter<W> {
|
||||
pub fn with_capacity(capacity: usize, inner: W) -> LineWriter<W> {
|
||||
LineWriter {
|
||||
inner: BufWriter::with_capacity(cap, inner),
|
||||
inner: BufWriter::with_capacity(capacity, inner),
|
||||
need_flush: false,
|
||||
}
|
||||
}
|
||||
|
@ -146,10 +146,10 @@ impl Wtf8Buf {
|
||||
Wtf8Buf { bytes: Vec::new() }
|
||||
}
|
||||
|
||||
/// Creates a new, empty WTF-8 string with pre-allocated capacity for `n` bytes.
|
||||
/// Creates a new, empty WTF-8 string with pre-allocated capacity for `capacity` bytes.
|
||||
#[inline]
|
||||
pub fn with_capacity(n: usize) -> Wtf8Buf {
|
||||
Wtf8Buf { bytes: Vec::with_capacity(n) }
|
||||
pub fn with_capacity(capacity: usize) -> Wtf8Buf {
|
||||
Wtf8Buf { bytes: Vec::with_capacity(capacity) }
|
||||
}
|
||||
|
||||
/// Creates a WTF-8 string from a UTF-8 `String`.
|
||||
|
16
src/test/rustdoc/sidebar-links-to-foreign-impl.rs
Normal file
16
src/test/rustdoc/sidebar-links-to-foreign-impl.rs
Normal file
@ -0,0 +1,16 @@
|
||||
// issue #56018: "Implementations on Foreign Types" sidebar items should link to specific impls
|
||||
|
||||
#![crate_name = "foo"]
|
||||
|
||||
// @has foo/trait.Foo.html
|
||||
// @has - '//*[@class="sidebar-title"][@href="#foreign-impls"]' 'Implementations on Foreign Types'
|
||||
// @has - '//h2[@id="foreign-impls"]' 'Implementations on Foreign Types'
|
||||
// @has - '//*[@class="sidebar-links"]/a[@href="#impl-Foo-for-u32"]' 'u32'
|
||||
// @has - '//h3[@id="impl-Foo-for-u32"]//code' 'impl Foo for u32'
|
||||
// @has - '//*[@class="sidebar-links"]/a[@href="#impl-Foo-for-%26%27a%20str"]' "&'a str"
|
||||
// @has - '//h3[@id="impl-Foo-for-%26%27a%20str"]//code' "impl<'a> Foo for &'a str"
|
||||
pub trait Foo {}
|
||||
|
||||
impl Foo for u32 {}
|
||||
|
||||
impl<'a> Foo for &'a str {}
|
Loading…
Reference in New Issue
Block a user