Skip to content

Rollup of 5 pull requests #117087

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 15 commits into from
Oct 23, 2023
Merged
Changes from all commits
Commits
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
201 changes: 73 additions & 128 deletions compiler/rustc_attr/src/builtin.rs
Original file line number Diff line number Diff line change
@@ -31,54 +31,13 @@ pub fn is_builtin_attr(attr: &Attribute) -> bool {
attr.is_doc_comment() || attr.ident().is_some_and(|ident| is_builtin_attr_name(ident.name))
}

enum AttrError {
MultipleItem(String),
UnknownMetaItem(String, &'static [&'static str]),
MissingSince,
NonIdentFeature,
MissingFeature,
MultipleStabilityLevels,
UnsupportedLiteral(UnsupportedLiteralReason, /* is_bytestr */ bool),
}

pub(crate) enum UnsupportedLiteralReason {
Generic,
CfgString,
DeprecatedString,
DeprecatedKvPair,
}

fn handle_errors(sess: &ParseSess, span: Span, error: AttrError) {
match error {
AttrError::MultipleItem(item) => {
sess.emit_err(session_diagnostics::MultipleItem { span, item });
}
AttrError::UnknownMetaItem(item, expected) => {
sess.emit_err(session_diagnostics::UnknownMetaItem { span, item, expected });
}
AttrError::MissingSince => {
sess.emit_err(session_diagnostics::MissingSince { span });
}
AttrError::NonIdentFeature => {
sess.emit_err(session_diagnostics::NonIdentFeature { span });
}
AttrError::MissingFeature => {
sess.emit_err(session_diagnostics::MissingFeature { span });
}
AttrError::MultipleStabilityLevels => {
sess.emit_err(session_diagnostics::MultipleStabilityLevels { span });
}
AttrError::UnsupportedLiteral(reason, is_bytestr) => {
sess.emit_err(session_diagnostics::UnsupportedLiteral {
span,
reason,
is_bytestr,
start_point_span: sess.source_map().start_point(span),
});
}
}
}

#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
pub enum InlineAttr {
None,
@@ -241,7 +200,7 @@ pub fn find_stability(
sym::rustc_allowed_through_unstable_modules => allowed_through_unstable_modules = true,
sym::unstable => {
if stab.is_some() {
handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels);
sess.emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span });
break;
}

@@ -251,7 +210,7 @@ pub fn find_stability(
}
sym::stable => {
if stab.is_some() {
handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels);
sess.emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span });
break;
}
if let Some((feature, level)) = parse_stability(sess, attr) {
@@ -295,7 +254,7 @@ pub fn find_const_stability(
sym::rustc_promotable => promotable = true,
sym::rustc_const_unstable => {
if const_stab.is_some() {
handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels);
sess.emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span });
break;
}

@@ -306,7 +265,7 @@ pub fn find_const_stability(
}
sym::rustc_const_stable => {
if const_stab.is_some() {
handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels);
sess.emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span });
break;
}
if let Some((feature, level)) = parse_stability(sess, attr) {
@@ -340,7 +299,7 @@ pub fn find_body_stability(
for attr in attrs {
if attr.has_name(sym::rustc_default_body_unstable) {
if body_stab.is_some() {
handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels);
sess.emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span });
break;
}

@@ -355,11 +314,10 @@ pub fn find_body_stability(

fn insert_or_error(sess: &Session, meta: &MetaItem, item: &mut Option<Symbol>) -> Option<()> {
if item.is_some() {
handle_errors(
&sess.parse_sess,
meta.span,
AttrError::MultipleItem(pprust::path_to_string(&meta.path)),
);
sess.emit_err(session_diagnostics::MultipleItem {
span: meta.span,
item: pprust::path_to_string(&meta.path),
});
None
} else if let Some(v) = meta.value_str() {
*item = Some(v);
@@ -380,26 +338,24 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit
let mut since = None;
for meta in metas {
let Some(mi) = meta.meta_item() else {
handle_errors(
&sess.parse_sess,
meta.span(),
AttrError::UnsupportedLiteral(UnsupportedLiteralReason::Generic, false),
);
sess.emit_err(session_diagnostics::UnsupportedLiteral {
span: meta.span(),
reason: UnsupportedLiteralReason::Generic,
is_bytestr: false,
start_point_span: sess.source_map().start_point(meta.span()),
});
return None;
};

match mi.name_or_empty() {
sym::feature => insert_or_error(sess, mi, &mut feature)?,
sym::since => insert_or_error(sess, mi, &mut since)?,
_ => {
handle_errors(
&sess.parse_sess,
meta.span(),
AttrError::UnknownMetaItem(
pprust::path_to_string(&mi.path),
&["feature", "since"],
),
);
sess.emit_err(session_diagnostics::UnknownMetaItem {
span: meta.span(),
item: pprust::path_to_string(&mi.path),
expected: &["feature", "since"],
});
return None;
}
}
@@ -417,11 +373,11 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit
Some((feature, level))
}
(None, _) => {
handle_errors(&sess.parse_sess, attr.span, AttrError::MissingFeature);
sess.emit_err(session_diagnostics::MissingFeature { span: attr.span });
None
}
_ => {
handle_errors(&sess.parse_sess, attr.span, AttrError::MissingSince);
sess.emit_err(session_diagnostics::MissingSince { span: attr.span });
None
}
}
@@ -441,11 +397,12 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil
let mut implied_by = None;
for meta in metas {
let Some(mi) = meta.meta_item() else {
handle_errors(
&sess.parse_sess,
meta.span(),
AttrError::UnsupportedLiteral(UnsupportedLiteralReason::Generic, false),
);
sess.emit_err(session_diagnostics::UnsupportedLiteral {
span: meta.span(),
reason: UnsupportedLiteralReason::Generic,
is_bytestr: false,
start_point_span: sess.source_map().start_point(meta.span()),
});
return None;
};

@@ -484,14 +441,11 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil
}
sym::implied_by => insert_or_error(sess, mi, &mut implied_by)?,
_ => {
handle_errors(
&sess.parse_sess,
meta.span(),
AttrError::UnknownMetaItem(
pprust::path_to_string(&mi.path),
&["feature", "reason", "issue", "soft", "implied_by"],
),
);
sess.emit_err(session_diagnostics::UnknownMetaItem {
span: meta.span(),
item: pprust::path_to_string(&mi.path),
expected: &["feature", "reason", "issue", "soft", "implied_by"],
});
return None;
}
}
@@ -500,7 +454,7 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil
match (feature, reason, issue) {
(Some(feature), reason, Some(_)) => {
if !rustc_lexer::is_ident(feature.as_str()) {
handle_errors(&sess.parse_sess, attr.span, AttrError::NonIdentFeature);
sess.emit_err(session_diagnostics::NonIdentFeature { span: attr.span });
return None;
}
let level = StabilityLevel::Unstable {
@@ -512,7 +466,7 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil
Some((feature, level))
}
(None, _, _) => {
handle_errors(&sess.parse_sess, attr.span, AttrError::MissingFeature);
sess.emit_err(session_diagnostics::MissingFeature { span: attr.span });
return None;
}
_ => {
@@ -659,11 +613,12 @@ pub fn eval_condition(
ast::MetaItemKind::List(mis) => {
for mi in mis.iter() {
if !mi.is_meta_item() {
handle_errors(
sess,
mi.span(),
AttrError::UnsupportedLiteral(UnsupportedLiteralReason::Generic, false),
);
sess.emit_err(session_diagnostics::UnsupportedLiteral {
span: mi.span(),
reason: UnsupportedLiteralReason::Generic,
is_bytestr: false,
start_point_span: sess.source_map().start_point(mi.span()),
});
return false;
}
}
@@ -731,14 +686,12 @@ pub fn eval_condition(
true
}
MetaItemKind::NameValue(lit) if !lit.kind.is_str() => {
handle_errors(
sess,
lit.span,
AttrError::UnsupportedLiteral(
UnsupportedLiteralReason::CfgString,
lit.kind.is_bytestr(),
),
);
sess.emit_err(session_diagnostics::UnsupportedLiteral {
span: lit.span,
reason: UnsupportedLiteralReason::CfgString,
is_bytestr: lit.kind.is_bytestr(),
start_point_span: sess.source_map().start_point(lit.span),
});
true
}
ast::MetaItemKind::Word | ast::MetaItemKind::NameValue(..) => {
@@ -795,26 +748,23 @@ pub fn find_deprecation(
MetaItemKind::List(list) => {
let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
if item.is_some() {
handle_errors(
&sess.parse_sess,
meta.span,
AttrError::MultipleItem(pprust::path_to_string(&meta.path)),
);
sess.emit_err(session_diagnostics::MultipleItem {
span: meta.span,
item: pprust::path_to_string(&meta.path),
});
return false;
}
if let Some(v) = meta.value_str() {
*item = Some(v);
true
} else {
if let Some(lit) = meta.name_value_literal() {
handle_errors(
&sess.parse_sess,
lit.span,
AttrError::UnsupportedLiteral(
UnsupportedLiteralReason::DeprecatedString,
lit.kind.is_bytestr(),
),
);
sess.emit_err(session_diagnostics::UnsupportedLiteral {
span: lit.span,
reason: UnsupportedLiteralReason::DeprecatedString,
is_bytestr: lit.kind.is_bytestr(),
start_point_span: sess.source_map().start_point(lit.span),
});
} else {
sess.emit_err(session_diagnostics::IncorrectMetaItem {
span: meta.span,
@@ -852,30 +802,25 @@ pub fn find_deprecation(
}
}
_ => {
handle_errors(
&sess.parse_sess,
meta.span(),
AttrError::UnknownMetaItem(
pprust::path_to_string(&mi.path),
if features.deprecated_suggestion {
&["since", "note", "suggestion"]
} else {
&["since", "note"]
},
),
);
sess.emit_err(session_diagnostics::UnknownMetaItem {
span: meta.span(),
item: pprust::path_to_string(&mi.path),
expected: if features.deprecated_suggestion {
&["since", "note", "suggestion"]
} else {
&["since", "note"]
},
});
continue 'outer;
}
},
NestedMetaItem::Lit(lit) => {
handle_errors(
&sess.parse_sess,
lit.span,
AttrError::UnsupportedLiteral(
UnsupportedLiteralReason::DeprecatedKvPair,
false,
),
);
sess.emit_err(session_diagnostics::UnsupportedLiteral {
span: lit.span,
reason: UnsupportedLiteralReason::DeprecatedKvPair,
is_bytestr: false,
start_point_span: sess.source_map().start_point(lit.span),
});
continue 'outer;
}
}
@@ -885,7 +830,7 @@ pub fn find_deprecation(

if is_rustc {
if since.is_none() {
handle_errors(&sess.parse_sess, attr.span, AttrError::MissingSince);
sess.emit_err(session_diagnostics::MissingSince { span: attr.span });
continue;
}

21 changes: 14 additions & 7 deletions compiler/rustc_borrowck/src/dataflow.rs
Original file line number Diff line number Diff line change
@@ -272,21 +272,28 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
loan_issued_at: Location,
) {
let sccs = self.regioncx.constraint_sccs();
let universal_regions = self.regioncx.universal_regions();
let issuing_region_scc = sccs.scc(issuing_region);

// We first handle the cases where the loan doesn't go out of scope, depending on the issuing
// region's successors.
for scc in sccs.depth_first_search(issuing_region_scc) {
// 1. Via member constraints
// 1. Via applied member constraints
//
// The issuing region can flow into the choice regions, and they are either:
// - placeholders or free regions themselves,
// - or also transitively outlive a free region.
//
// That is to say, if there are member constraints here, the loan escapes the function
// and cannot go out of scope. We can early return.
if self.regioncx.scc_has_member_constraints(scc) {
return;
// That is to say, if there are applied member constraints here, the loan escapes the
// function and cannot go out of scope. We could early return here.
//
// For additional insurance via fuzzing and crater, we verify that the constraint's min
// choice indeed escapes the function. In the future, we could e.g. turn this check into
// a debug assert and early return as an optimization.
for constraint in self.regioncx.applied_member_constraints(scc) {
if universal_regions.is_universal_region(constraint.min_choice) {
return;
}
}

// 2. Via regions that are live at all points: placeholders and free regions.
@@ -413,12 +420,12 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
let mut polonius_prec = PoloniusOutOfScopePrecomputer::new(body, regioncx);
for (loan_idx, loan_data) in borrow_set.iter_enumerated() {
let issuing_region = loan_data.region;
let issued_location = loan_data.reserve_location;
let loan_issued_at = loan_data.reserve_location;

polonius_prec.precompute_loans_out_of_scope(
loan_idx,
issuing_region,
issued_location,
loan_issued_at,
);
}

18 changes: 7 additions & 11 deletions compiler/rustc_borrowck/src/region_infer/mod.rs
Original file line number Diff line number Diff line change
@@ -644,11 +644,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
self.scc_universes[scc]
}

/// Once region solving has completed, this function will return
/// the member constraints that were applied to the value of a given
/// region `r`. See `AppliedMemberConstraint`.
pub(crate) fn applied_member_constraints(&self, r: RegionVid) -> &[AppliedMemberConstraint] {
let scc = self.constraint_sccs.scc(r);
/// Once region solving has completed, this function will return the member constraints that
/// were applied to the value of a given SCC `scc`. See `AppliedMemberConstraint`.
pub(crate) fn applied_member_constraints(
&self,
scc: ConstraintSccIndex,
) -> &[AppliedMemberConstraint] {
binary_search_util::binary_search_slice(
&self.member_constraints_applied,
|applied| applied.member_region_scc,
@@ -1945,7 +1946,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// Member constraints can also give rise to `'r: 'x` edges that
// were not part of the graph initially, so watch out for those.
// (But they are extremely rare; this loop is very cold.)
for constraint in self.applied_member_constraints(r) {
for constraint in self.applied_member_constraints(self.constraint_sccs.scc(r)) {
let p_c = &self.member_constraints[constraint.member_constraint_index];
let constraint = OutlivesConstraint {
sup: r,
@@ -2292,11 +2293,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
self.constraint_sccs.as_ref()
}

/// Returns whether the given SCC has any member constraints.
pub(crate) fn scc_has_member_constraints(&self, scc: ConstraintSccIndex) -> bool {
self.member_constraints.indices(scc).next().is_some()
}

/// Returns whether the given SCC is live at all points: whether the representative is a
/// placeholder or a free region.
pub(crate) fn scc_is_live_at_all_points(&self, scc: ConstraintSccIndex) -> bool {
2 changes: 1 addition & 1 deletion compiler/rustc_feature/src/removed.rs
Original file line number Diff line number Diff line change
@@ -99,7 +99,7 @@ declare_features! (
/// Allows generators to be cloned.
(removed, generator_clone, "1.65.0", Some(95360), None, Some("renamed to `coroutine_clone`")),
/// Allows defining generators.
(removed, generators, "1.21.0", Some(43122), None, Some("renamed to `coroutine`")),
(removed, generators, "1.21.0", Some(43122), None, Some("renamed to `coroutines`")),
/// Allows `impl Trait` in bindings (`let`, `const`, `static`).
(removed, impl_trait_in_bindings, "1.55.0", Some(63065), None,
Some("the implementation was not maintainable, the feature may get reintroduced once the current refactorings are done")),
9 changes: 2 additions & 7 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
@@ -3463,9 +3463,10 @@ impl DumpMonoStatsFormat {

/// `-Zpolonius` values, enabling the borrow checker polonius analysis, and which version: legacy,
/// or future prototype.
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
#[derive(Clone, Copy, PartialEq, Hash, Debug, Default)]
pub enum Polonius {
/// The default value: disabled.
#[default]
Off,

/// Legacy version, using datalog and the `polonius-engine` crate. Historical value for `-Zpolonius`.
@@ -3475,12 +3476,6 @@ pub enum Polonius {
Next,
}

impl Default for Polonius {
fn default() -> Self {
Polonius::Off
}
}

impl Polonius {
/// Returns whether the legacy version of polonius is enabled
pub fn is_legacy_enabled(&self) -> bool {
133 changes: 78 additions & 55 deletions src/etc/gdb_lookup.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import gdb
import gdb.printing
import re

from gdb_providers import *
@@ -9,7 +10,7 @@
gdb_version = [int(num) for num in _gdb_version_matched.groups()] if _gdb_version_matched else []

def register_printers(objfile):
objfile.pretty_printers.append(lookup)
objfile.pretty_printers.append(printer)


# BACKCOMPAT: rust 1.35
@@ -38,58 +39,80 @@ def check_enum_discriminant(valobj):
return True


def lookup(valobj):
rust_type = classify_rust_type(valobj.type)

if rust_type == RustType.ENUM:
# use enum provider only for GDB <7.12
if gdb_version[0] < 7 or (gdb_version[0] == 7 and gdb_version[1] < 12):
if check_enum_discriminant(valobj):
return EnumProvider(valobj)

if rust_type == RustType.STD_STRING:
return StdStringProvider(valobj)
if rust_type == RustType.STD_OS_STRING:
return StdOsStringProvider(valobj)
if rust_type == RustType.STD_STR:
return StdStrProvider(valobj)
if rust_type == RustType.STD_SLICE:
return StdSliceProvider(valobj)
if rust_type == RustType.STD_VEC:
return StdVecProvider(valobj)
if rust_type == RustType.STD_VEC_DEQUE:
return StdVecDequeProvider(valobj)
if rust_type == RustType.STD_BTREE_SET:
return StdBTreeSetProvider(valobj)
if rust_type == RustType.STD_BTREE_MAP:
return StdBTreeMapProvider(valobj)
if rust_type == RustType.STD_HASH_MAP:
if is_hashbrown_hashmap(valobj):
return StdHashMapProvider(valobj)
else:
return StdOldHashMapProvider(valobj)
if rust_type == RustType.STD_HASH_SET:
hash_map = valobj[valobj.type.fields()[0]]
if is_hashbrown_hashmap(hash_map):
return StdHashMapProvider(valobj, show_values=False)
else:
return StdOldHashMapProvider(hash_map, show_values=False)

if rust_type == RustType.STD_RC:
return StdRcProvider(valobj)
if rust_type == RustType.STD_ARC:
return StdRcProvider(valobj, is_atomic=True)

if rust_type == RustType.STD_CELL:
return StdCellProvider(valobj)
if rust_type == RustType.STD_REF:
return StdRefProvider(valobj)
if rust_type == RustType.STD_REF_MUT:
return StdRefProvider(valobj)
if rust_type == RustType.STD_REF_CELL:
return StdRefCellProvider(valobj)

if rust_type == RustType.STD_NONZERO_NUMBER:
return StdNonZeroNumberProvider(valobj)

# Helper for enum printing that checks the discriminant. Only used in
# older gdb.
def enum_provider(valobj):
if check_enum_discriminant(valobj):
return EnumProvider(valobj)
return None


# Helper to handle both old and new hash maps.
def hashmap_provider(valobj):
if is_hashbrown_hashmap(valobj):
return StdHashMapProvider(valobj)
else:
return StdOldHashMapProvider(valobj)


# Helper to handle both old and new hash sets.
def hashset_provider(valobj):
hash_map = valobj[valobj.type.fields()[0]]
if is_hashbrown_hashmap(hash_map):
return StdHashMapProvider(valobj, show_values=False)
else:
return StdOldHashMapProvider(hash_map, show_values=False)


class PrintByRustType(gdb.printing.SubPrettyPrinter):
def __init__(self, name, provider):
super(PrintByRustType, self).__init__(name)
self.provider = provider

def __call__(self, val):
if self.enabled:
return self.provider(val)
return None


class RustPrettyPrinter(gdb.printing.PrettyPrinter):
def __init__(self, name):
super(RustPrettyPrinter, self).__init__(name, [])
self.type_map = {}

def add(self, rust_type, provider):
# Just use the rust_type as the name.
printer = PrintByRustType(rust_type, provider)
self.type_map[rust_type] = printer
self.subprinters.append(printer)

def __call__(self, valobj):
rust_type = classify_rust_type(valobj.type)
if rust_type in self.type_map:
return self.type_map[rust_type](valobj)
return None


printer = RustPrettyPrinter("rust")
# use enum provider only for GDB <7.12
if gdb_version[0] < 7 or (gdb_version[0] == 7 and gdb_version[1] < 12):
printer.add(RustType.ENUM, enum_provider)
printer.add(RustType.STD_STRING, StdStringProvider)
printer.add(RustType.STD_OS_STRING, StdOsStringProvider)
printer.add(RustType.STD_STR, StdStrProvider)
printer.add(RustType.STD_SLICE, StdSliceProvider)
printer.add(RustType.STD_VEC, StdVecProvider)
printer.add(RustType.STD_VEC_DEQUE, StdVecDequeProvider)
printer.add(RustType.STD_BTREE_SET, StdBTreeSetProvider)
printer.add(RustType.STD_BTREE_MAP, StdBTreeMapProvider)
printer.add(RustType.STD_HASH_MAP, hashmap_provider)
printer.add(RustType.STD_HASH_SET, hashset_provider)
printer.add(RustType.STD_RC, StdRcProvider)
printer.add(RustType.STD_ARC, lambda valobj: StdRcProvider(valobj, is_atomic=True))

printer.add(RustType.STD_CELL, StdCellProvider)
printer.add(RustType.STD_REF, StdRefProvider)
printer.add(RustType.STD_REF_MUT, StdRefProvider)
printer.add(RustType.STD_REF_CELL, StdRefCellProvider)

printer.add(RustType.STD_NONZERO_NUMBER, StdNonZeroNumberProvider)
2 changes: 1 addition & 1 deletion src/tools/compiletest/src/runtest.rs
Original file line number Diff line number Diff line change
@@ -2470,7 +2470,7 @@ impl<'test> TestCx<'test> {
}
CoverageMap => {
rustc.arg("-Cinstrument-coverage");
// These tests only compile to MIR, so they don't need the
// These tests only compile to LLVM IR, so they don't need the
// profiler runtime to be present.
rustc.arg("-Zno-profiler-runtime");
// Coverage mappings are sensitive to MIR optimizations, and
2 changes: 1 addition & 1 deletion src/tools/tidy/src/ui_tests.rs
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ use std::path::{Path, PathBuf};
const ENTRY_LIMIT: usize = 900;
// FIXME: The following limits should be reduced eventually.
const ISSUES_ENTRY_LIMIT: usize = 1854;
const ROOT_ENTRY_LIMIT: usize = 865;
const ROOT_ENTRY_LIMIT: usize = 866;

const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
"rs", // test source files
23 changes: 23 additions & 0 deletions tests/codegen/instrument-coverage-off.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Test that `-Cinstrument-coverage=off` does not add coverage instrumentation to LLVM IR.

// needs-profiler-support
// revisions: n no off false zero
// [n] compile-flags: -Cinstrument-coverage=n
// [no] compile-flags: -Cinstrument-coverage=no
// [off] compile-flags: -Cinstrument-coverage=off
// [false] compile-flags: -Cinstrument-coverage=false
// [zero] compile-flags: -Cinstrument-coverage=0

// CHECK-NOT: __llvm_profile_filename
// CHECK-NOT: __llvm_coverage_mapping

#![crate_type="lib"]

#[inline(never)]
fn some_function() {

}

pub fn some_other_function() {
some_function();
}
9 changes: 8 additions & 1 deletion tests/codegen/instrument-coverage.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
// Test that `-Cinstrument-coverage` creates expected __llvm_profile_filename symbol in LLVM IR.

// needs-profiler-support
// compile-flags: -Cinstrument-coverage
// revisions: default y yes on true all
// [default] compile-flags: -Cinstrument-coverage
// [y] compile-flags: -Cinstrument-coverage=y
// [yes] compile-flags: -Cinstrument-coverage=yes
// [on] compile-flags: -Cinstrument-coverage=on
// [true] compile-flags: -Cinstrument-coverage=true
// [all] compile-flags: -Cinstrument-coverage=all

// CHECK: @__llvm_profile_filename = {{.*}}"default_%m_%p.profraw\00"{{.*}}
// CHECK: @__llvm_coverage_mapping

#![crate_type="lib"]

2 changes: 2 additions & 0 deletions tests/ui/instrument-coverage/bad-value.bad.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
error: incorrect value `bad-value` for codegen option `instrument-coverage` - `all` (default), `except-unused-generics`, `except-unused-functions`, or `off` was expected

2 changes: 2 additions & 0 deletions tests/ui/instrument-coverage/bad-value.blank.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
error: incorrect value `` for codegen option `instrument-coverage` - `all` (default), `except-unused-generics`, `except-unused-functions`, or `off` was expected

5 changes: 5 additions & 0 deletions tests/ui/instrument-coverage/bad-value.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// revisions: blank bad
// [blank] compile-flags: -Cinstrument-coverage=
// [bad] compile-flags: -Cinstrument-coverage=bad-value

fn main() {}
3 changes: 3 additions & 0 deletions tests/ui/instrument-coverage/except-unused-functions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// compile-flags: -Cinstrument-coverage=except-unused-functions

fn main() {}
2 changes: 2 additions & 0 deletions tests/ui/instrument-coverage/except-unused-functions.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
error: `-C instrument-coverage=except-*` requires `-Z unstable-options`

3 changes: 3 additions & 0 deletions tests/ui/instrument-coverage/except-unused-generics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// compile-flags: -Cinstrument-coverage=except-unused-generics

fn main() {}
2 changes: 2 additions & 0 deletions tests/ui/instrument-coverage/except-unused-generics.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
error: `-C instrument-coverage=except-*` requires `-Z unstable-options`

9 changes: 9 additions & 0 deletions tests/ui/instrument-coverage/off-values.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// check-pass
// revisions: n no off false zero
// [n] compile-flags: -Cinstrument-coverage=n
// [no] compile-flags: -Cinstrument-coverage=no
// [off] compile-flags: -Cinstrument-coverage=off
// [false] compile-flags: -Cinstrument-coverage=false
// [zero] compile-flags: -Cinstrument-coverage=0

fn main() {}
11 changes: 11 additions & 0 deletions tests/ui/instrument-coverage/on-values.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// check-pass
// needs-profiler-support
// revisions: default y yes on true all
// [default] compile-flags: -Cinstrument-coverage
// [y] compile-flags: -Cinstrument-coverage=y
// [yes] compile-flags: -Cinstrument-coverage=yes
// [on] compile-flags: -Cinstrument-coverage=on
// [true] compile-flags: -Cinstrument-coverage=true
// [all] compile-flags: -Cinstrument-coverage=all

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
error[E0046]: not all trait items implemented, missing: `call`
--> $DIR/location-insensitive-scopes-issue-116657.rs:18:1
|
LL | fn call(x: Self) -> Self::Output;
| --------------------------------- `call` from trait
...
LL | impl<T: PlusOne> Callable for T {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `call` in implementation

error: unconstrained opaque type
--> $DIR/location-insensitive-scopes-issue-116657.rs:22:19
|
LL | type Output = impl PlusOne;
| ^^^^^^^^^^^^
|
= note: `Output` must be used in combination with a concrete type within the same impl

error[E0700]: hidden type for `impl PlusOne` captures lifetime that does not appear in bounds
--> $DIR/location-insensitive-scopes-issue-116657.rs:28:5
|
LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne {
| -- ------------ opaque type defined here
| |
| hidden type `<&'a mut i32 as Callable>::Output` captures the lifetime `'a` as defined here
LL | <&mut i32 as Callable>::call(y)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: to declare that `impl PlusOne` captures `'a`, you can add an explicit `'a` lifetime bound
|
LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne + 'a {
| ++++

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0046, E0700.
For more information about an error, try `rustc --explain E0046`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
error[E0046]: not all trait items implemented, missing: `call`
--> $DIR/location-insensitive-scopes-issue-116657.rs:18:1
|
LL | fn call(x: Self) -> Self::Output;
| --------------------------------- `call` from trait
...
LL | impl<T: PlusOne> Callable for T {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `call` in implementation

error: unconstrained opaque type
--> $DIR/location-insensitive-scopes-issue-116657.rs:22:19
|
LL | type Output = impl PlusOne;
| ^^^^^^^^^^^^
|
= note: `Output` must be used in combination with a concrete type within the same impl

error[E0700]: hidden type for `impl PlusOne` captures lifetime that does not appear in bounds
--> $DIR/location-insensitive-scopes-issue-116657.rs:28:5
|
LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne {
| -- ------------ opaque type defined here
| |
| hidden type `<&'a mut i32 as Callable>::Output` captures the lifetime `'a` as defined here
LL | <&mut i32 as Callable>::call(y)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: to declare that `impl PlusOne` captures `'a`, you can add an explicit `'a` lifetime bound
|
LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne + 'a {
| ++++

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0046, E0700.
For more information about an error, try `rustc --explain E0046`.
33 changes: 33 additions & 0 deletions tests/ui/nll/polonius/location-insensitive-scopes-issue-116657.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// This is a non-regression test for issue #116657, where NLL and `-Zpolonius=next` computed
// different loan scopes when a member constraint was not ultimately applied.

// revisions: nll polonius
// [polonius] compile-flags: -Zpolonius=next

#![feature(impl_trait_in_assoc_type)]

trait Callable {
type Output;
fn call(x: Self) -> Self::Output;
}

trait PlusOne {}

impl<'a> PlusOne for &'a mut i32 {}

impl<T: PlusOne> Callable for T {
//[nll]~^ ERROR not all trait items implemented
//[polonius]~^^ ERROR not all trait items implemented

type Output = impl PlusOne;
//[nll]~^ ERROR unconstrained opaque type
//[polonius]~^^ ERROR unconstrained opaque type
}

fn test<'a>(y: &'a mut i32) -> impl PlusOne {
<&mut i32 as Callable>::call(y)
//[nll]~^ ERROR hidden type for `impl PlusOne` captures lifetime
//[polonius]~^^ ERROR hidden type for `impl PlusOne` captures lifetime
}

fn main() {}