Skip to content

Rollup of 4 pull requests #94692

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Mar 7, 2022
Merged
8 changes: 2 additions & 6 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
@@ -2064,17 +2064,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
)),
_ => None,
});
if let ImplTraitContext::TypeAliasesOpaqueTy { ref mut capturable_lifetimes, .. } =
itctx
{
if let ImplTraitContext::TypeAliasesOpaqueTy { ref mut capturable_lifetimes } = itctx {
capturable_lifetimes.extend(lt_def_names.clone());
}

let res = this.lower_trait_ref(&p.trait_ref, itctx.reborrow());

if let ImplTraitContext::TypeAliasesOpaqueTy { ref mut capturable_lifetimes, .. } =
itctx
{
if let ImplTraitContext::TypeAliasesOpaqueTy { ref mut capturable_lifetimes } = itctx {
for param in lt_def_names {
capturable_lifetimes.remove(&param);
}
10 changes: 5 additions & 5 deletions compiler/rustc_const_eval/src/interpret/cast.rs
Original file line number Diff line number Diff line change
@@ -97,7 +97,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
Ok(())
}

fn misc_cast(
pub fn misc_cast(
&self,
src: &ImmTy<'tcx, M::PointerTag>,
cast_ty: Ty<'tcx>,
@@ -139,7 +139,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
if let Some(discr) = src.layout.ty.discriminant_for_variant(*self.tcx, index) {
assert!(src.layout.is_zst());
let discr_layout = self.layout_of(discr.ty)?;
return Ok(self.cast_from_scalar(discr.val, discr_layout, cast_ty).into());
return Ok(self.cast_from_int_like(discr.val, discr_layout, cast_ty).into());
}
}
Variants::Multiple { .. } => {}
@@ -169,17 +169,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
}

// # The remaining source values are scalar.
// # The remaining source values are scalar and "int-like".

// For all remaining casts, we either
// (a) cast a raw ptr to usize, or
// (b) cast from an integer-like (including bool, char, enums).
// In both cases we want the bits.
let bits = src.to_scalar()?.to_bits(src.layout.size)?;
Ok(self.cast_from_scalar(bits, src.layout, cast_ty).into())
Ok(self.cast_from_int_like(bits, src.layout, cast_ty).into())
}

pub(super) fn cast_from_scalar(
fn cast_from_int_like(
&self,
v: u128, // raw bits (there is no ScalarTy so we separate data+layout)
src_layout: TyAndLayout<'tcx>,
11 changes: 8 additions & 3 deletions compiler/rustc_const_eval/src/interpret/operand.rs
Original file line number Diff line number Diff line change
@@ -681,18 +681,22 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let tag_val = self.read_immediate(&self.operand_field(op, tag_field)?)?;
assert_eq!(tag_layout.size, tag_val.layout.size);
assert_eq!(tag_layout.abi.is_signed(), tag_val.layout.abi.is_signed());
let tag_val = tag_val.to_scalar()?;
trace!("tag value: {:?}", tag_val);
trace!("tag value: {}", tag_val);

// Figure out which discriminant and variant this corresponds to.
Ok(match *tag_encoding {
TagEncoding::Direct => {
// Generate a specific error if `tag_val` is not an integer.
// (`tag_bits` itself is only used for error messages below.)
let tag_bits = tag_val
.to_scalar()?
.try_to_int()
.map_err(|dbg_val| err_ub!(InvalidTag(dbg_val)))?
.assert_bits(tag_layout.size);
// Cast bits from tag layout to discriminant layout.
let discr_val = self.cast_from_scalar(tag_bits, tag_layout, discr_layout.ty);
// After the checks we did above, this cannot fail.
let discr_val =
self.misc_cast(&tag_val, discr_layout.ty).unwrap().to_scalar().unwrap();
let discr_bits = discr_val.assert_bits(discr_layout.size);
// Convert discriminant to variant index, and catch invalid discriminants.
let index = match *op.layout.ty.kind() {
@@ -712,6 +716,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
(discr_val, index.0)
}
TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start } => {
let tag_val = tag_val.to_scalar()?;
// Compute the variant this niche value/"tag" corresponds to. With niche layout,
// discriminant (encoded in niche/tag) and variant index are the same.
let variants_start = niche_variants.start().as_u32();
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/mir/pretty.rs
Original file line number Diff line number Diff line change
@@ -660,7 +660,7 @@ pub fn write_allocations<'tcx>(
}
fn alloc_ids_from_const(val: ConstValue<'_>) -> impl Iterator<Item = AllocId> + '_ {
match val {
ConstValue::Scalar(interpret::Scalar::Ptr(ptr, _size)) => {
ConstValue::Scalar(interpret::Scalar::Ptr(ptr, _)) => {
Either::Left(Either::Left(std::iter::once(ptr.provenance)))
}
ConstValue::Scalar(interpret::Scalar::Int { .. }) => {
2 changes: 1 addition & 1 deletion compiler/rustc_privacy/src/lib.rs
Original file line number Diff line number Diff line change
@@ -852,7 +852,7 @@ impl ReachEverythingInTheInterfaceVisitor<'_, '_> {
self.visit(self.ev.tcx.type_of(param.def_id));
}
}
GenericParamDefKind::Const { has_default, .. } => {
GenericParamDefKind::Const { has_default } => {
self.visit(self.ev.tcx.type_of(param.def_id));
if has_default {
self.visit(self.ev.tcx.const_param_default(param.def_id));
Original file line number Diff line number Diff line change
@@ -405,7 +405,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
}
hir::Node::Item(hir::Item {
kind:
hir::ItemKind::Trait(_, _, generics, _, _)
hir::ItemKind::Trait(_, _, generics, ..)
| hir::ItemKind::Impl(hir::Impl { generics, .. }),
..
}) if projection.is_some() => {
2 changes: 1 addition & 1 deletion compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
@@ -1403,7 +1403,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.fcx.var_for_def(self.span, param)
}
}
GenericParamDefKind::Const { has_default, .. } => {
GenericParamDefKind::Const { has_default } => {
if !infer_args && has_default {
tcx.const_param_default(param.def_id)
.subst_spanned(tcx, substs.unwrap(), Some(self.span))
22 changes: 12 additions & 10 deletions compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
@@ -281,6 +281,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.demand_suptype(provided_arg.span, formal_input_ty, coerced_ty);
};

let minimum_input_count = formal_input_tys.len();

// 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
@@ -303,7 +305,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
})
}

let minimum_input_count = formal_input_tys.len();
for (idx, arg) in provided_args.iter().enumerate() {
// Warn only for the first loop (the "no closures" one).
// Closure arguments themselves can't be diverging, but
@@ -456,17 +457,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err.emit();
}

// We also need to make sure we at least write the ty of the other
// arguments which we skipped above.
if c_variadic {
fn variadic_error<'tcx>(sess: &Session, span: Span, ty: Ty<'tcx>, cast_ty: &str) {
use crate::structured_errors::MissingCastForVariadicArg;
for arg in provided_args.iter().skip(minimum_input_count) {
let arg_ty = self.check_expr(&arg);

MissingCastForVariadicArg { sess, span, ty, cast_ty }.diagnostic().emit();
}
if c_variadic {
// We also need to make sure we at least write the ty of the other
// arguments which we skipped above, either because they were additional
// c_variadic args, or because we had an argument count mismatch.
fn variadic_error<'tcx>(sess: &Session, span: Span, ty: Ty<'tcx>, cast_ty: &str) {
use crate::structured_errors::MissingCastForVariadicArg;

for arg in provided_args.iter().skip(expected_arg_count) {
let arg_ty = self.check_expr(&arg);
MissingCastForVariadicArg { sess, span, ty, cast_ty }.diagnostic().emit();
}

// There are a few types which get autopromoted when passed via varargs
// in C but we just error out instead and require explicit casts.
19 changes: 3 additions & 16 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
@@ -402,16 +402,7 @@ fn projection_to_path_segment(ty: ty::ProjectionTy<'_>, cx: &mut DocContext<'_>)
PathSegment {
name: item.name,
args: GenericArgs::AngleBracketed {
args: ty.substs[generics.parent_count..]
.iter()
.map(|ty| match ty.unpack() {
ty::subst::GenericArgKind::Lifetime(lt) => {
GenericArg::Lifetime(lt.clean(cx).unwrap())
}
ty::subst::GenericArgKind::Type(ty) => GenericArg::Type(ty.clean(cx)),
ty::subst::GenericArgKind::Const(c) => GenericArg::Const(Box::new(c.clean(cx))),
})
.collect(),
args: substs_to_args(cx, &ty.substs[generics.parent_count..], false),
bindings: Default::default(),
},
}
@@ -451,7 +442,7 @@ impl Clean<GenericParamDef> for ty::GenericParamDef {
},
)
}
ty::GenericParamDefKind::Const { has_default, .. } => (
ty::GenericParamDefKind::Const { has_default } => (
self.name,
GenericParamDefKind::Const {
did: self.def_id,
@@ -1379,11 +1370,7 @@ fn maybe_expand_private_type_alias(cx: &mut DocContext<'_>, path: &hir::Path<'_>
});
if let Some(lt) = lifetime.cloned() {
let lt_def_id = cx.tcx.hir().local_def_id(param.hir_id);
let cleaned = if !lt.is_elided() {
lt.clean(cx)
} else {
self::types::Lifetime::elided()
};
let cleaned = if !lt.is_elided() { lt.clean(cx) } else { Lifetime::elided() };
substs.insert(lt_def_id.to_def_id(), SubstParam::Lifetime(cleaned));
}
indices.lifetimes += 1;
45 changes: 25 additions & 20 deletions src/librustdoc/clean/utils.rs
Original file line number Diff line number Diff line change
@@ -77,16 +77,12 @@ crate fn krate(cx: &mut DocContext<'_>) -> Crate {
Crate { module, primitives, external_traits: cx.external_traits.clone() }
}

fn external_generic_args(
crate fn substs_to_args(
cx: &mut DocContext<'_>,
did: DefId,
has_self: bool,
bindings: Vec<TypeBinding>,
substs: SubstsRef<'_>,
) -> GenericArgs {
let mut skip_self = has_self;
let mut ty_kind = None;
let args: Vec<_> = substs
substs: &[ty::subst::GenericArg<'_>],
mut skip_first: bool,
) -> Vec<GenericArg> {
substs
.iter()
.filter_map(|kind| match kind.unpack() {
GenericArgKind::Lifetime(lt) => match *lt {
@@ -95,23 +91,32 @@ fn external_generic_args(
}
_ => lt.clean(cx).map(GenericArg::Lifetime),
},
GenericArgKind::Type(_) if skip_self => {
skip_self = false;
GenericArgKind::Type(_) if skip_first => {
skip_first = false;
None
}
GenericArgKind::Type(ty) => {
ty_kind = Some(ty.kind());
Some(GenericArg::Type(ty.clean(cx)))
}
GenericArgKind::Type(ty) => Some(GenericArg::Type(ty.clean(cx))),
GenericArgKind::Const(ct) => Some(GenericArg::Const(Box::new(ct.clean(cx)))),
})
.collect();
.collect()
}

fn external_generic_args(
cx: &mut DocContext<'_>,
did: DefId,
has_self: bool,
bindings: Vec<TypeBinding>,
substs: SubstsRef<'_>,
) -> GenericArgs {
let args = substs_to_args(cx, &substs, has_self);

if cx.tcx.fn_trait_kind_from_lang_item(did).is_some() {
let inputs = match ty_kind.unwrap() {
ty::Tuple(tys) => tys.iter().map(|t| t.clean(cx)).collect(),
_ => return GenericArgs::AngleBracketed { args, bindings: bindings.into() },
};
let inputs =
// The trait's first substitution is the one after self, if there is one.
match substs.iter().nth(if has_self { 1 } else { 0 }).unwrap().expect_ty().kind() {
ty::Tuple(tys) => tys.iter().map(|t| t.clean(cx)).collect(),
_ => return GenericArgs::AngleBracketed { args, bindings: bindings.into() },
};
let output = None;
// FIXME(#20299) return type comes from a projection now
// match types[1].kind {
13 changes: 13 additions & 0 deletions src/test/rustdoc/generic-associated-types/issue-94683.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#![crate_name = "foo"]
#![feature(generic_associated_types)]

pub trait Trait {
type Gat<'a>;
}

// Make sure that the elided lifetime shows up

// @has foo/type.T.html
// @has - "pub type T = "
// @has - "&lt;'_&gt;"
pub type T = fn(&<() as Trait>::Gat<'_>);
6 changes: 6 additions & 0 deletions src/test/ui/tuple/wrong_argument_ice-4.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fn main() {
(|| {})(|| {
//~^ ERROR this function takes 0 arguments but 1 argument was supplied
let b = 1;
});
}
15 changes: 15 additions & 0 deletions src/test/ui/tuple/wrong_argument_ice-4.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error[E0057]: this function takes 0 arguments but 1 argument was supplied
--> $DIR/wrong_argument_ice-4.rs:2:5
|
LL | (|| {})(|| {
| _____^^^^^^^_-
| | |
| | expected 0 arguments
LL | |
LL | | let b = 1;
LL | | });
| |_____- supplied 1 argument

error: aborting due to previous error

For more information about this error, try `rustc --explain E0057`.