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 5 pull requests #121627

Merged
merged 15 commits into from
Feb 26, 2024
Merged
Show file tree
Hide file tree
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
Original file line number Diff line number Diff line change
Expand Up @@ -1331,7 +1331,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
}
}

self.tcx.dcx().span_bug(
self.tcx.dcx().span_delayed_bug(
lifetime_ref.ident.span,
format!("Could not resolve {:?} in scope {:#?}", lifetime_ref, self.scope,),
);
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir_typeck/src/method/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -804,10 +804,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
let trait_ref = principal.with_self_ty(self.tcx, self_ty);
self.elaborate_bounds(iter::once(trait_ref), |this, new_trait_ref, item| {
if new_trait_ref.has_non_region_bound_vars() {
this.dcx().span_bug(
this.dcx().span_delayed_bug(
this.span,
"tried to select method from HRTB with non-lifetime bound vars",
);
return;
}

let new_trait_ref = this.instantiate_bound_regions_with_erased(new_trait_ref);
Expand Down
23 changes: 21 additions & 2 deletions compiler/rustc_lint/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,28 @@ lint_hidden_unicode_codepoints = unicode codepoint changing visible direction of
lint_identifier_non_ascii_char = identifier contains non-ASCII characters

lint_identifier_uncommon_codepoints = identifier contains {$codepoints_len ->
[one] an uncommon Unicode codepoint
*[other] uncommon Unicode codepoints
[one] { $identifier_type ->
[Exclusion] a character from an archaic script
[Technical] a character that is for non-linguistic, specialized usage
[Limited_Use] a character from a script in limited use
[Not_NFKC] a non normalized (NFKC) character
*[other] an uncommon character
}
*[other] { $identifier_type ->
[Exclusion] {$codepoints_len} characters from archaic scripts
[Technical] {$codepoints_len} characters that are for non-linguistic, specialized usage
[Limited_Use] {$codepoints_len} characters from scripts in limited use
[Not_NFKC] {$codepoints_len} non normalized (NFKC) characters
*[other] uncommon characters
}
}: {$codepoints}
.note = {$codepoints_len ->
[one] this character is
*[other] these characters are
} included in the{$identifier_type ->
[Restricted] {""}
*[other] {" "}{$identifier_type}
} Unicode general security profile

lint_ignored_unless_crate_specified = {$level}({$name}) is ignored unless specified at crate level

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#![feature(array_windows)]
#![feature(box_patterns)]
#![feature(control_flow_enum)]
#![feature(extract_if)]
#![feature(generic_nonzero)]
#![feature(if_let_guard)]
#![feature(iter_order_by)]
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_lint/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1129,9 +1129,11 @@ pub struct IdentifierNonAsciiChar;

#[derive(LintDiagnostic)]
#[diag(lint_identifier_uncommon_codepoints)]
#[note]
pub struct IdentifierUncommonCodepoints {
pub codepoints: Vec<char>,
pub codepoints_len: usize,
pub identifier_type: &'static str,
}

#[derive(LintDiagnostic)]
Expand Down
47 changes: 39 additions & 8 deletions compiler/rustc_lint/src/non_ascii_idents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use rustc_ast as ast;
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::unord::UnordMap;
use rustc_span::symbol::Symbol;
use unicode_security::general_security_profile::IdentifierType;

declare_lint! {
/// The `non_ascii_idents` lint detects non-ASCII identifiers.
Expand Down Expand Up @@ -189,17 +190,47 @@ impl EarlyLintPass for NonAsciiIdents {
if check_uncommon_codepoints
&& !symbol_str.chars().all(GeneralSecurityProfile::identifier_allowed)
{
let codepoints: Vec<_> = symbol_str
let mut chars: Vec<_> = symbol_str
.chars()
.filter(|c| !GeneralSecurityProfile::identifier_allowed(*c))
.map(|c| (c, GeneralSecurityProfile::identifier_type(c)))
.collect();
let codepoints_len = codepoints.len();

cx.emit_span_lint(
UNCOMMON_CODEPOINTS,
sp,
IdentifierUncommonCodepoints { codepoints, codepoints_len },
);
for (id_ty, id_ty_descr) in [
(IdentifierType::Exclusion, "Exclusion"),
(IdentifierType::Technical, "Technical"),
(IdentifierType::Limited_Use, "Limited_Use"),
(IdentifierType::Not_NFKC, "Not_NFKC"),
] {
let codepoints: Vec<_> =
chars.extract_if(|(_, ty)| *ty == Some(id_ty)).collect();
if codepoints.is_empty() {
continue;
}
cx.emit_span_lint(
UNCOMMON_CODEPOINTS,
sp,
IdentifierUncommonCodepoints {
codepoints_len: codepoints.len(),
codepoints: codepoints.into_iter().map(|(c, _)| c).collect(),
identifier_type: id_ty_descr,
},
);
}

let remaining = chars
.extract_if(|(c, _)| !GeneralSecurityProfile::identifier_allowed(*c))
.collect::<Vec<_>>();
if !remaining.is_empty() {
cx.emit_span_lint(
UNCOMMON_CODEPOINTS,
sp,
IdentifierUncommonCodepoints {
codepoints_len: remaining.len(),
codepoints: remaining.into_iter().map(|(c, _)| c).collect(),
identifier_type: "Restricted",
},
);
}
}
}

Expand Down
14 changes: 11 additions & 3 deletions src/librustdoc/html/static/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,12 @@ function preLoadCss(cssUrl) {
(function() {
const isHelpPage = window.location.pathname.endsWith("/help.html");

function loadScript(url) {
function loadScript(url, errorCallback) {
const script = document.createElement("script");
script.src = url;
if (errorCallback !== undefined) {
script.onerror = errorCallback;
}
document.head.append(script);
}

Expand Down Expand Up @@ -292,11 +295,16 @@ function preLoadCss(cssUrl) {
return;
}
let searchLoaded = false;
// If you're browsing the nightly docs, the page might need to be refreshed for the
// search to work because the hash of the JS scripts might have changed.
function sendSearchForm() {
document.getElementsByClassName("search-form")[0].submit();
}
function loadSearch() {
if (!searchLoaded) {
searchLoaded = true;
loadScript(getVar("static-root-path") + getVar("search-js"));
loadScript(resourcePath("search-index", ".js"));
loadScript(getVar("static-root-path") + getVar("search-js"), sendSearchForm);
loadScript(resourcePath("search-index", ".js"), sendSearchForm);
}
}

Expand Down
8 changes: 8 additions & 0 deletions src/tools/compiletest/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ pub struct TestProps {
/// Extra flags to pass to `llvm-cov` when producing coverage reports.
/// Only used by the "coverage-run" test mode.
pub llvm_cov_flags: Vec<String>,
/// Extra flags to pass to LLVM's `filecheck` tool, in tests that use it.
pub filecheck_flags: Vec<String>,
}

mod directives {
Expand Down Expand Up @@ -236,6 +238,7 @@ mod directives {
pub const REMAP_SRC_BASE: &'static str = "remap-src-base";
pub const COMPARE_OUTPUT_LINES_BY_SUBSET: &'static str = "compare-output-lines-by-subset";
pub const LLVM_COV_FLAGS: &'static str = "llvm-cov-flags";
pub const FILECHECK_FLAGS: &'static str = "filecheck-flags";
// This isn't a real directive, just one that is probably mistyped often
pub const INCORRECT_COMPILER_FLAGS: &'static str = "compiler-flags";
}
Expand Down Expand Up @@ -286,6 +289,7 @@ impl TestProps {
mir_unit_test: None,
remap_src_base: false,
llvm_cov_flags: vec![],
filecheck_flags: vec![],
}
}

Expand Down Expand Up @@ -542,6 +546,10 @@ impl TestProps {
if let Some(flags) = config.parse_name_value_directive(ln, LLVM_COV_FLAGS) {
self.llvm_cov_flags.extend(split_flags(&flags));
}

if let Some(flags) = config.parse_name_value_directive(ln, FILECHECK_FLAGS) {
self.filecheck_flags.extend(split_flags(&flags));
}
},
);

Expand Down
39 changes: 23 additions & 16 deletions src/tools/compiletest/src/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2909,25 +2909,32 @@ impl<'test> TestCx<'test> {
fn verify_with_filecheck(&self, output: &Path) -> ProcRes {
let mut filecheck = Command::new(self.config.llvm_filecheck.as_ref().unwrap());
filecheck.arg("--input-file").arg(output).arg(&self.testpaths.file);
// It would be more appropriate to make most of the arguments configurable through
// a comment-attribute similar to `compile-flags`. For example, --check-prefixes is a very
// useful flag.
//
// For now, though…
let prefix_for_target =
if self.config.target.contains("msvc") { "MSVC" } else { "NONMSVC" };
let prefixes = if let Some(rev) = self.revision {
format!("CHECK,{},{}", prefix_for_target, rev)
} else {
format!("CHECK,{}", prefix_for_target)
};
if self.config.llvm_version.unwrap_or(0) >= 130000 {
filecheck.args(&["--allow-unused-prefixes", "--check-prefixes", &prefixes]);
} else {
filecheck.args(&["--check-prefixes", &prefixes]);

// FIXME: Consider making some of these prefix flags opt-in per test,
// via `filecheck-flags` or by adding new header directives.

// Because we use custom prefixes, we also have to register the default prefix.
filecheck.arg("--check-prefix=CHECK");

// Some tests use the current revision name as a check prefix.
if let Some(rev) = self.revision {
filecheck.arg("--check-prefix").arg(rev);
}

// Some tests also expect either the MSVC or NONMSVC prefix to be defined.
let msvc_or_not = if self.config.target.contains("msvc") { "MSVC" } else { "NONMSVC" };
filecheck.arg("--check-prefix").arg(msvc_or_not);

// The filecheck tool normally fails if a prefix is defined but not used.
// However, we define several prefixes globally for all tests.
filecheck.arg("--allow-unused-prefixes");

// Provide more context on failures.
filecheck.args(&["--dump-input-context", "100"]);

// Add custom flags supplied by the `filecheck-flags:` test header.
filecheck.args(&self.props.filecheck_flags);

self.compose_and_run(filecheck, "", None, None)
}

Expand Down
120 changes: 120 additions & 0 deletions tests/codegen/instrument-coverage/testprog.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
//@ edition: 2021
//@ needs-profiler-support
//@ compile-flags: -Cinstrument-coverage -Copt-level=0
//@ revisions: LINUX DARWIN WINDOWS

//@ [LINUX] only-linux
//@ [LINUX] filecheck-flags: -DINSTR_PROF_DATA=__llvm_prf_data
//@ [LINUX] filecheck-flags: -DINSTR_PROF_NAME=__llvm_prf_names
//@ [LINUX] filecheck-flags: -DINSTR_PROF_CNTS=__llvm_prf_cnts
//@ [LINUX] filecheck-flags: -DINSTR_PROF_COVMAP=__llvm_covmap
//@ [LINUX] filecheck-flags: -DINSTR_PROF_COVFUN=__llvm_covfun
//@ [LINUX] filecheck-flags: '-DCOMDAT_IF_SUPPORTED=, comdat'

//@ [DARWIN] only-macos
//@ [DARWIN] filecheck-flags: -DINSTR_PROF_DATA=__DATA,__llvm_prf_data,regular,live_support
//@ [DARWIN] filecheck-flags: -DINSTR_PROF_NAME=__DATA,__llvm_prf_names
//@ [DARWIN] filecheck-flags: -DINSTR_PROF_CNTS=__DATA,__llvm_prf_cnts
//@ [DARWIN] filecheck-flags: -DINSTR_PROF_COVMAP=__LLVM_COV,__llvm_covmap
//@ [DARWIN] filecheck-flags: -DINSTR_PROF_COVFUN=__LLVM_COV,__llvm_covfun
//@ [DARWIN] filecheck-flags: -DCOMDAT_IF_SUPPORTED=

//@ [WINDOWS] only-windows
//@ [WINDOWS] filecheck-flags: -DINSTR_PROF_DATA=.lprfd$M
//@ [WINDOWS] filecheck-flags: -DINSTR_PROF_NAME=.lprfn$M
//@ [WINDOWS] filecheck-flags: -DINSTR_PROF_CNTS=.lprfc$M
//@ [WINDOWS] filecheck-flags: -DINSTR_PROF_COVMAP=.lcovmap$M
//@ [WINDOWS] filecheck-flags: -DINSTR_PROF_COVFUN=.lcovfun$M
//@ [WINDOWS] filecheck-flags: '-DCOMDAT_IF_SUPPORTED=, comdat'

// ignore-tidy-linelength

pub fn will_be_called() -> &'static str {
let val = "called";
println!("{}", val);
val
}

pub fn will_not_be_called() -> bool {
println!("should not have been called");
false
}

pub fn print<T>(left: &str, value: T, right: &str)
where
T: std::fmt::Display,
{
println!("{}{}{}", left, value, right);
}

pub fn wrap_with<F, T>(inner: T, should_wrap: bool, wrapper: F)
where
F: FnOnce(&T)
{
if should_wrap {
wrapper(&inner)
}
}

fn main() {
let less = 1;
let more = 100;

if less < more {
wrap_with(will_be_called(), less < more, |inner| print(" ***", inner, "*** "));
wrap_with(will_be_called(), more < less, |inner| print(" ***", inner, "*** "));
} else {
wrap_with(will_not_be_called(), true, |inner| print("wrapped result is: ", inner, ""));
}
}

// Check for metadata, variables, declarations, and function definitions injected
// into LLVM IR when compiling with -Cinstrument-coverage.

// WINDOWS: $__llvm_profile_runtime_user = comdat any

// CHECK: @__llvm_coverage_mapping = private constant
// CHECK-SAME: section "[[INSTR_PROF_COVMAP]]", align 8

// CHECK: @__covrec_{{[A-F0-9]+}}u = linkonce_odr hidden constant
// CHECK-SAME: section "[[INSTR_PROF_COVFUN]]"[[COMDAT_IF_SUPPORTED]], align 8

// WINDOWS: @__llvm_profile_runtime = external{{.*}}global i32

// CHECK: @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called = {{private|internal}} global
// CHECK-SAME: section "[[INSTR_PROF_CNTS]]"{{.*}}, align 8

// CHECK: @__profd__R{{[a-zA-Z0-9_]+}}testprog14will_be_called = {{private|internal}} global
// CHECK-SAME: @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called
// CHECK-SAME: section "[[INSTR_PROF_DATA]]"{{.*}}, align 8

// CHECK: @__profc__R{{[a-zA-Z0-9_]+}}testprog4main = {{private|internal}} global
// CHECK-SAME: section "[[INSTR_PROF_CNTS]]"{{.*}}, align 8

// CHECK: @__profd__R{{[a-zA-Z0-9_]+}}testprog4main = {{private|internal}} global
// CHECK-SAME: @__profc__R{{[a-zA-Z0-9_]+}}testprog4main
// CHECK-SAME: section "[[INSTR_PROF_DATA]]"{{.*}}, align 8

// CHECK: @__llvm_prf_nm = private constant
// CHECK-SAME: section "[[INSTR_PROF_NAME]]", align 1

// CHECK: @llvm.used = appending global
// CHECK-SAME: @__llvm_coverage_mapping
// CHECK-SAME: @__llvm_prf_nm
// CHECK-SAME: section "llvm.metadata"

// CHECK: define internal { {{.*}} } @_R{{[a-zA-Z0-9_]+}}testprog14will_be_called() unnamed_addr #{{[0-9]+}} {
// CHECK-NEXT: start:
// CHECK-NOT: define internal
// CHECK: atomicrmw add ptr
// CHECK-SAME: @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called,

// CHECK: declare void @llvm.instrprof.increment(ptr, i64, i32, i32) #[[LLVM_INSTRPROF_INCREMENT_ATTR:[0-9]+]]

// WINDOWS: define linkonce_odr hidden i32 @__llvm_profile_runtime_user() #[[LLVM_PROFILE_RUNTIME_USER_ATTR:[0-9]+]] comdat {
// WINDOWS-NEXT: %1 = load i32, ptr @__llvm_profile_runtime
// WINDOWS-NEXT: ret i32 %1
// WINDOWS-NEXT: }

// CHECK: attributes #[[LLVM_INSTRPROF_INCREMENT_ATTR]] = { nounwind }
// WINDOWS: attributes #[[LLVM_PROFILE_RUNTIME_USER_ATTR]] = { noinline }
4 changes: 4 additions & 0 deletions tests/codegen/meta-filecheck/check-prefix.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Simple test that uses the default CHECK prefix and should always succeed.

// CHECK: main
fn main() {}
8 changes: 8 additions & 0 deletions tests/codegen/meta-filecheck/filecheck-flags.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Arguments provided via `filecheck-flags` should be passed to `filecheck`.

//@ revisions: good bad
//@ [good] filecheck-flags: --check-prefix=CUSTOM
//@ [bad] should-fail

// CUSTOM: main
fn main() {}
7 changes: 7 additions & 0 deletions tests/codegen/meta-filecheck/msvc-prefix-bad.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// This is exactly like `msvc-prefix-good.rs`, except that it should always fail.

//@ should-fail

// MSVC: text that should not match
// NONMSVC: text that should not match
fn main() {}
Loading
Loading