Skip to content

Commit 127fa22

Browse files
committed
Auto merge of rust-lang#127014 - jhpratt:rollup-45ic8f5, r=jhpratt
Rollup of 6 pull requests Successful merges: - rust-lang#126571 (Less `maybe_whole_expr`, take 2) - rust-lang#126721 (coverage: Make `#[coverage(..)]` apply recursively to nested functions) - rust-lang#126928 (Some `Nonterminal` removal precursors) - rust-lang#126929 (Remove `__rust_force_expr`.) - rust-lang#126980 (set self.is_known_utf8 to false in extend_from_slice) - rust-lang#126983 (Remove `f16` and `f128` ICE paths from smir) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 536235f + 73016dc commit 127fa22

37 files changed

+560
-399
lines changed

compiler/rustc_ast/src/attr/mod.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,8 @@ impl MetaItem {
327327
I: Iterator<Item = &'a TokenTree>,
328328
{
329329
// FIXME: Share code with `parse_path`.
330-
let path = match tokens.next().map(|tt| TokenTree::uninterpolate(tt)).as_deref() {
330+
let tt = tokens.next().map(|tt| TokenTree::uninterpolate(tt));
331+
let path = match tt.as_deref() {
331332
Some(&TokenTree::Token(
332333
Token { kind: ref kind @ (token::Ident(..) | token::PathSep), span },
333334
_,
@@ -368,6 +369,12 @@ impl MetaItem {
368369
token::Nonterminal::NtPath(path) => (**path).clone(),
369370
_ => return None,
370371
},
372+
Some(TokenTree::Token(
373+
Token { kind: token::OpenDelim(_) | token::CloseDelim(_), .. },
374+
_,
375+
)) => {
376+
panic!("Should be `AttrTokenTree::Delimited`, not delim tokens: {:?}", tt);
377+
}
371378
_ => return None,
372379
};
373380
let list_closing_paren_pos = tokens.peek().map(|tt| tt.span().hi());

compiler/rustc_ast/src/tokenstream.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ impl AttrTokenStream {
224224
// Inner attributes are only supported on extern blocks, functions,
225225
// impls, and modules. All of these have their inner attributes
226226
// placed at the beginning of the rightmost outermost braced group:
227-
// e.g. fn foo() { #![my_attr} }
227+
// e.g. fn foo() { #![my_attr] }
228228
//
229229
// Therefore, we can insert them back into the right location
230230
// without needing to do any extra position tracking.

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

-17
Original file line numberDiff line numberDiff line change
@@ -124,22 +124,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
124124
.emit();
125125
}
126126
}
127-
sym::coverage => {
128-
let inner = attr.meta_item_list();
129-
match inner.as_deref() {
130-
Some([item]) if item.has_name(sym::off) => {
131-
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_COVERAGE;
132-
}
133-
Some([item]) if item.has_name(sym::on) => {
134-
// Allow #[coverage(on)] for being explicit, maybe also in future to enable
135-
// coverage on a smaller scope within an excluded larger scope.
136-
}
137-
Some(_) | None => {
138-
tcx.dcx()
139-
.span_delayed_bug(attr.span, "unexpected value of coverage attribute");
140-
}
141-
}
142-
}
143127
sym::rustc_std_internal_symbol => {
144128
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL
145129
}
@@ -584,7 +568,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
584568
}
585569

586570
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
587-
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_COVERAGE;
588571
codegen_fn_attrs.inline = InlineAttr::Never;
589572
}
590573

compiler/rustc_expand/src/config.rs

+6
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,12 @@ impl<'a> StripUnconfigured<'a> {
214214
) => {
215215
panic!("Nonterminal should have been flattened: {:?}", tree);
216216
}
217+
AttrTokenTree::Token(
218+
Token { kind: TokenKind::OpenDelim(_) | TokenKind::CloseDelim(_), .. },
219+
_,
220+
) => {
221+
panic!("Should be `AttrTokenTree::Delimited`, not delim tokens: {:?}", tree);
222+
}
217223
AttrTokenTree::Token(token, spacing) => {
218224
Some(AttrTokenTree::Token(token, spacing)).into_iter()
219225
}

compiler/rustc_middle/src/middle/codegen_fn_attrs.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,7 @@ bitflags::bitflags! {
8787
/// #[cmse_nonsecure_entry]: with a TrustZone-M extension, declare a
8888
/// function as an entry function from Non-Secure code.
8989
const CMSE_NONSECURE_ENTRY = 1 << 13;
90-
/// `#[coverage(off)]`: indicates that the function should be ignored by
91-
/// the MIR `InstrumentCoverage` pass and not added to the coverage map
92-
/// during codegen.
93-
const NO_COVERAGE = 1 << 14;
90+
// (Bit 14 was used for `#[coverage(off)]`, but is now unused.)
9491
/// `#[used(linker)]`:
9592
/// indicates that neither LLVM nor the linker will eliminate this function.
9693
const USED_LINKER = 1 << 15;

compiler/rustc_middle/src/query/mod.rs

+9
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,15 @@ rustc_queries! {
572572
separate_provide_extern
573573
}
574574

575+
/// Checks for the nearest `#[coverage(off)]` or `#[coverage(on)]` on
576+
/// this def and any enclosing defs, up to the crate root.
577+
///
578+
/// Returns `false` if `#[coverage(off)]` was found, or `true` if
579+
/// either `#[coverage(on)]` or no coverage attribute was found.
580+
query coverage_attr_on(key: LocalDefId) -> bool {
581+
desc { |tcx| "checking for `#[coverage(..)]` on `{}`", tcx.def_path_str(key) }
582+
}
583+
575584
/// Summarizes coverage IDs inserted by the `InstrumentCoverage` MIR pass
576585
/// (for compiler option `-Cinstrument-coverage`), after MIR optimizations
577586
/// have had a chance to potentially remove some of them.

compiler/rustc_mir_transform/src/coverage/query.rs

+32-1
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ use rustc_middle::query::TyCtxtAt;
66
use rustc_middle::ty::{self, TyCtxt};
77
use rustc_middle::util::Providers;
88
use rustc_span::def_id::LocalDefId;
9+
use rustc_span::sym;
910

1011
/// Registers query/hook implementations related to coverage.
1112
pub(crate) fn provide(providers: &mut Providers) {
1213
providers.hooks.is_eligible_for_coverage =
1314
|TyCtxtAt { tcx, .. }, def_id| is_eligible_for_coverage(tcx, def_id);
15+
providers.queries.coverage_attr_on = coverage_attr_on;
1416
providers.queries.coverage_ids_info = coverage_ids_info;
1517
}
1618

@@ -38,14 +40,43 @@ fn is_eligible_for_coverage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
3840
return false;
3941
}
4042

41-
if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::NO_COVERAGE) {
43+
if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::NAKED) {
44+
trace!("InstrumentCoverage skipped for {def_id:?} (`#[naked]`)");
45+
return false;
46+
}
47+
48+
if !tcx.coverage_attr_on(def_id) {
4249
trace!("InstrumentCoverage skipped for {def_id:?} (`#[coverage(off)]`)");
4350
return false;
4451
}
4552

4653
true
4754
}
4855

56+
/// Query implementation for `coverage_attr_on`.
57+
fn coverage_attr_on(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
58+
// Check for annotations directly on this def.
59+
if let Some(attr) = tcx.get_attr(def_id, sym::coverage) {
60+
match attr.meta_item_list().as_deref() {
61+
Some([item]) if item.has_name(sym::off) => return false,
62+
Some([item]) if item.has_name(sym::on) => return true,
63+
Some(_) | None => {
64+
// Other possibilities should have been rejected by `rustc_parse::validate_attr`.
65+
tcx.dcx().span_bug(attr.span, "unexpected value of coverage attribute");
66+
}
67+
}
68+
}
69+
70+
match tcx.opt_local_parent(def_id) {
71+
// Check the parent def (and so on recursively) until we find an
72+
// enclosing attribute or reach the crate root.
73+
Some(parent) => tcx.coverage_attr_on(parent),
74+
// We reached the crate root without seeing a coverage attribute, so
75+
// allow coverage instrumentation by default.
76+
None => true,
77+
}
78+
}
79+
4980
/// Query implementation for `coverage_ids_info`.
5081
fn coverage_ids_info<'tcx>(
5182
tcx: TyCtxt<'tcx>,

compiler/rustc_parse/src/parser/expr.rs

+41-32
Original file line numberDiff line numberDiff line change
@@ -39,36 +39,6 @@ use rustc_span::{BytePos, ErrorGuaranteed, Pos, Span};
3939
use thin_vec::{thin_vec, ThinVec};
4040
use tracing::instrument;
4141

42-
/// Possibly accepts an `token::Interpolated` expression (a pre-parsed expression
43-
/// dropped into the token stream, which happens while parsing the result of
44-
/// macro expansion). Placement of these is not as complex as I feared it would
45-
/// be. The important thing is to make sure that lookahead doesn't balk at
46-
/// `token::Interpolated` tokens.
47-
macro_rules! maybe_whole_expr {
48-
($p:expr) => {
49-
if let token::Interpolated(nt) = &$p.token.kind {
50-
match &**nt {
51-
token::NtExpr(e) | token::NtLiteral(e) => {
52-
let e = e.clone();
53-
$p.bump();
54-
return Ok(e);
55-
}
56-
token::NtPath(path) => {
57-
let path = (**path).clone();
58-
$p.bump();
59-
return Ok($p.mk_expr($p.prev_token.span, ExprKind::Path(None, path)));
60-
}
61-
token::NtBlock(block) => {
62-
let block = block.clone();
63-
$p.bump();
64-
return Ok($p.mk_expr($p.prev_token.span, ExprKind::Block(block, None)));
65-
}
66-
_ => {}
67-
};
68-
}
69-
};
70-
}
71-
7242
#[derive(Debug)]
7343
pub(super) enum LhsExpr {
7444
// Already parsed just the outer attributes.
@@ -1421,7 +1391,27 @@ impl<'a> Parser<'a> {
14211391
/// correctly if called from `parse_dot_or_call_expr()`.
14221392
fn parse_expr_bottom(&mut self) -> PResult<'a, P<Expr>> {
14231393
maybe_recover_from_interpolated_ty_qpath!(self, true);
1424-
maybe_whole_expr!(self);
1394+
1395+
if let token::Interpolated(nt) = &self.token.kind {
1396+
match &**nt {
1397+
token::NtExpr(e) | token::NtLiteral(e) => {
1398+
let e = e.clone();
1399+
self.bump();
1400+
return Ok(e);
1401+
}
1402+
token::NtPath(path) => {
1403+
let path = (**path).clone();
1404+
self.bump();
1405+
return Ok(self.mk_expr(self.prev_token.span, ExprKind::Path(None, path)));
1406+
}
1407+
token::NtBlock(block) => {
1408+
let block = block.clone();
1409+
self.bump();
1410+
return Ok(self.mk_expr(self.prev_token.span, ExprKind::Block(block, None)));
1411+
}
1412+
_ => {}
1413+
};
1414+
}
14251415

14261416
// Outer attributes are already parsed and will be
14271417
// added to the return value after the fact.
@@ -2190,7 +2180,26 @@ impl<'a> Parser<'a> {
21902180
/// Matches `'-' lit | lit` (cf. `ast_validation::AstValidator::check_expr_within_pat`).
21912181
/// Keep this in sync with `Token::can_begin_literal_maybe_minus`.
21922182
pub fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> {
2193-
maybe_whole_expr!(self);
2183+
if let token::Interpolated(nt) = &self.token.kind {
2184+
match &**nt {
2185+
// FIXME(nnethercote) The `NtExpr` case should only match if
2186+
// `e` is an `ExprKind::Lit` or an `ExprKind::Unary` containing
2187+
// an `UnOp::Neg` and an `ExprKind::Lit`, like how
2188+
// `can_begin_literal_maybe_minus` works. But this method has
2189+
// been over-accepting for a long time, and to make that change
2190+
// here requires also changing some `parse_literal_maybe_minus`
2191+
// call sites to accept additional expression kinds. E.g.
2192+
// `ExprKind::Path` must be accepted when parsing range
2193+
// patterns. That requires some care. So for now, we continue
2194+
// being less strict here than we should be.
2195+
token::NtExpr(e) | token::NtLiteral(e) => {
2196+
let e = e.clone();
2197+
self.bump();
2198+
return Ok(e);
2199+
}
2200+
_ => {}
2201+
};
2202+
}
21942203

21952204
let lo = self.token.span;
21962205
let minus_present = self.eat(&token::BinOp(token::Minus));

compiler/rustc_passes/src/check_attr.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -369,13 +369,16 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
369369
}
370370
}
371371

372-
/// Checks that `#[coverage(..)]` is applied to a function or closure.
372+
/// Checks that `#[coverage(..)]` is applied to a function/closure/method,
373+
/// or to an impl block or module.
373374
fn check_coverage(&self, attr: &Attribute, span: Span, target: Target) -> bool {
374375
match target {
375-
// #[coverage(..)] on function is fine
376376
Target::Fn
377377
| Target::Closure
378-
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true,
378+
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent)
379+
| Target::Impl
380+
| Target::Mod => true,
381+
379382
_ => {
380383
self.dcx().emit_err(errors::CoverageNotFnOrClosure {
381384
attr_span: attr.span,

compiler/rustc_smir/src/rustc_internal/internal.rs

+2
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,10 @@ impl RustcInternal for FloatTy {
188188

189189
fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
190190
match self {
191+
FloatTy::F16 => rustc_ty::FloatTy::F16,
191192
FloatTy::F32 => rustc_ty::FloatTy::F32,
192193
FloatTy::F64 => rustc_ty::FloatTy::F64,
194+
FloatTy::F128 => rustc_ty::FloatTy::F128,
193195
}
194196
}
195197
}

compiler/rustc_smir/src/rustc_smir/convert/ty.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -304,10 +304,10 @@ impl<'tcx> Stable<'tcx> for ty::FloatTy {
304304

305305
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
306306
match self {
307-
ty::FloatTy::F16 => unimplemented!("f16_f128"),
307+
ty::FloatTy::F16 => FloatTy::F16,
308308
ty::FloatTy::F32 => FloatTy::F32,
309309
ty::FloatTy::F64 => FloatTy::F64,
310-
ty::FloatTy::F128 => unimplemented!("f16_f128"),
310+
ty::FloatTy::F128 => FloatTy::F128,
311311
}
312312
}
313313
}

compiler/stable_mir/src/ty.rs

+2
Original file line numberDiff line numberDiff line change
@@ -608,8 +608,10 @@ impl UintTy {
608608

609609
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
610610
pub enum FloatTy {
611+
F16,
611612
F32,
612613
F64,
614+
F128,
613615
}
614616

615617
#[derive(Clone, Copy, Debug, PartialEq, Eq)]

library/alloc/src/macros.rs

+4-14
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,18 @@
4141
#[allow_internal_unstable(rustc_attrs, liballoc_internals)]
4242
macro_rules! vec {
4343
() => (
44-
$crate::__rust_force_expr!($crate::vec::Vec::new())
44+
$crate::vec::Vec::new()
4545
);
4646
($elem:expr; $n:expr) => (
47-
$crate::__rust_force_expr!($crate::vec::from_elem($elem, $n))
47+
$crate::vec::from_elem($elem, $n)
4848
);
4949
($($x:expr),+ $(,)?) => (
50-
$crate::__rust_force_expr!(<[_]>::into_vec(
50+
<[_]>::into_vec(
5151
// This rustc_box is not required, but it produces a dramatic improvement in compile
5252
// time when constructing arrays with many elements.
5353
#[rustc_box]
5454
$crate::boxed::Box::new([$($x),+])
55-
))
55+
)
5656
);
5757
}
5858

@@ -126,13 +126,3 @@ macro_rules! format {
126126
res
127127
}}
128128
}
129-
130-
/// Force AST node to an expression to improve diagnostics in pattern position.
131-
#[doc(hidden)]
132-
#[macro_export]
133-
#[unstable(feature = "liballoc_internals", issue = "none", reason = "implementation detail")]
134-
macro_rules! __rust_force_expr {
135-
($e:expr) => {
136-
$e
137-
};
138-
}

library/std/src/sys_common/wtf8.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ impl Wtf8Buf {
480480
#[inline]
481481
pub(crate) fn extend_from_slice(&mut self, other: &[u8]) {
482482
self.bytes.extend_from_slice(other);
483-
self.is_known_utf8 = self.is_known_utf8 || self.next_surrogate(0).is_none();
483+
self.is_known_utf8 = false;
484484
}
485485
}
486486

library/std/src/sys_common/wtf8/tests.rs

+24
Original file line numberDiff line numberDiff line change
@@ -725,3 +725,27 @@ fn wtf8_utf8_boundary_between_surrogates() {
725725
string.push(CodePoint::from_u32(0xD800).unwrap());
726726
check_utf8_boundary(&string, 3);
727727
}
728+
729+
#[test]
730+
fn wobbled_wtf8_plus_bytes_isnt_utf8() {
731+
let mut string: Wtf8Buf = unsafe { Wtf8::from_bytes_unchecked(b"\xED\xA0\x80").to_owned() };
732+
assert!(!string.is_known_utf8);
733+
string.extend_from_slice(b"some utf-8");
734+
assert!(!string.is_known_utf8);
735+
}
736+
737+
#[test]
738+
fn wobbled_wtf8_plus_str_isnt_utf8() {
739+
let mut string: Wtf8Buf = unsafe { Wtf8::from_bytes_unchecked(b"\xED\xA0\x80").to_owned() };
740+
assert!(!string.is_known_utf8);
741+
string.push_str("some utf-8");
742+
assert!(!string.is_known_utf8);
743+
}
744+
745+
#[test]
746+
fn unwobbly_wtf8_plus_utf8_is_utf8() {
747+
let mut string: Wtf8Buf = Wtf8Buf::from_str("hello world");
748+
assert!(string.is_known_utf8);
749+
string.push_str("some utf-8");
750+
assert!(string.is_known_utf8);
751+
}

0 commit comments

Comments
 (0)