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 11 pull requests #120237

Closed
wants to merge 29 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
c0a9f72
Undeprecate and use lint `unstable_features`
fmease Dec 5, 2023
bfe04e0
Fix deallocation with wrong allocator in (A)Rc::from_box_in
zachs18 Jan 9, 2024
3b325bc
Refactor uses of `objc_msgSend` to no longer have clashing definitions
madsmtm Nov 14, 2023
341f0a1
revert temporary patch #108288
onur-ozkan Jan 17, 2024
8a461aa
distribute actual stage of the compiled compiler
onur-ozkan Jan 18, 2024
12ebc3d
Add tests
Nadrieril Jan 18, 2024
753680a
Consistently set `MatchVisitor.error` on error
Nadrieril Jan 18, 2024
0a9bb97
Consistently warn unreachable subpatterns
Nadrieril Jan 18, 2024
f26f52c
Validate AggregateKind types in MIR
compiler-errors Jan 19, 2024
fc75a4e
Allow any expression blocks in `thread_local!`
nvzqz Oct 3, 2023
f52b88e
Revert example change from PR 116392
dtolnay Jan 21, 2024
c43344e
Add test of thread_local containing multiline const block
dtolnay Jan 21, 2024
b58a8a9
`maybe_lint_impl_trait`: separate `is_downgradable` from `is_object_s…
trevyn Jan 20, 2024
7ee5f3a
Builtin macros effectively have implicit #[collapse_debuginfo(yes)] a…
azhogin Jan 21, 2024
981e8b4
Check that a token can begin a nonterminal kind before parsing it as …
compiler-errors Jan 22, 2024
b93ae21
Do not eagerly recover malformed AST in rustfmt
compiler-errors Jan 22, 2024
5297433
Actually, just use nonterminal_may_begin_with
compiler-errors Jan 22, 2024
9454b51
Make generic const type mismatches not hide trait impls from the trai…
oli-obk Jan 17, 2024
299c0fb
Rollup merge of #117910 - madsmtm:msg-send-no-clashing, r=thomcc
matthiaskrgr Jan 22, 2024
f1d9c1a
Rollup merge of #118639 - fmease:deny-features-in-stable-rustc-crates…
matthiaskrgr Jan 22, 2024
aac7ea7
Rollup merge of #119801 - zachs18:zachs18-patch-1, r=steffahn,Nilstrieb
matthiaskrgr Jan 22, 2024
7b6311b
Rollup merge of #120058 - onur-ozkan:compiler-assemble, r=Mark-Simula…
matthiaskrgr Jan 22, 2024
071938a
Rollup merge of #120059 - oli-obk:const_arg_type_mismatch, r=compiler…
matthiaskrgr Jan 22, 2024
64cea92
Rollup merge of #120097 - Nadrieril:consistent_unreachable_subpats, r…
matthiaskrgr Jan 22, 2024
7902c69
Rollup merge of #120137 - compiler-errors:validate-aggregates, r=nnet…
matthiaskrgr Jan 22, 2024
dc4234d
Rollup merge of #120164 - trevyn:is_downgradable, r=compiler-errors
matthiaskrgr Jan 22, 2024
a71e49c
Rollup merge of #120181 - dtolnay:tlconst, r=thomcc
matthiaskrgr Jan 22, 2024
3423853
Rollup merge of #120204 - azhogin:azhogin/collapse_debuginfo_for_buil…
matthiaskrgr Jan 22, 2024
e153296
Rollup merge of #120218 - compiler-errors:parse_macro_arg, r=calebcar…
matthiaskrgr Jan 22, 2024
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
62 changes: 61 additions & 1 deletion compiler/rustc_const_eval/src/transform/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -796,7 +796,67 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
};
}
match rvalue {
Rvalue::Use(_) | Rvalue::CopyForDeref(_) | Rvalue::Aggregate(..) => {}
Rvalue::Use(_) | Rvalue::CopyForDeref(_) => {}
Rvalue::Aggregate(kind, fields) => match **kind {
AggregateKind::Tuple => {}
AggregateKind::Array(dest) => {
for src in fields {
if !self.mir_assign_valid_types(src.ty(self.body, self.tcx), dest) {
self.fail(location, "array field has the wrong type");
}
}
}
AggregateKind::Adt(def_id, idx, args, _, Some(field)) => {
let adt_def = self.tcx.adt_def(def_id);
assert!(adt_def.is_union());
assert_eq!(idx, FIRST_VARIANT);
let dest = adt_def.non_enum_variant().fields[field].ty(self.tcx, args);
if fields.len() != 1 {
self.fail(location, "unions should have one initialized field");
}
if !self.mir_assign_valid_types(fields.raw[0].ty(self.body, self.tcx), dest) {
self.fail(location, "union field has the wrong type");
}
}
AggregateKind::Adt(def_id, idx, args, _, None) => {
let adt_def = self.tcx.adt_def(def_id);
assert!(!adt_def.is_union());
let variant = &adt_def.variants()[idx];
if variant.fields.len() != fields.len() {
self.fail(location, "adt has the wrong number of initialized fields");
}
for (src, dest) in std::iter::zip(fields, &variant.fields) {
if !self.mir_assign_valid_types(
src.ty(self.body, self.tcx),
dest.ty(self.tcx, args),
) {
self.fail(location, "adt field has the wrong type");
}
}
}
AggregateKind::Closure(_, args) => {
let upvars = args.as_closure().upvar_tys();
if upvars.len() != fields.len() {
self.fail(location, "closure has the wrong number of initialized fields");
}
for (src, dest) in std::iter::zip(fields, upvars) {
if !self.mir_assign_valid_types(src.ty(self.body, self.tcx), dest) {
self.fail(location, "closure field has the wrong type");
}
}
}
AggregateKind::Coroutine(_, args) => {
let upvars = args.as_coroutine().upvar_tys();
if upvars.len() != fields.len() {
self.fail(location, "coroutine has the wrong number of initialized fields");
}
for (src, dest) in std::iter::zip(fields, upvars) {
if !self.mir_assign_valid_types(src.ty(self.body, self.tcx), dest) {
self.fail(location, "coroutine field has the wrong type");
}
}
}
},
Rvalue::Ref(_, BorrowKind::Fake, _) => {
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
self.fail(
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -796,9 +796,15 @@ impl SyntaxExtension {
/// | external | no | if-ext | if-ext | yes |
/// | yes | yes | yes | yes | yes |
fn get_collapse_debuginfo(sess: &Session, attrs: &[ast::Attribute], is_local: bool) -> bool {
let collapse_debuginfo_attr = attr::find_by_name(attrs, sym::collapse_debuginfo)
let mut collapse_debuginfo_attr = attr::find_by_name(attrs, sym::collapse_debuginfo)
.map(|v| Self::collapse_debuginfo_by_name(sess, v))
.unwrap_or(CollapseMacroDebuginfo::Unspecified);
if collapse_debuginfo_attr == CollapseMacroDebuginfo::Unspecified
&& attr::contains_name(attrs, sym::rustc_builtin_macro)
{
collapse_debuginfo_attr = CollapseMacroDebuginfo::Yes;
}

let flag = sess.opts.unstable_opts.collapse_macro_debuginfo;
let attr = collapse_debuginfo_attr;
let ext = !is_local;
Expand Down
16 changes: 9 additions & 7 deletions compiler/rustc_hir_analysis/src/astconv/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
return false;
};
let impl_sugg = vec![(self_ty.span.shrink_to_lo(), "impl ".to_string())];
let mut is_downgradable = true;
let is_object_safe = match self_ty.kind {
hir::TyKind::TraitObject(objects, ..) => {
objects.iter().all(|o| match o.trait_ref.path.res {
Res::Def(DefKind::Trait, id) if Some(id) == owner => {
// When we're dealing with a recursive trait, we don't want to downgrade
// the error, so we consider them to be object safe always. (#119652)
true
Res::Def(DefKind::Trait, id) => {
if Some(id) == owner {
// For recursive traits, don't downgrade the error. (#119652)
is_downgradable = false;
}
tcx.check_is_object_safe(id)
}
Res::Def(DefKind::Trait, id) => tcx.check_is_object_safe(id),
_ => false,
})
}
Expand Down Expand Up @@ -130,7 +132,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
],
Applicability::MachineApplicable,
);
} else if diag.is_error() {
} else if diag.is_error() && is_downgradable {
// We'll emit the object safety error already, with a structured suggestion.
diag.downgrade_to_delayed_bug();
}
Expand All @@ -156,7 +158,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
if !is_object_safe {
diag.note(format!("`{trait_name}` it is not object safe, so it can't be `dyn`"));
if diag.is_error() {
if diag.is_error() && is_downgradable {
// We'll emit the object safety error already, with a structured suggestion.
diag.downgrade_to_delayed_bug();
}
Expand Down
34 changes: 10 additions & 24 deletions compiler/rustc_infer/src/infer/relate/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,9 @@ impl<'tcx> InferCtxt<'tcx> {
//
// This probe is probably not strictly necessary but it seems better to be safe and not accidentally find
// ourselves with a check to find bugs being required for code to compile because it made inference progress.
let compatible_types = self.probe(|_| {
self.probe(|_| {
if a.ty() == b.ty() {
return Ok(());
return;
}

// We don't have access to trait solving machinery in `rustc_infer` so the logic for determining if the
Expand All @@ -177,32 +177,18 @@ impl<'tcx> InferCtxt<'tcx> {
relation.param_env().and((a.ty(), b.ty())),
&mut OriginalQueryValues::default(),
);
self.tcx.check_tys_might_be_eq(canonical).map_err(|_| {
self.tcx.check_tys_might_be_eq(canonical).unwrap_or_else(|_| {
// The error will only be reported later. If we emit an ErrorGuaranteed
// here, then we will never get to the code that actually emits the error.
self.tcx.dcx().delayed_bug(format!(
"cannot relate consts of different types (a={a:?}, b={b:?})",
))
})
));
// We treat these constants as if they were of the same type, so that any
// such constants being used in impls make these impls match barring other mismatches.
// This helps with diagnostics down the road.
});
});

// If the consts have differing types, just bail with a const error with
// the expected const's type. Specifically, we don't want const infer vars
// to do any type shapeshifting before and after resolution.
if let Err(guar) = compatible_types {
// HACK: equating both sides with `[const error]` eagerly prevents us
// from leaving unconstrained inference vars during things like impl
// matching in the solver.
let a_error = ty::Const::new_error(self.tcx, guar, a.ty());
if let ty::ConstKind::Infer(InferConst::Var(vid)) = a.kind() {
return self.unify_const_variable(vid, a_error, relation.param_env());
}
let b_error = ty::Const::new_error(self.tcx, guar, b.ty());
if let ty::ConstKind::Infer(InferConst::Var(vid)) = b.kind() {
return self.unify_const_variable(vid, b_error, relation.param_env());
}

return Ok(if relation.a_is_expected() { a_error } else { b_error });
}

match (a.kind(), b.kind()) {
(
ty::ConstKind::Infer(InferConst::Var(a_vid)),
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_lexer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@
//! [`rustc_parse::lexer`]: ../rustc_parse/lexer/index.html
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
// We want to be able to build this crate with a stable compiler, so no
// `#![feature]` attributes should be added.
// We want to be able to build this crate with a stable compiler,
// so no `#![feature]` attributes should be added.
#![deny(unstable_features)]

mod cursor;
pub mod unescape;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ lint_builtin_unsafe_impl = implementation of an `unsafe` trait

lint_builtin_unsafe_trait = declaration of an `unsafe` trait

lint_builtin_unstable_features = unstable feature
lint_builtin_unstable_features = use of an unstable feature

lint_builtin_unused_doc_comment = unused doc comment
.label = rustdoc does not generate documentation for {$kind}
Expand Down
34 changes: 27 additions & 7 deletions compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1233,10 +1233,30 @@ impl<'tcx> LateLintPass<'tcx> for MutableTransmutes {
}

declare_lint! {
/// The `unstable_features` is deprecated and should no longer be used.
/// The `unstable_features` lint detects uses of `#![feature]`.
///
/// ### Example
///
/// ```rust,compile_fail
/// #![deny(unstable_features)]
/// #![feature(test)]
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// In larger nightly-based projects which
///
/// * consist of a multitude of crates where a subset of crates has to compile on
/// stable either unconditionally or depending on a `cfg` flag to for example
/// allow stable users to depend on them,
/// * don't use nightly for experimental features but for, e.g., unstable options only,
///
/// this lint may come in handy to enforce policies of these kinds.
UNSTABLE_FEATURES,
Allow,
"enabling unstable features (deprecated. do not use)"
"enabling unstable features"
}

declare_lint_pass!(
Expand All @@ -1246,11 +1266,11 @@ declare_lint_pass!(

impl<'tcx> LateLintPass<'tcx> for UnstableFeatures {
fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &ast::Attribute) {
if attr.has_name(sym::feature) {
if let Some(items) = attr.meta_item_list() {
for item in items {
cx.emit_spanned_lint(UNSTABLE_FEATURES, item.span(), BuiltinUnstableFeatures);
}
if attr.has_name(sym::feature)
&& let Some(items) = attr.meta_item_list()
{
for item in items {
cx.emit_spanned_lint(UNSTABLE_FEATURES, item.span(), BuiltinUnstableFeatures);
}
}
}
Expand Down
88 changes: 49 additions & 39 deletions compiler/rustc_mir_build/src/thir/pattern/check_match.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use rustc_pattern_analysis::errors::Uncovered;
use rustc_pattern_analysis::rustc::{
Constructor, DeconstructedPat, RustcMatchCheckCtxt as MatchCheckCtxt, Usefulness,
Constructor, DeconstructedPat, MatchArm, RustcMatchCheckCtxt as MatchCheckCtxt, Usefulness,
UsefulnessReport, WitnessPat,
};
use rustc_pattern_analysis::{analyze_match, MatchArm};

use crate::errors::*;

Expand Down Expand Up @@ -390,6 +389,34 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
}
}

fn analyze_patterns(
&mut self,
cx: &MatchCheckCtxt<'p, 'tcx>,
arms: &[MatchArm<'p, 'tcx>],
scrut_ty: Ty<'tcx>,
) -> Result<UsefulnessReport<'p, 'tcx>, ErrorGuaranteed> {
let report =
rustc_pattern_analysis::analyze_match(&cx, &arms, scrut_ty).map_err(|err| {
self.error = Err(err);
err
})?;

// Warn unreachable subpatterns.
for (arm, is_useful) in report.arm_usefulness.iter() {
if let Usefulness::Useful(redundant_subpats) = is_useful
&& !redundant_subpats.is_empty()
{
let mut redundant_subpats = redundant_subpats.clone();
// Emit lints in the order in which they occur in the file.
redundant_subpats.sort_unstable_by_key(|pat| pat.data().unwrap().span);
for pat in redundant_subpats {
report_unreachable_pattern(cx, arm.arm_data, pat.data().unwrap().span, None)
}
}
}
Ok(report)
}

#[instrument(level = "trace", skip(self))]
fn check_let(&mut self, pat: &'p Pat<'tcx>, scrutinee: Option<ExprId>, span: Span) {
assert!(self.let_source != LetSource::None);
Expand Down Expand Up @@ -435,14 +462,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
}
}

let scrut_ty = scrut.ty;
let report = match analyze_match(&cx, &tarms, scrut_ty) {
Ok(report) => report,
Err(err) => {
self.error = Err(err);
return;
}
};
let Ok(report) = self.analyze_patterns(&cx, &tarms, scrut.ty) else { return };

match source {
// Don't report arm reachability of desugared `match $iter.into_iter() { iter => .. }`
Expand Down Expand Up @@ -474,7 +494,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
);
} else {
self.error = Err(report_non_exhaustive_match(
&cx, self.thir, scrut_ty, scrut.span, witnesses, arms, expr_span,
&cx, self.thir, scrut.ty, scrut.span, witnesses, arms, expr_span,
));
}
}
Expand Down Expand Up @@ -556,7 +576,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
let cx = self.new_cx(refutability, None, scrut, pat.span);
let pat = self.lower_pattern(&cx, pat)?;
let arms = [MatchArm { pat, arm_data: self.lint_level, has_guard: false }];
let report = analyze_match(&cx, &arms, pat.ty().inner())?;
let report = self.analyze_patterns(&cx, &arms, pat.ty().inner())?;
Ok((cx, report))
}

Expand All @@ -567,7 +587,6 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
) -> Result<RefutableFlag, ErrorGuaranteed> {
let (cx, report) = self.analyze_binding(pat, Refutable, scrut)?;
// Report if the pattern is unreachable, which can only occur when the type is uninhabited.
// This also reports unreachable sub-patterns.
report_arm_reachability(&cx, &report);
// If the list of witnesses is empty, the match is exhaustive, i.e. the `if let` pattern is
// irrefutable.
Expand Down Expand Up @@ -850,39 +869,30 @@ fn report_irrefutable_let_patterns(
}
}

/// Report unreachable arms, if any.
fn report_unreachable_pattern<'p, 'tcx>(
cx: &MatchCheckCtxt<'p, 'tcx>,
hir_id: HirId,
span: Span,
catchall: Option<Span>,
) {
cx.tcx.emit_spanned_lint(
UNREACHABLE_PATTERNS,
hir_id,
span,
UnreachablePattern { span: if catchall.is_some() { Some(span) } else { None }, catchall },
);
}

/// Report unreachable arms, if any.
fn report_arm_reachability<'p, 'tcx>(
cx: &MatchCheckCtxt<'p, 'tcx>,
report: &UsefulnessReport<'p, 'tcx>,
) {
let report_unreachable_pattern = |span, hir_id, catchall: Option<Span>| {
cx.tcx.emit_spanned_lint(
UNREACHABLE_PATTERNS,
hir_id,
span,
UnreachablePattern {
span: if catchall.is_some() { Some(span) } else { None },
catchall,
},
);
};

let mut catchall = None;
for (arm, is_useful) in report.arm_usefulness.iter() {
match is_useful {
Usefulness::Redundant => {
report_unreachable_pattern(arm.pat.data().unwrap().span, arm.arm_data, catchall)
}
Usefulness::Useful(redundant_subpats) if redundant_subpats.is_empty() => {}
// The arm is reachable, but contains redundant subpatterns (from or-patterns).
Usefulness::Useful(redundant_subpats) => {
let mut redundant_subpats = redundant_subpats.clone();
// Emit lints in the order in which they occur in the file.
redundant_subpats.sort_unstable_by_key(|pat| pat.data().unwrap().span);
for pat in redundant_subpats {
report_unreachable_pattern(pat.data().unwrap().span, arm.arm_data, None);
}
}
if matches!(is_useful, Usefulness::Redundant) {
report_unreachable_pattern(cx, arm.arm_data, arm.pat.data().unwrap().span, catchall)
}
if !arm.has_guard && catchall.is_none() && pat_is_catchall(arm.pat) {
catchall = Some(arm.pat.data().unwrap().span);
Expand Down
Loading
Loading