Skip to content
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

Rollup of 7 pull requests #91505

Merged
merged 20 commits into from
Dec 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
29403ee
add unchecked downcast methods
ibraheemdev Nov 13, 2021
6f98293
add tracking issue for `downcast_unchecked`
ibraheemdev Nov 13, 2021
25271a5
fix doc links for `downcast_unchecked`
ibraheemdev Nov 20, 2021
f6b499d
Suggest the `pat_param` specifier before `|` on 2021 edition
ecstatic-morse Nov 30, 2021
4c1d317
Bless tests with new suggestion
ecstatic-morse Nov 30, 2021
bfd95e1
Bless duplicate test
ecstatic-morse Nov 30, 2021
e2846a7
Implement `@snapshot` check for htmldocck
camelid Nov 25, 2021
fe88fcf
Migrate a test to use `@snapshot`
camelid Nov 25, 2021
5b5df0f
Remove incorrect newline from float cast suggestion
estebank Dec 3, 2021
bdc4b46
Use let_else in some more places in rustc_lint
est31 Dec 3, 2021
7c108ab
Fix ICE when yielding in fn returning impl Trait
compiler-errors Dec 3, 2021
9931782
Document how recursion is handled for `ty::Ty`
camelid Nov 3, 2021
4ec5cdc
fix stability annotations for `Box::downcast`
ibraheemdev Dec 3, 2021
f99cd40
Rollup merge of #90538 - camelid:doc-recur-ty, r=estebank
matthiaskrgr Dec 4, 2021
0bd4ee7
Rollup merge of #90851 - ibraheemdev:downcast-unchecked, r=scottmcm
matthiaskrgr Dec 4, 2021
420ddd0
Rollup merge of #91209 - camelid:snapshot, r=jyn514
matthiaskrgr Dec 4, 2021
2b64476
Rollup merge of #91385 - ecstatic-morse:pat-param-spec-suggest, r=est…
matthiaskrgr Dec 4, 2021
f9587b6
Rollup merge of #91478 - estebank:fix-newline-in-cast-suggestion, r=c…
matthiaskrgr Dec 4, 2021
af546db
Rollup merge of #91481 - est31:let_else, r=jackh726
matthiaskrgr Dec 4, 2021
df51bff
Rollup merge of #91488 - compiler-errors:issue-91477, r=estebank
matthiaskrgr Dec 4, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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