Skip to content

Commit

Permalink
Auto merge of #91505 - matthiaskrgr:rollup-orxgsxo, r=matthiaskrgr
Browse files Browse the repository at this point in the history
Rollup of 7 pull requests

Successful merges:

 - #90538 (Document how recursion is handled for `ty::Ty`)
 - #90851 (Add unchecked downcast methods)
 - #91209 (Implement ``@snapshot`` check for htmldocck)
 - #91385 (Suggest the `pat_param` specifier before `|` on 2021 edition )
 - #91478 (Remove incorrect newline from float cast suggestion)
 - #91481 (Use let_else in some more places in rustc_lint)
 - #91488 (Fix ICE when `yield`ing in function returning `impl Trait`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Dec 4, 2021
2 parents 14c1e71 + df51bff commit f581572
Show file tree
Hide file tree
Showing 23 changed files with 530 additions and 146 deletions.
26 changes: 23 additions & 3 deletions compiler/rustc_borrowck/src/type_check/input_output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,29 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}
}

assert!(body.yield_ty().is_some() == universal_regions.yield_ty.is_some());
if let Some(mir_yield_ty) = body.yield_ty() {
let ur_yield_ty = universal_regions.yield_ty.unwrap();
debug!(
"equate_inputs_and_outputs: body.yield_ty {:?}, universal_regions.yield_ty {:?}",
body.yield_ty(),
universal_regions.yield_ty
);

// We will not have a universal_regions.yield_ty if we yield (by accident)
// outside of a generator and return an `impl Trait`, so emit a delay_span_bug
// because we don't want to panic in an assert here if we've already got errors.
if body.yield_ty().is_some() != universal_regions.yield_ty.is_some() {
self.tcx().sess.delay_span_bug(
body.span,
&format!(
"Expected body to have yield_ty ({:?}) iff we have a UR yield_ty ({:?})",
body.yield_ty(),
universal_regions.yield_ty,
),
);
}

if let (Some(mir_yield_ty), Some(ur_yield_ty)) =
(body.yield_ty(), universal_regions.yield_ty)
{
let yield_span = body.local_decls[RETURN_PLACE].source_info.span;
self.equate_normalized_input_or_output(ur_yield_ty, mir_yield_ty, yield_span);
}
Expand Down
18 changes: 18 additions & 0 deletions compiler/rustc_expand/src/mbe/macro_rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1027,6 +1027,24 @@ fn check_matcher_core(
),
);
err.span_label(sp, format!("not allowed after `{}` fragments", kind));

if kind == NonterminalKind::PatWithOr
&& sess.edition == Edition::Edition2021
&& next_token.is_token(&BinOp(token::BinOpToken::Or))
{
let suggestion = quoted_tt_to_string(&TokenTree::MetaVarDecl(
span,
name,
Some(NonterminalKind::PatParam { inferred: false }),
));
err.span_suggestion(
span,
&format!("try a `pat_param` fragment specifier instead"),
suggestion,
Applicability::MaybeIncorrect,
);
}

let msg = "allowed there are: ";
match possible {
&[] => {}
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_lint/src/array_into_iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,8 @@ impl<'tcx> LateLintPass<'tcx> for ArrayIntoIter {
let receiver_ty = cx.typeck_results().expr_ty(receiver_arg);
let adjustments = cx.typeck_results().expr_adjustments(receiver_arg);

let target = match adjustments.last() {
Some(Adjustment { kind: Adjust::Borrow(_), target }) => target,
_ => return,
let Some(Adjustment { kind: Adjust::Borrow(_), target }) = adjustments.last() else {
return
};

let types =
Expand Down
64 changes: 29 additions & 35 deletions compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -609,14 +609,12 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
// If the trait is private, add the impl items to `private_traits` so they don't get
// reported for missing docs.
let real_trait = trait_ref.path.res.def_id();
if let Some(def_id) = real_trait.as_local() {
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def_id);
if let Some(Node::Item(item)) = cx.tcx.hir().find(hir_id) {
if let hir::VisibilityKind::Inherited = item.vis.node {
for impl_item_ref in items {
self.private_traits.insert(impl_item_ref.id.hir_id());
}
}
let Some(def_id) = real_trait.as_local() else { return };
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def_id);
let Some(Node::Item(item)) = cx.tcx.hir().find(hir_id) else { return };
if let hir::VisibilityKind::Inherited = item.vis.node {
for impl_item_ref in items {
self.private_traits.insert(impl_item_ref.id.hir_id());
}
}
return;
Expand Down Expand Up @@ -829,9 +827,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations {
_ => return,
}

let debug = match cx.tcx.get_diagnostic_item(sym::Debug) {
Some(debug) => debug,
None => return,
let Some(debug) = cx.tcx.get_diagnostic_item(sym::Debug) else {
return
};

if self.impling_types.is_none() {
Expand Down Expand Up @@ -1509,9 +1506,8 @@ impl TypeAliasBounds {

impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
let (ty, type_alias_generics) = match item.kind {
hir::ItemKind::TyAlias(ref ty, ref generics) => (&*ty, generics),
_ => return,
let hir::ItemKind::TyAlias(ty, type_alias_generics) = &item.kind else {
return
};
if let hir::TyKind::OpaqueDef(..) = ty.kind {
// Bounds are respected for `type X = impl Trait`
Expand Down Expand Up @@ -2266,16 +2262,15 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
// and should check for them here.
match predicate.bounded_ty.kind {
hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) => {
if let Res::Def(DefKind::TyParam, def_id) = path.res {
let index = ty_generics.param_def_id_to_index[&def_id];
(
Self::lifetimes_outliving_type(inferred_outlives, index),
&predicate.bounds,
predicate.span,
)
} else {
continue;
}
let Res::Def(DefKind::TyParam, def_id) = path.res else {
continue
};
let index = ty_generics.param_def_id_to_index[&def_id];
(
Self::lifetimes_outliving_type(inferred_outlives, index),
&predicate.bounds,
predicate.span,
)
}
_ => {
continue;
Expand Down Expand Up @@ -3216,18 +3211,17 @@ impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels {
for (idx, _) in statement.match_indices(':') {
let possible_label = statement[start_idx..idx].trim();
let mut chars = possible_label.chars();
if let Some(c) = chars.next() {
// A label starts with an alphabetic character or . or _ and continues with alphanumeric characters, _, or $
if (c.is_alphabetic() || matches!(c, '.' | '_'))
&& chars.all(|c| c.is_alphanumeric() || matches!(c, '_' | '$'))
{
found_labels.push(possible_label);
} else {
// If we encounter a non-label, there cannot be any further labels, so stop checking
break;
}
} else {
let Some(c) = chars.next() else {
// Empty string means a leading ':' in this section, which is not a label
break
};
// A label starts with an alphabetic character or . or _ and continues with alphanumeric characters, _, or $
if (c.is_alphabetic() || matches!(c, '.' | '_'))
&& chars.all(|c| c.is_alphanumeric() || matches!(c, '_' | '$'))
{
found_labels.push(possible_label);
} else {
// If we encounter a non-label, there cannot be any further labels, so stop checking
break;
}

Expand Down
15 changes: 6 additions & 9 deletions compiler/rustc_lint/src/levels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,14 +227,12 @@ impl<'s> LintLevelsBuilder<'s> {
let sess = self.sess;
let bad_attr = |span| struct_span_err!(sess, span, E0452, "malformed lint attribute input");
for attr in attrs {
let level = match Level::from_symbol(attr.name_or_empty()) {
None => continue,
Some(lvl) => lvl,
let Some(level) = Level::from_symbol(attr.name_or_empty()) else {
continue
};

let mut metas = match attr.meta_item_list() {
Some(x) => x,
None => continue,
let Some(mut metas) = attr.meta_item_list() else {
continue
};

if metas.is_empty() {
Expand Down Expand Up @@ -481,9 +479,8 @@ impl<'s> LintLevelsBuilder<'s> {
continue;
}

let (lint_attr_name, lint_attr_span) = match *src {
LintLevelSource::Node(name, span, _) => (name, span),
_ => continue,
let LintLevelSource::Node(lint_attr_name, lint_attr_span, _) = *src else {
continue
};

let lint = builtin::UNUSED_ATTRIBUTES;
Expand Down
10 changes: 4 additions & 6 deletions compiler/rustc_lint/src/noop_method_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,8 @@ declare_lint_pass!(NoopMethodCall => [NOOP_METHOD_CALL]);
impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
// We only care about method calls.
let (call, elements) = match expr.kind {
ExprKind::MethodCall(call, _, elements, _) => (call, elements),
_ => return,
let ExprKind::MethodCall(call, _, elements, _) = &expr.kind else {
return
};
// We only care about method calls corresponding to the `Clone`, `Deref` and `Borrow`
// traits and ignore any other method call.
Expand Down Expand Up @@ -70,9 +69,8 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
}
let param_env = cx.tcx.param_env(trait_id);
// Resolve the trait method instance.
let i = match ty::Instance::resolve(cx.tcx, param_env, did, substs) {
Ok(Some(i)) => i,
_ => return,
let Ok(Some(i)) = ty::Instance::resolve(cx.tcx, param_env, did, substs) else {
return
};
// (Re)check that it implements the noop diagnostic.
let Some(name) = cx.tcx.get_diagnostic_name(i.def_id()) else { return };
Expand Down
20 changes: 8 additions & 12 deletions compiler/rustc_lint/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,8 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {

let predicates = cx.tcx.explicit_predicates_of(item.def_id);
for &(predicate, span) in predicates.predicates {
let trait_predicate = match predicate.kind().skip_binder() {
Trait(trait_predicate) => trait_predicate,
_ => continue,
let Trait(trait_predicate) = predicate.kind().skip_binder() else {
continue
};
if trait_predicate.constness == ty::BoundConstness::ConstIfConst {
// `~const Drop` definitely have meanings so avoid linting here.
Expand All @@ -106,9 +105,8 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
continue;
}
cx.struct_span_lint(DROP_BOUNDS, span, |lint| {
let needs_drop = match cx.tcx.get_diagnostic_item(sym::needs_drop) {
Some(needs_drop) => needs_drop,
None => return,
let Some(needs_drop) = cx.tcx.get_diagnostic_item(sym::needs_drop) else {
return
};
let msg = format!(
"bounds on `{}` are most likely incorrect, consider instead \
Expand All @@ -123,17 +121,15 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
}

fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx hir::Ty<'tcx>) {
let bounds = match &ty.kind {
hir::TyKind::TraitObject(bounds, _lifetime, _syntax) => bounds,
_ => return,
let hir::TyKind::TraitObject(bounds, _lifetime, _syntax) = &ty.kind else {
return
};
for bound in &bounds[..] {
let def_id = bound.trait_ref.trait_def_id();
if cx.tcx.lang_items().drop_trait() == def_id {
cx.struct_span_lint(DYN_DROP, bound.span, |lint| {
let needs_drop = match cx.tcx.get_diagnostic_item(sym::needs_drop) {
Some(needs_drop) => needs_drop,
None => return,
let Some(needs_drop) = cx.tcx.get_diagnostic_item(sym::needs_drop) else {
return
};
let msg = format!(
"types that do not implement `Drop` can still have drop glue, consider \
Expand Down
7 changes: 3 additions & 4 deletions compiler/rustc_lint/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1342,11 +1342,10 @@ impl<'tcx> LateLintPass<'tcx> for VariantSizeDifferences {
| ty::layout::LayoutError::NormalizationFailure(_, _),
) => return,
};
let (variants, tag) = match layout.variants {
Variants::Multiple {
let Variants::Multiple {
tag_encoding: TagEncoding::Direct, tag, ref variants, ..
} => (variants, tag),
_ => return,
} = &layout.variants else {
return
};

let tag_size = tag.value.size(&cx.tcx).bytes();
Expand Down
24 changes: 24 additions & 0 deletions compiler/rustc_middle/src/ty/adt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,30 @@ bitflags! {
/// Moreover, Rust only allows recursive data types through indirection.
///
/// [adt]: https://en.wikipedia.org/wiki/Algebraic_data_type
///
/// # Recursive types
///
/// It may seem impossible to represent recursive types using [`Ty`],
/// since [`TyKind::Adt`] includes [`AdtDef`], which includes its fields,
/// creating a cycle. However, `AdtDef` does not actually include the *types*
/// of its fields; it includes just their [`DefId`]s.
///
/// [`TyKind::Adt`]: ty::TyKind::Adt
///
/// For example, the following type:
///
/// ```
/// struct S { x: Box<S> }
/// ```
///
/// is essentially represented with [`Ty`] as the following pseudocode:
///
/// ```
/// struct S { x }
/// ```
///
/// where `x` here represents the `DefId` of `S.x`. Then, the `DefId`
/// can be used with [`TyCtxt::type_of()`] to get the type of the field.
pub struct AdtDef {
/// The `DefId` of the struct, enum or union item.
pub did: DefId,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1711,7 +1711,7 @@ impl ReprOptions {

impl<'tcx> FieldDef {
/// Returns the type of this field. The resulting type is not normalized. The `subst` is
/// typically obtained via the second field of `TyKind::AdtDef`.
/// typically obtained via the second field of [`TyKind::Adt`].
pub fn ty(&self, tcx: TyCtxt<'tcx>, subst: SubstsRef<'tcx>) -> Ty<'tcx> {
tcx.type_of(self.did).subst(tcx, subst)
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_typeck/src/check/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1223,7 +1223,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Missing try_into implementation for `{integer}` to `{float}`
err.multipart_suggestion_verbose(
&format!(
"{}, producing the floating point representation of the integer,
"{}, producing the floating point representation of the integer, \
rounded if necessary",
cast_msg,
),
Expand Down
Loading

0 comments on commit f581572

Please sign in to comment.