Merge branch 'master' into abi

This commit is contained in:
Stefan Lankes 2020-04-04 16:19:40 +02:00 committed by GitHub
commit e2780b3919
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
42 changed files with 769 additions and 495 deletions

View File

@ -87,12 +87,6 @@ dependencies = [
"scoped_threadpool",
]
[[package]]
name = "arrayref"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee"
[[package]]
name = "arrayvec"
version = "0.4.7"
@ -187,11 +181,22 @@ dependencies = [
[[package]]
name = "block-buffer"
version = "0.3.3"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab"
checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
dependencies = [
"block-padding",
"byte-tools",
"byteorder",
"generic-array",
]
[[package]]
name = "block-padding"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
dependencies = [
"arrayref",
"byte-tools",
]
@ -240,9 +245,9 @@ version = "0.1.0"
[[package]]
name = "byte-tools"
version = "0.2.0"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
[[package]]
name = "bytecount"
@ -897,9 +902,9 @@ checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
[[package]]
name = "digest"
version = "0.7.6"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
dependencies = [
"generic-array",
]
@ -1226,9 +1231,9 @@ dependencies = [
[[package]]
name = "generic-array"
version = "0.9.0"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
dependencies = [
"typenum",
]
@ -1962,6 +1967,17 @@ version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
[[package]]
name = "md-5"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a18af3dcaf2b0219366cdb4e2af65a6101457b415c3d1a5c71dd9c2b7c77b9c8"
dependencies = [
"block-buffer",
"digest",
"opaque-debug",
]
[[package]]
name = "mdbook"
version = "0.3.5"
@ -2250,6 +2266,12 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6a04cb71e910d0034815600180f62a95bf6e67942d7ab52a166a68c7d7e9cd0"
[[package]]
name = "opaque-debug"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
[[package]]
name = "open"
version = "1.2.1"
@ -2467,9 +2489,9 @@ dependencies = [
[[package]]
name = "pest_meta"
version = "2.1.0"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5a3492a4ed208ffc247adcdcc7ba2a95be3104f58877d0d02f0df39bf3efb5e"
checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d"
dependencies = [
"maplit",
"pest",
@ -4155,11 +4177,13 @@ dependencies = [
"arena",
"cfg-if",
"log",
"md-5",
"rustc_data_structures",
"rustc_index",
"rustc_macros",
"scoped-tls",
"serialize",
"sha-1",
"unicode-width",
]
@ -4535,14 +4559,14 @@ dependencies = [
[[package]]
name = "sha-1"
version = "0.7.0"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9d1f3b5de8a167ab06834a7c883bd197f2191e1dda1a22d9ccfeedbf9aded"
checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
dependencies = [
"block-buffer",
"byte-tools",
"digest",
"fake-simd",
"opaque-debug",
]
[[package]]

View File

@ -0,0 +1,11 @@
# `src-hash-algorithm`
The tracking issue for this feature is: [#70401](https://github.com/rust-lang/rust/issues/70401).
------------------------
The `-Z src-hash-algorithm` compiler flag controls which algorithm is used when hashing each source file. The hash is stored in the debug info and can be used by a debugger to verify the source code matches the executable.
Supported hash algorithms are: `md5`, and `sha1`. Note that not all hash algorithms are supported by all debug info formats.
By default, the compiler chooses the hash algorithm based on the target specification.

View File

@ -41,7 +41,7 @@ use rustc_middle::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
use rustc_middle::{bug, span_bug};
use rustc_session::config::{self, DebugInfo};
use rustc_span::symbol::{Interner, Symbol};
use rustc_span::{self, FileName, Span};
use rustc_span::{self, FileName, SourceFileHash, Span};
use rustc_target::abi::{Abi, Align, DiscriminantKind, HasDataLayout, Integer, LayoutOf};
use rustc_target::abi::{Int, Pointer, F32, F64};
use rustc_target::abi::{Primitive, Size, VariantIdx, Variants};
@ -751,6 +751,14 @@ pub fn type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>, usage_site_span: Sp
metadata
}
fn hex_encode(data: &[u8]) -> String {
let mut hex_string = String::with_capacity(data.len() * 2);
for byte in data.iter() {
write!(&mut hex_string, "{:02x}", byte).unwrap();
}
hex_string
}
pub fn file_metadata(
cx: &CodegenCx<'ll, '_>,
file_name: &FileName,
@ -758,6 +766,8 @@ pub fn file_metadata(
) -> &'ll DIFile {
debug!("file_metadata: file_name: {}, defining_crate: {}", file_name, defining_crate);
let source_file = cx.sess().source_map().get_source_file(file_name);
let hash = source_file.as_ref().map(|f| &f.src_hash);
let file_name = Some(file_name.to_string());
let directory = if defining_crate == LOCAL_CRATE {
Some(cx.sess().working_dir.0.to_string_lossy().to_string())
@ -766,17 +776,18 @@ pub fn file_metadata(
// independent of the compiler's working directory one way or another.
None
};
file_metadata_raw(cx, file_name, directory)
file_metadata_raw(cx, file_name, directory, hash)
}
pub fn unknown_file_metadata(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile {
file_metadata_raw(cx, None, None)
file_metadata_raw(cx, None, None, None)
}
fn file_metadata_raw(
cx: &CodegenCx<'ll, '_>,
file_name: Option<String>,
directory: Option<String>,
hash: Option<&SourceFileHash>,
) -> &'ll DIFile {
let key = (file_name, directory);
@ -789,6 +800,17 @@ fn file_metadata_raw(
let file_name = file_name.as_deref().unwrap_or("<unknown>");
let directory = directory.as_deref().unwrap_or("");
let (hash_kind, hash_value) = match hash {
Some(hash) => {
let kind = match hash.kind {
rustc_span::SourceFileHashAlgorithm::Md5 => llvm::ChecksumKind::MD5,
rustc_span::SourceFileHashAlgorithm::Sha1 => llvm::ChecksumKind::SHA1,
};
(kind, hex_encode(hash.hash_bytes()))
}
None => (llvm::ChecksumKind::None, String::new()),
};
let file_metadata = unsafe {
llvm::LLVMRustDIBuilderCreateFile(
DIB(cx),
@ -796,6 +818,9 @@ fn file_metadata_raw(
file_name.len(),
directory.as_ptr().cast(),
directory.len(),
hash_kind,
hash_value.as_ptr().cast(),
hash_value.len(),
)
};
@ -920,6 +945,9 @@ pub fn compile_unit_metadata(
name_in_debuginfo.len(),
work_dir.as_ptr().cast(),
work_dir.len(),
llvm::ChecksumKind::None,
ptr::null(),
0,
);
let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit(

View File

@ -546,6 +546,15 @@ pub enum ThreadLocalMode {
LocalExec,
}
/// LLVMRustChecksumKind
#[derive(Copy, Clone)]
#[repr(C)]
pub enum ChecksumKind {
None,
MD5,
SHA1,
}
extern "C" {
type Opaque;
}
@ -1640,6 +1649,9 @@ extern "C" {
FilenameLen: size_t,
Directory: *const c_char,
DirectoryLen: size_t,
CSKind: ChecksumKind,
Checksum: *const c_char,
ChecksumLen: size_t,
) -> &'a DIFile;
pub fn LLVMRustDIBuilderCreateSubroutineType(

View File

@ -22,7 +22,7 @@ use rustc_session::parse::CrateConfig;
use rustc_session::CrateDisambiguator;
use rustc_session::{config, early_error, filesearch, output, DiagnosticOutput, Session};
use rustc_span::edition::Edition;
use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMap};
use rustc_span::source_map::{FileLoader, SourceMap};
use rustc_span::symbol::{sym, Symbol};
use smallvec::SmallVec;
use std::env;
@ -62,15 +62,13 @@ pub fn create_session(
lint_caps: FxHashMap<lint::LintId, lint::Level>,
descriptions: Registry,
) -> (Lrc<Session>, Lrc<Box<dyn CodegenBackend>>, Lrc<SourceMap>) {
let loader = file_loader.unwrap_or(box RealFileLoader);
let source_map = Lrc::new(SourceMap::with_file_loader(loader, sopts.file_path_mapping()));
let mut sess = session::build_session_with_source_map(
let (mut sess, source_map) = session::build_session_with_source_map(
sopts,
input_path,
descriptions,
source_map.clone(),
diagnostic_output,
lint_caps,
file_loader,
);
let codegen_backend = get_codegen_backend(&sess);

View File

@ -61,7 +61,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
cnum,
// Do not hash the source as it is not encoded
src: _,
src_hash,
ref src_hash,
external_src: _,
start_pos,
end_pos: _,

View File

@ -1077,48 +1077,42 @@ impl<'tcx> Generics {
false
}
pub fn param_at(&'tcx self, param_index: usize, tcx: TyCtxt<'tcx>) -> &'tcx GenericParamDef {
if let Some(index) = param_index.checked_sub(self.parent_count) {
&self.params[index]
} else {
tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?"))
.param_at(param_index, tcx)
}
}
pub fn region_param(
&'tcx self,
param: &EarlyBoundRegion,
tcx: TyCtxt<'tcx>,
) -> &'tcx GenericParamDef {
if let Some(index) = param.index.checked_sub(self.parent_count as u32) {
let param = &self.params[index as usize];
match param.kind {
GenericParamDefKind::Lifetime => param,
_ => bug!("expected lifetime parameter, but found another generic parameter"),
}
} else {
tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?"))
.region_param(param, tcx)
let param = self.param_at(param.index as usize, tcx);
match param.kind {
GenericParamDefKind::Lifetime => param,
_ => bug!("expected lifetime parameter, but found another generic parameter"),
}
}
/// Returns the `GenericParamDef` associated with this `ParamTy`.
pub fn type_param(&'tcx self, param: &ParamTy, tcx: TyCtxt<'tcx>) -> &'tcx GenericParamDef {
if let Some(index) = param.index.checked_sub(self.parent_count as u32) {
let param = &self.params[index as usize];
match param.kind {
GenericParamDefKind::Type { .. } => param,
_ => bug!("expected type parameter, but found another generic parameter"),
}
} else {
tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?"))
.type_param(param, tcx)
let param = self.param_at(param.index as usize, tcx);
match param.kind {
GenericParamDefKind::Type { .. } => param,
_ => bug!("expected type parameter, but found another generic parameter"),
}
}
/// Returns the `ConstParameterDef` associated with this `ParamConst`.
pub fn const_param(&'tcx self, param: &ParamConst, tcx: TyCtxt<'tcx>) -> &GenericParamDef {
if let Some(index) = param.index.checked_sub(self.parent_count as u32) {
let param = &self.params[index as usize];
match param.kind {
GenericParamDefKind::Const => param,
_ => bug!("expected const parameter, but found another generic parameter"),
}
} else {
tcx.generics_of(self.parent.expect("parent_count>0 but no parent?"))
.const_param(param, tcx)
let param = self.param_at(param.index as usize, tcx);
match param.kind {
GenericParamDefKind::Const => param,
_ => bug!("expected const parameter, but found another generic parameter"),
}
}
}

View File

@ -18,9 +18,10 @@ use rustc_feature::UnstableFeatures;
use rustc_span::edition::{Edition, DEFAULT_EDITION, EDITION_NAME_LIST};
use rustc_span::source_map::{FileName, FilePathMapping};
use rustc_span::symbol::{sym, Symbol};
use rustc_span::SourceFileHashAlgorithm;
use rustc_errors::emitter::HumanReadableErrorType;
use rustc_errors::{ColorConfig, FatalError, Handler, HandlerFlags};
use rustc_errors::{ColorConfig, HandlerFlags};
use std::collections::btree_map::{
Iter as BTreeMapIter, Keys as BTreeMapKeysIter, Values as BTreeMapValuesIter,
@ -748,25 +749,30 @@ pub fn build_configuration(sess: &Session, mut user_cfg: CrateConfig) -> CrateCo
user_cfg
}
pub fn build_target_config(opts: &Options, sp: &Handler) -> Config {
pub fn build_target_config(opts: &Options, error_format: ErrorOutputType) -> Config {
let target = Target::search(&opts.target_triple).unwrap_or_else(|e| {
sp.struct_fatal(&format!("Error loading target specification: {}", e))
.help("Use `--print target-list` for a list of built-in targets")
.emit();
FatalError.raise();
early_error(
error_format,
&format!(
"Error loading target specification: {}. \
Use `--print target-list` for a list of built-in targets",
e
),
)
});
let ptr_width = match &target.target_pointer_width[..] {
"16" => 16,
"32" => 32,
"64" => 64,
w => sp
.fatal(&format!(
w => early_error(
error_format,
&format!(
"target specification was invalid: \
unrecognized target-pointer-width {}",
w
))
.raise(),
),
),
};
Config { target, ptr_width }
@ -1971,7 +1977,8 @@ impl PpMode {
crate mod dep_tracking {
use super::{
CFGuard, CrateType, DebugInfo, ErrorOutputType, LinkerPluginLto, LtoCli, OptLevel,
OutputTypes, Passes, Sanitizer, SwitchWithOptPath, SymbolManglingVersion,
OutputTypes, Passes, Sanitizer, SourceFileHashAlgorithm, SwitchWithOptPath,
SymbolManglingVersion,
};
use crate::lint;
use crate::utils::NativeLibraryKind;
@ -2049,6 +2056,7 @@ crate mod dep_tracking {
impl_dep_tracking_hash_via_hash!(LinkerPluginLto);
impl_dep_tracking_hash_via_hash!(SwitchWithOptPath);
impl_dep_tracking_hash_via_hash!(SymbolManglingVersion);
impl_dep_tracking_hash_via_hash!(Option<SourceFileHashAlgorithm>);
impl_dep_tracking_hash_for_sortable_vec_of!(String);
impl_dep_tracking_hash_for_sortable_vec_of!(PathBuf);

View File

@ -10,6 +10,7 @@ use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, RelroLevel
use rustc_feature::UnstableFeatures;
use rustc_span::edition::Edition;
use rustc_span::SourceFileHashAlgorithm;
use std::collections::BTreeMap;
@ -283,12 +284,14 @@ macro_rules! options {
Some("one of: `disabled`, `trampolines`, or `aliases`");
pub const parse_symbol_mangling_version: Option<&str> =
Some("either `legacy` or `v0` (RFC 2603)");
pub const parse_src_file_hash: Option<&str> =
Some("either `md5`, or `sha1`");
}
#[allow(dead_code)]
mod $mod_set {
use super::{$struct_name, Passes, Sanitizer, LtoCli, LinkerPluginLto, SwitchWithOptPath,
SymbolManglingVersion, CFGuard};
SymbolManglingVersion, CFGuard, SourceFileHashAlgorithm};
use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, RelroLevel};
use std::path::PathBuf;
use std::str::FromStr;
@ -622,6 +625,14 @@ macro_rules! options {
};
true
}
fn parse_src_file_hash(slot: &mut Option<SourceFileHashAlgorithm>, v: Option<&str>) -> bool {
match v.and_then(|s| SourceFileHashAlgorithm::from_str(s).ok()) {
Some(hash_kind) => *slot = Some(hash_kind),
_ => return false,
}
true
}
}
) }
@ -961,4 +972,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
"use new LLVM pass manager"),
link_native_libraries: Option<bool> = (None, parse_opt_bool, [UNTRACKED],
"Link native libraries in the linker invocation."),
src_hash_algorithm: Option<SourceFileHashAlgorithm> = (None, parse_src_file_hash, [TRACKED],
"hash algorithm of source files in debug info (`md5`, or `sha1`)"),
}

View File

@ -20,7 +20,8 @@ use rustc_errors::emitter::{Emitter, EmitterWriter, HumanReadableErrorType};
use rustc_errors::json::JsonEmitter;
use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId, ErrorReported};
use rustc_span::edition::Edition;
use rustc_span::source_map::{self, MultiSpan, Span};
use rustc_span::source_map::{self, FileLoader, MultiSpan, RealFileLoader, SourceMap, Span};
use rustc_span::SourceFileHashAlgorithm;
use rustc_target::spec::{PanicStrategy, RelroLevel, Target, TargetTriple};
use std::cell::{self, RefCell};
@ -870,16 +871,15 @@ pub fn build_session(
local_crate_source_file: Option<PathBuf>,
registry: rustc_errors::registry::Registry,
) -> Session {
let file_path_mapping = sopts.file_path_mapping();
build_session_with_source_map(
sopts,
local_crate_source_file,
registry,
Lrc::new(source_map::SourceMap::new(file_path_mapping)),
DiagnosticOutput::Default,
Default::default(),
None,
)
.0
}
fn default_emitter(
@ -956,10 +956,10 @@ pub fn build_session_with_source_map(
sopts: config::Options,
local_crate_source_file: Option<PathBuf>,
registry: rustc_errors::registry::Registry,
source_map: Lrc<source_map::SourceMap>,
diagnostics_output: DiagnosticOutput,
lint_caps: FxHashMap<lint::LintId, lint::Level>,
) -> Session {
driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
) -> (Session, Lrc<SourceMap>) {
// FIXME: This is not general enough to make the warning lint completely override
// normal diagnostic warnings, since the warning lint can also be denied and changed
// later via the source code.
@ -977,23 +977,33 @@ pub fn build_session_with_source_map(
DiagnosticOutput::Default => None,
DiagnosticOutput::Raw(write) => Some(write),
};
let target_cfg = config::build_target_config(&sopts, sopts.error_format);
let host_triple = TargetTriple::from_triple(config::host_triple());
let host = Target::search(&host_triple).unwrap_or_else(|e| {
early_error(sopts.error_format, &format!("Error loading host specification: {}", e))
});
let loader = file_loader.unwrap_or(Box::new(RealFileLoader));
let hash_kind = sopts.debugging_opts.src_hash_algorithm.unwrap_or_else(|| {
if target_cfg.target.options.is_like_msvc {
SourceFileHashAlgorithm::Sha1
} else {
SourceFileHashAlgorithm::Md5
}
});
let source_map = Lrc::new(SourceMap::with_file_loader_and_hash_kind(
loader,
sopts.file_path_mapping(),
hash_kind,
));
let emitter = default_emitter(&sopts, registry, &source_map, write_dest);
let diagnostic_handler = rustc_errors::Handler::with_emitter_and_flags(
let span_diagnostic = rustc_errors::Handler::with_emitter_and_flags(
emitter,
sopts.debugging_opts.diagnostic_handler_flags(can_emit_warnings),
);
build_session_(sopts, local_crate_source_file, diagnostic_handler, source_map, lint_caps)
}
fn build_session_(
sopts: config::Options,
local_crate_source_file: Option<PathBuf>,
span_diagnostic: rustc_errors::Handler,
source_map: Lrc<source_map::SourceMap>,
driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
) -> Session {
let self_profiler = if let SwitchWithOptPath::Enabled(ref d) = sopts.debugging_opts.self_profile
{
let directory =
@ -1015,13 +1025,7 @@ fn build_session_(
None
};
let host_triple = TargetTriple::from_triple(config::host_triple());
let host = Target::search(&host_triple).unwrap_or_else(|e| {
span_diagnostic.fatal(&format!("Error loading host specification: {}", e)).raise()
});
let target_cfg = config::build_target_config(&sopts, &span_diagnostic);
let parse_sess = ParseSess::with_span_handler(span_diagnostic, source_map);
let parse_sess = ParseSess::with_span_handler(span_diagnostic, source_map.clone());
let sysroot = match &sopts.maybe_sysroot {
Some(sysroot) => sysroot.clone(),
None => filesearch::get_or_default_sysroot(),
@ -1135,7 +1139,7 @@ fn build_session_(
validate_commandline_args_with_session_available(&sess);
sess
(sess, source_map)
}
// If it is useful to have a Session available already for validating a

View File

@ -19,3 +19,5 @@ scoped-tls = "1.0"
unicode-width = "0.1.4"
cfg-if = "0.1.2"
log = "0.4"
sha-1 = "0.8"
md-5 = "0.8"

View File

@ -47,9 +47,14 @@ use std::borrow::Cow;
use std::cell::RefCell;
use std::cmp::{self, Ordering};
use std::fmt;
use std::hash::{Hash, Hasher};
use std::hash::Hash;
use std::ops::{Add, Sub};
use std::path::PathBuf;
use std::str::FromStr;
use md5::Md5;
use sha1::Digest;
use sha1::Sha1;
#[cfg(test)]
mod tests;
@ -874,6 +879,70 @@ impl ExternalSource {
#[derive(Debug)]
pub struct OffsetOverflowError;
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub enum SourceFileHashAlgorithm {
Md5,
Sha1,
}
impl FromStr for SourceFileHashAlgorithm {
type Err = ();
fn from_str(s: &str) -> Result<SourceFileHashAlgorithm, ()> {
match s {
"md5" => Ok(SourceFileHashAlgorithm::Md5),
"sha1" => Ok(SourceFileHashAlgorithm::Sha1),
_ => Err(()),
}
}
}
rustc_data_structures::impl_stable_hash_via_hash!(SourceFileHashAlgorithm);
/// The hash of the on-disk source file used for debug info.
#[derive(Copy, Clone, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable)]
#[derive(HashStable_Generic)]
pub struct SourceFileHash {
pub kind: SourceFileHashAlgorithm,
value: [u8; 20],
}
impl SourceFileHash {
pub fn new(kind: SourceFileHashAlgorithm, src: &str) -> SourceFileHash {
let mut hash = SourceFileHash { kind, value: Default::default() };
let len = hash.hash_len();
let value = &mut hash.value[..len];
let data = src.as_bytes();
match kind {
SourceFileHashAlgorithm::Md5 => {
value.copy_from_slice(&Md5::digest(data));
}
SourceFileHashAlgorithm::Sha1 => {
value.copy_from_slice(&Sha1::digest(data));
}
}
hash
}
/// Check if the stored hash matches the hash of the string.
pub fn matches(&self, src: &str) -> bool {
Self::new(self.kind, src) == *self
}
/// The bytes of the hash.
pub fn hash_bytes(&self) -> &[u8] {
let len = self.hash_len();
&self.value[..len]
}
fn hash_len(&self) -> usize {
match self.kind {
SourceFileHashAlgorithm::Md5 => 16,
SourceFileHashAlgorithm::Sha1 => 20,
}
}
}
/// A single source in the `SourceMap`.
#[derive(Clone)]
pub struct SourceFile {
@ -889,7 +958,7 @@ pub struct SourceFile {
/// The complete source code.
pub src: Option<Lrc<String>>,
/// The source code's hash.
pub src_hash: u128,
pub src_hash: SourceFileHash,
/// The external source code (used for external crates, which will have a `None`
/// value as `self.src`.
pub external_src: Lock<ExternalSource>,
@ -987,7 +1056,8 @@ impl Decodable for SourceFile {
let name: FileName = d.read_struct_field("name", 0, |d| Decodable::decode(d))?;
let name_was_remapped: bool =
d.read_struct_field("name_was_remapped", 1, |d| Decodable::decode(d))?;
let src_hash: u128 = d.read_struct_field("src_hash", 2, |d| Decodable::decode(d))?;
let src_hash: SourceFileHash =
d.read_struct_field("src_hash", 2, |d| Decodable::decode(d))?;
let start_pos: BytePos =
d.read_struct_field("start_pos", 3, |d| Decodable::decode(d))?;
let end_pos: BytePos = d.read_struct_field("end_pos", 4, |d| Decodable::decode(d))?;
@ -1062,14 +1132,12 @@ impl SourceFile {
unmapped_path: FileName,
mut src: String,
start_pos: BytePos,
hash_kind: SourceFileHashAlgorithm,
) -> Self {
// Compute the file hash before any normalization.
let src_hash = SourceFileHash::new(hash_kind, &src);
let normalized_pos = normalize_src(&mut src, start_pos);
let src_hash = {
let mut hasher: StableHasher = StableHasher::new();
hasher.write(src.as_bytes());
hasher.finish::<u128>()
};
let name_hash = {
let mut hasher: StableHasher = StableHasher::new();
name.hash(&mut hasher);
@ -1125,10 +1193,7 @@ impl SourceFile {
} = &mut *external_src
{
if let Some(src) = src {
let mut hasher: StableHasher = StableHasher::new();
hasher.write(src.as_bytes());
if hasher.finish::<u128>() == self.src_hash {
if self.src_hash.matches(&src) {
*src_kind = ExternalSourceKind::Present(Lrc::new(src));
return true;
}

View File

@ -141,27 +141,31 @@ pub struct SourceMap {
// This is used to apply the file path remapping as specified via
// `--remap-path-prefix` to all `SourceFile`s allocated within this `SourceMap`.
path_mapping: FilePathMapping,
/// The algorithm used for hashing the contents of each source file.
hash_kind: SourceFileHashAlgorithm,
}
impl SourceMap {
pub fn new(path_mapping: FilePathMapping) -> SourceMap {
SourceMap {
used_address_space: AtomicU32::new(0),
files: Default::default(),
file_loader: Box::new(RealFileLoader),
Self::with_file_loader_and_hash_kind(
Box::new(RealFileLoader),
path_mapping,
}
SourceFileHashAlgorithm::Md5,
)
}
pub fn with_file_loader(
pub fn with_file_loader_and_hash_kind(
file_loader: Box<dyn FileLoader + Sync + Send>,
path_mapping: FilePathMapping,
hash_kind: SourceFileHashAlgorithm,
) -> SourceMap {
SourceMap {
used_address_space: AtomicU32::new(0),
files: Default::default(),
file_loader,
path_mapping,
hash_kind,
}
}
@ -275,6 +279,7 @@ impl SourceMap {
unmapped_path,
src,
Pos::from_usize(start_pos),
self.hash_kind,
));
let mut files = self.files.borrow_mut();
@ -296,7 +301,7 @@ impl SourceMap {
&self,
filename: FileName,
name_was_remapped: bool,
src_hash: u128,
src_hash: SourceFileHash,
name_hash: u128,
source_len: usize,
cnum: CrateNum,

View File

@ -9,7 +9,7 @@ use rustc_hir::def_id::DefId;
use rustc_hir::itemlikevisit::ParItemLikeVisitor;
use rustc_hir::lang_items;
use rustc_hir::ItemKind;
use rustc_middle::ty::subst::{InternalSubsts, Subst};
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst};
use rustc_middle::ty::trait_def::TraitSpecializationKind;
use rustc_middle::ty::{
self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
@ -864,87 +864,77 @@ fn check_opaque_types<'fcx, 'tcx>(
trace!("check_opaque_types: opaque_ty, {:?}, {:?}", def_id, substs);
let generics = tcx.generics_of(def_id);
// Only check named `impl Trait` types defined in this crate.
// FIXME(eddyb) is `generics.parent.is_none()` correct? It seems
// potentially risky wrt associated types in `impl`s.
if generics.parent.is_none() && def_id.is_local() {
let opaque_hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
if may_define_opaque_type(tcx, fn_def_id, opaque_hir_id) {
trace!("check_opaque_types: may define, generics={:#?}", generics);
let mut seen: FxHashMap<_, Vec<_>> = FxHashMap::default();
for (subst, param) in substs.iter().zip(&generics.params) {
match subst.unpack() {
ty::subst::GenericArgKind::Type(ty) => match ty.kind {
ty::Param(..) => {}
// Prevent `fn foo() -> Foo<u32>` from being defining.
_ => {
tcx.sess
.struct_span_err(
span,
"non-defining opaque type use \
in defining scope",
)
.span_note(
tcx.def_span(param.def_id),
&format!(
"used non-generic type {} for \
generic parameter",
ty,
),
)
.emit();
}
},
let mut seen_params: FxHashMap<_, Vec<_>> = FxHashMap::default();
for (i, &arg) in substs.iter().enumerate() {
let arg_is_param = match arg.unpack() {
GenericArgKind::Type(ty) => matches!(ty.kind, ty::Param(_)),
ty::subst::GenericArgKind::Lifetime(region) => {
let param_span = tcx.def_span(param.def_id);
GenericArgKind::Lifetime(region) => {
if let ty::ReStatic = region {
tcx.sess
.struct_span_err(
span,
"non-defining opaque type use \
in defining scope",
"non-defining opaque type use in defining scope",
)
.span_label(
param_span,
tcx.def_span(generics.param_at(i, tcx).def_id),
"cannot use static lifetime; use a bound lifetime \
instead or remove the lifetime parameter from the \
opaque type",
)
.emit();
} else {
seen.entry(region).or_default().push(param_span);
continue;
}
true
}
ty::subst::GenericArgKind::Const(ct) => match ct.val {
ty::ConstKind::Param(_) => {}
_ => {
tcx.sess
.struct_span_err(
span,
"non-defining opaque type use \
in defining scope",
)
.span_note(
tcx.def_span(param.def_id),
&format!(
"used non-generic const {} for \
generic parameter",
ty,
),
)
.emit();
}
},
} // match subst
} // for (subst, param)
for (_, spans) in seen {
if spans.len() > 1 {
GenericArgKind::Const(ct) => {
matches!(ct.val, ty::ConstKind::Param(_))
}
};
if arg_is_param {
seen_params.entry(arg).or_default().push(i);
} else {
// Prevent `fn foo() -> Foo<u32>` from being defining.
let opaque_param = generics.param_at(i, tcx);
tcx.sess
.struct_span_err(
span,
"non-defining opaque type use \
in defining scope",
"non-defining opaque type use in defining scope",
)
.span_note(spans, "lifetime used multiple times")
.span_note(
tcx.def_span(opaque_param.def_id),
&format!(
"used non-generic {} `{}` for generic parameter",
opaque_param.kind.descr(),
arg,
),
)
.emit();
}
} // for (arg, param)
for (_, indices) in seen_params {
if indices.len() > 1 {
let descr = generics.param_at(indices[0], tcx).kind.descr();
let spans: Vec<_> = indices
.into_iter()
.map(|i| tcx.def_span(generics.param_at(i, tcx).def_id))
.collect();
tcx.sess
.struct_span_err(
span,
"non-defining opaque type use in defining scope",
)
.span_note(spans, &format!("{} used multiple times", descr))
.emit();
}
}

View File

@ -1,4 +1,4 @@
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{struct_span_err, Applicability, StashKey};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
@ -7,7 +7,7 @@ use rustc_hir::intravisit;
use rustc_hir::intravisit::Visitor;
use rustc_hir::Node;
use rustc_middle::hir::map::Map;
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst};
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable};
use rustc_session::parse::feature_err;
@ -369,13 +369,8 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
struct ConstraintLocator<'tcx> {
tcx: TyCtxt<'tcx>,
def_id: DefId,
// (first found type span, actual type, mapping from the opaque type's generic
// parameters to the concrete type's generic parameters)
//
// The mapping is an index for each use site of a generic parameter in the concrete type
//
// The indices index into the generic parameters on the opaque type.
found: Option<(Span, Ty<'tcx>, Vec<usize>)>,
// (first found type span, actual type)
found: Option<(Span, Ty<'tcx>)>,
}
impl ConstraintLocator<'_> {
@ -407,83 +402,51 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
// FIXME(oli-obk): trace the actual span from inference to improve errors.
let span = self.tcx.def_span(def_id);
// used to quickly look up the position of a generic parameter
let mut index_map: FxHashMap<ty::ParamTy, usize> = FxHashMap::default();
// Skipping binder is ok, since we only use this to find generic parameters and
// their positions.
for (idx, subst) in substs.iter().enumerate() {
if let GenericArgKind::Type(ty) = subst.unpack() {
if let ty::Param(p) = ty.kind {
if index_map.insert(p, idx).is_some() {
// There was already an entry for `p`, meaning a generic parameter
// was used twice.
self.tcx.sess.span_err(
span,
&format!(
"defining opaque type use restricts opaque \
type by using the generic parameter `{}` twice",
p,
),
);
return;
}
} else {
// HACK(eddyb) this check shouldn't be needed, as `wfcheck`
// performs the same checks, in theory, but I've kept it here
// using `delay_span_bug`, just in case `wfcheck` slips up.
let opaque_generics = self.tcx.generics_of(self.def_id);
let mut used_params: FxHashSet<_> = FxHashSet::default();
for (i, arg) in substs.iter().enumerate() {
let arg_is_param = match arg.unpack() {
GenericArgKind::Type(ty) => matches!(ty.kind, ty::Param(_)),
GenericArgKind::Lifetime(lt) => {
matches!(lt, ty::ReEarlyBound(_) | ty::ReFree(_))
}
GenericArgKind::Const(ct) => matches!(ct.val, ty::ConstKind::Param(_)),
};
if arg_is_param {
if !used_params.insert(arg) {
// There was already an entry for `arg`, meaning a generic parameter
// was used twice.
self.tcx.sess.delay_span_bug(
span,
&format!(
"non-defining opaque ty use in defining scope: {:?}, {:?}",
concrete_type, substs,
"defining opaque type use restricts opaque \
type by using the generic parameter `{}` twice",
arg,
),
);
}
}
}
// Compute the index within the opaque type for each generic parameter used in
// the concrete type.
let indices = concrete_type
.subst(self.tcx, substs)
.walk()
.filter_map(|t| match &t.kind {
ty::Param(p) => Some(*index_map.get(p).unwrap()),
_ => None,
})
.collect();
let is_param = |ty: Ty<'_>| match ty.kind {
ty::Param(_) => true,
_ => false,
};
let bad_substs: Vec<_> = substs
.iter()
.enumerate()
.filter_map(|(i, k)| {
if let GenericArgKind::Type(ty) = k.unpack() { Some((i, ty)) } else { None }
})
.filter(|(_, ty)| !is_param(ty))
.collect();
if !bad_substs.is_empty() {
let identity_substs = InternalSubsts::identity_for_item(self.tcx, self.def_id);
for (i, bad_subst) in bad_substs {
self.tcx.sess.span_err(
} else {
let param = opaque_generics.param_at(i, self.tcx);
self.tcx.sess.delay_span_bug(
span,
&format!(
"defining opaque type use does not fully define opaque type: \
generic parameter `{}` is specified as concrete type `{}`",
identity_substs.type_at(i),
bad_subst
generic parameter `{}` is specified as concrete {} `{}`",
param.name,
param.kind.descr(),
arg,
),
);
}
} else if let Some((prev_span, prev_ty, ref prev_indices)) = self.found {
let mut ty = concrete_type.walk().fuse();
let mut p_ty = prev_ty.walk().fuse();
let iter_eq = (&mut ty).zip(&mut p_ty).all(|(t, p)| match (&t.kind, &p.kind) {
// Type parameters are equal to any other type parameter for the purpose of
// concrete type equality, as it is possible to obtain the same type just
// by passing matching parameters to a function.
(ty::Param(_), ty::Param(_)) => true,
_ => t == p,
});
if !iter_eq || ty.next().is_some() || p_ty.next().is_some() {
}
if let Some((prev_span, prev_ty)) = self.found {
if *concrete_type != prev_ty {
debug!("find_opaque_ty_constraints: span={:?}", span);
// Found different concrete types for the opaque type.
let mut err = self.tcx.sess.struct_span_err(
@ -496,34 +459,9 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
);
err.span_note(prev_span, "previous use here");
err.emit();
} else if indices != *prev_indices {
// Found "same" concrete types, but the generic parameter order differs.
let mut err = self.tcx.sess.struct_span_err(
span,
"concrete type's generic parameters differ from previous defining use",
);
use std::fmt::Write;
let mut s = String::new();
write!(s, "expected [").unwrap();
let list = |s: &mut String, indices: &Vec<usize>| {
let mut indices = indices.iter().cloned();
if let Some(first) = indices.next() {
write!(s, "`{}`", substs[first]).unwrap();
for i in indices {
write!(s, ", `{}`", substs[i]).unwrap();
}
}
};
list(&mut s, prev_indices);
write!(s, "], got [").unwrap();
list(&mut s, &indices);
write!(s, "]").unwrap();
err.span_label(span, s);
err.span_note(prev_span, "previous use here");
err.emit();
}
} else {
self.found = Some((span, concrete_type, indices));
self.found = Some((span, concrete_type));
}
} else {
debug!(
@ -606,7 +544,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
}
match locator.found {
Some((_, ty, _)) => ty,
Some((_, ty)) => ty,
None => {
let span = tcx.def_span(def_id);
tcx.sess.span_err(span, "could not find defining uses");

View File

@ -706,6 +706,30 @@ impl<T: Decodable> Decodable for Vec<T> {
}
}
impl Encodable for [u8; 20] {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
s.emit_seq(self.len(), |s| {
for (i, e) in self.iter().enumerate() {
s.emit_seq_elt(i, |s| e.encode(s))?
}
Ok(())
})
}
}
impl Decodable for [u8; 20] {
fn decode<D: Decoder>(d: &mut D) -> Result<[u8; 20], D::Error> {
d.read_seq(|d, len| {
assert!(len == 20);
let mut v = [0u8; 20];
for i in 0..len {
v[i] = d.read_seq_elt(i, |d| Decodable::decode(d))?;
}
Ok(v)
})
}
}
impl<'a, T: Encodable> Encodable for Cow<'a, [T]>
where
[T]: ToOwned<Owned = Vec<T>>,

View File

@ -93,9 +93,7 @@ pub unsafe extern "C" fn __rust_abort() {
#[cfg(not(test))]
pub fn init() {
unsafe {
let _ = net::init();
}
let _ = net::init();
}
#[cfg(not(test))]

View File

@ -1,291 +1,362 @@
use crate::convert::TryFrom;
use crate::fmt;
use crate::io::{self, IoSlice, IoSliceMut};
use crate::io::{self, ErrorKind, IoSlice, IoSliceMut};
use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
use crate::str;
use crate::sys::hermit::abi;
use crate::sys::{unsupported, Void};
use crate::time::Duration;
//// Iinitializes HermitCore's network stack
pub unsafe fn init() -> io::Result<()> {
/// Checks whether the HermitCore's socket interface has been started already, and
/// if not, starts it.
pub fn init() -> io::Result<()> {
if abi::network_init() < 0 {
return Err(io::Error::new(ErrorKind::Other, "Unable to initialize network interface"));
}
Ok(())
}
pub struct TcpStream(Void);
pub struct TcpStream(abi::Handle);
impl TcpStream {
pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
unsupported()
pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
let addr = addr?;
match abi::tcpstream::connect(addr.ip().to_string().as_bytes(), addr.port(), None) {
Ok(handle) => Ok(TcpStream(handle)),
_ => {
Err(io::Error::new(ErrorKind::Other, "Unable to initiate a connection on a socket"))
}
}
}
pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> {
unsupported()
pub fn connect_timeout(saddr: &SocketAddr, duration: Duration) -> io::Result<TcpStream> {
match abi::tcpstream::connect(
saddr.ip().to_string().as_bytes(),
saddr.port(),
Some(duration.as_millis() as u64),
) {
Ok(handle) => Ok(TcpStream(handle)),
_ => {
Err(io::Error::new(ErrorKind::Other, "Unable to initiate a connection on a socket"))
}
}
}
pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
match self.0 {}
pub fn set_read_timeout(&self, duration: Option<Duration>) -> io::Result<()> {
abi::tcpstream::set_read_timeout(self.0, duration.map(|d| d.as_millis() as u64))
.map_err(|_| io::Error::new(ErrorKind::Other, "Unable to set timeout value"))
}
pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
match self.0 {}
pub fn set_write_timeout(&self, duration: Option<Duration>) -> io::Result<()> {
abi::tcpstream::set_write_timeout(self.0, duration.map(|d| d.as_millis() as u64))
.map_err(|_| io::Error::new(ErrorKind::Other, "Unable to set timeout value"))
}
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
match self.0 {}
let duration = abi::tcpstream::get_read_timeout(self.0)
.map_err(|_| io::Error::new(ErrorKind::Other, "Unable to determine timeout value"))?;
Ok(duration.map(|d| Duration::from_millis(d)))
}
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
match self.0 {}
let duration = abi::tcpstream::get_write_timeout(self.0)
.map_err(|_| io::Error::new(ErrorKind::Other, "Unable to determine timeout value"))?;
Ok(duration.map(|d| Duration::from_millis(d)))
}
pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
match self.0 {}
pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
abi::tcpstream::peek(self.0, buf)
.map_err(|_| io::Error::new(ErrorKind::Other, "set_nodelay failed"))
}
pub fn read(&self, _: &mut [u8]) -> io::Result<usize> {
match self.0 {}
pub fn read(&self, buffer: &mut [u8]) -> io::Result<usize> {
self.read_vectored(&mut [IoSliceMut::new(buffer)])
}
pub fn read_vectored(&self, _: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
match self.0 {}
pub fn read_vectored(&self, ioslice: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
let mut size: usize = 0;
for i in ioslice.iter_mut() {
let mut pos: usize = 0;
while pos < i.len() {
let ret = abi::tcpstream::read(self.0, &mut i[pos..])
.map_err(|_| io::Error::new(ErrorKind::Other, "Unable to read on socket"))?;
if ret == 0 {
return Ok(size);
} else {
size += ret;
pos += ret;
}
}
}
Ok(size)
}
pub fn write(&self, _: &[u8]) -> io::Result<usize> {
match self.0 {}
pub fn write(&self, buffer: &[u8]) -> io::Result<usize> {
self.write_vectored(&[IoSlice::new(buffer)])
}
pub fn write_vectored(&self, _: &[IoSlice<'_>]) -> io::Result<usize> {
match self.0 {}
pub fn write_vectored(&self, ioslice: &[IoSlice<'_>]) -> io::Result<usize> {
let mut size: usize = 0;
for i in ioslice.iter() {
size += abi::tcpstream::write(self.0, i)
.map_err(|_| io::Error::new(ErrorKind::Other, "Unable to write on socket"))?;
}
Ok(size)
}
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "peer_addr isn't supported"))
}
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "socket_addr isn't supported"))
}
pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
match self.0 {}
pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
abi::tcpstream::shutdown(self.0, how as i32)
.map_err(|_| io::Error::new(ErrorKind::Other, "unable to shutdown socket"))
}
pub fn duplicate(&self) -> io::Result<TcpStream> {
match self.0 {}
let handle = abi::tcpstream::duplicate(self.0)
.map_err(|_| io::Error::new(ErrorKind::Other, "unable to duplicate stream"))?;
Ok(TcpStream(handle))
}
pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
match self.0 {}
pub fn set_nodelay(&self, mode: bool) -> io::Result<()> {
abi::tcpstream::set_nodelay(self.0, mode)
.map_err(|_| io::Error::new(ErrorKind::Other, "set_nodelay failed"))
}
pub fn nodelay(&self) -> io::Result<bool> {
match self.0 {}
abi::tcpstream::nodelay(self.0)
.map_err(|_| io::Error::new(ErrorKind::Other, "nodelay failed"))
}
pub fn set_ttl(&self, _: u32) -> io::Result<()> {
match self.0 {}
pub fn set_ttl(&self, tll: u32) -> io::Result<()> {
abi::tcpstream::set_tll(self.0, tll)
.map_err(|_| io::Error::new(ErrorKind::Other, "unable to set TTL"))
}
pub fn ttl(&self) -> io::Result<u32> {
match self.0 {}
abi::tcpstream::get_tll(self.0)
.map_err(|_| io::Error::new(ErrorKind::Other, "unable to get TTL"))
}
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "take_error isn't supported"))
}
pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
match self.0 {}
pub fn set_nonblocking(&self, mode: bool) -> io::Result<()> {
abi::tcpstream::set_nonblocking(self.0, mode)
.map_err(|_| io::Error::new(ErrorKind::Other, "unable to set blocking mode"))
}
}
impl Drop for TcpStream {
fn drop(&mut self) {
let _ = abi::tcpstream::close(self.0);
}
}
impl fmt::Debug for TcpStream {
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.0 {}
Ok(())
}
}
pub struct TcpListener(Void);
pub struct TcpListener(abi::Handle);
impl TcpListener {
pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
unsupported()
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn duplicate(&self) -> io::Result<TcpListener> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn set_ttl(&self, _: u32) -> io::Result<()> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn ttl(&self) -> io::Result<u32> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn only_v6(&self) -> io::Result<bool> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
}
impl fmt::Debug for TcpListener {
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.0 {}
Ok(())
}
}
pub struct UdpSocket(Void);
pub struct UdpSocket(abi::Handle);
impl UdpSocket {
pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
unsupported()
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn duplicate(&self) -> io::Result<UdpSocket> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn set_broadcast(&self, _: bool) -> io::Result<()> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn broadcast(&self) -> io::Result<bool> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn multicast_loop_v4(&self) -> io::Result<bool> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn multicast_loop_v6(&self) -> io::Result<bool> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn set_ttl(&self, _: u32) -> io::Result<()> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn ttl(&self) -> io::Result<u32> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn send(&self, _: &[u8]) -> io::Result<usize> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
match self.0 {}
Err(io::Error::new(ErrorKind::Other, "not supported"))
}
}
impl fmt::Debug for UdpSocket {
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.0 {}
Ok(())
}
}

View File

@ -640,6 +640,25 @@ static DICompileUnit::DebugEmissionKind fromRust(LLVMRustDebugEmissionKind Kind)
}
}
enum class LLVMRustChecksumKind {
None,
MD5,
SHA1,
};
static Optional<DIFile::ChecksumKind> fromRust(LLVMRustChecksumKind Kind) {
switch (Kind) {
case LLVMRustChecksumKind::None:
return None;
case LLVMRustChecksumKind::MD5:
return DIFile::ChecksumKind::CSK_MD5;
case LLVMRustChecksumKind::SHA1:
return DIFile::ChecksumKind::CSK_SHA1;
default:
report_fatal_error("bad ChecksumKind.");
}
}
extern "C" uint32_t LLVMRustDebugMetadataVersion() {
return DEBUG_METADATA_VERSION;
}
@ -686,9 +705,15 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit(
extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFile(
LLVMRustDIBuilderRef Builder,
const char *Filename, size_t FilenameLen,
const char *Directory, size_t DirectoryLen) {
const char *Directory, size_t DirectoryLen, LLVMRustChecksumKind CSKind,
const char *Checksum, size_t ChecksumLen) {
Optional<DIFile::ChecksumKind> llvmCSKind = fromRust(CSKind);
Optional<DIFile::ChecksumInfo<StringRef>> CSInfo{};
if (llvmCSKind)
CSInfo.emplace(*llvmCSKind, StringRef{Checksum, ChecksumLen});
return wrap(Builder->createFile(StringRef(Filename, FilenameLen),
StringRef(Directory, DirectoryLen)));
StringRef(Directory, DirectoryLen),
CSInfo));
}
extern "C" LLVMMetadataRef

View File

@ -22,7 +22,7 @@ fn main() {
}
// Here we check that local debuginfo is mapped correctly.
// CHECK: !DIFile(filename: "/the/src/remap_path_prefix/main.rs", directory: "/the/cwd/")
// CHECK: !DIFile(filename: "/the/src/remap_path_prefix/main.rs", directory: "/the/cwd/"
// And here that debuginfo from other crates are expanded to absolute paths.
// CHECK: !DIFile(filename: "/the/aux-src/remap_path_prefix_aux.rs", directory: "")
// CHECK: !DIFile(filename: "/the/aux-src/remap_path_prefix_aux.rs", directory: ""

View File

@ -11,4 +11,4 @@ pub fn foo() {
}
// Here we check that local debuginfo is mapped correctly.
// CHECK: !DIFile(filename: "/the/aux-src/xcrate-generic.rs", directory: "")
// CHECK: !DIFile(filename: "/the/aux-src/xcrate-generic.rs", directory: ""

View File

@ -0,0 +1,6 @@
// compile-flags: -g -Z src-hash-algorithm=md5
#![crate_type = "lib"]
pub fn test() {}
// CHECK: checksumkind: CSK_MD5

View File

@ -0,0 +1,6 @@
// compile-flags: -g -Z src-hash-algorithm=sha1
#![crate_type = "lib"]
pub fn test() {}
// CHECK: checksumkind: CSK_SHA1

View File

@ -8,13 +8,12 @@ trait TraitWithAssoc {
}
type Foo<V> = impl Trait<V>;
//~^ ERROR could not find defining uses
//~| ERROR the trait bound `T: TraitWithAssoc` is not satisfied
//~^ ERROR the trait bound `T: TraitWithAssoc` is not satisfied
trait Trait<U> {}
impl<W> Trait<W> for () {}
fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> { //~ ERROR does not fully define
fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
()
}

View File

@ -9,20 +9,6 @@ help: consider further restricting this bound
LL | fn foo_desugared<T: TraitWithAssoc + TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
| ^^^^^^^^^^^^^^^^
error: defining opaque type use does not fully define opaque type: generic parameter `V` is specified as concrete type `<T as TraitWithAssoc>::Assoc`
--> $DIR/bound_reduction2.rs:18:1
|
LL | / fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
LL | | ()
LL | | }
| |_^
error: could not find defining uses
--> $DIR/bound_reduction2.rs:10:1
|
LL | type Foo<V> = impl Trait<V>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 3 previous errors
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.

View File

@ -1,14 +1,26 @@
#![feature(type_alias_impl_trait)]
#![feature(type_alias_impl_trait, const_generics)]
#![allow(incomplete_features)]
use std::fmt::Debug;
fn main() {}
// test that unused generic parameters are ok
type Two<T, U> = impl Debug;
//~^ could not find defining uses
type TwoTys<T, U> = impl Debug;
type TwoLifetimes<'a, 'b> = impl Debug;
type TwoConsts<const X: usize, const Y: usize> = impl Debug;
fn one<T: Debug>(t: T) -> Two<T, T> {
//~^ ERROR defining opaque type use restricts opaque type
fn one_ty<T: Debug>(t: T) -> TwoTys<T, T> {
//~^ ERROR non-defining opaque type use in defining scope
t
}
fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> {
//~^ ERROR non-defining opaque type use in defining scope
t
}
fn one_const<const N: usize>(t: *mut [u8; N]) -> TwoConsts<N, N> {
//~^ ERROR non-defining opaque type use in defining scope
t
}

View File

@ -1,17 +1,38 @@
error: defining opaque type use restricts opaque type by using the generic parameter `T` twice
--> $DIR/generic_duplicate_param_use.rs:11:1
error: non-defining opaque type use in defining scope
--> $DIR/generic_duplicate_param_use.rs:13:30
|
LL | / fn one<T: Debug>(t: T) -> Two<T, T> {
LL | |
LL | | t
LL | | }
| |_^
error: could not find defining uses
--> $DIR/generic_duplicate_param_use.rs:8:1
LL | fn one_ty<T: Debug>(t: T) -> TwoTys<T, T> {
| ^^^^^^^^^^^^
|
LL | type Two<T, U> = impl Debug;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: type used multiple times
--> $DIR/generic_duplicate_param_use.rs:9:13
|
LL | type TwoTys<T, U> = impl Debug;
| ^ ^
error: aborting due to 2 previous errors
error: non-defining opaque type use in defining scope
--> $DIR/generic_duplicate_param_use.rs:18:36
|
LL | fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> {
| ^^^^^^^^^^^^^^^^^^^^
|
note: lifetime used multiple times
--> $DIR/generic_duplicate_param_use.rs:10:19
|
LL | type TwoLifetimes<'a, 'b> = impl Debug;
| ^^ ^^
error: non-defining opaque type use in defining scope
--> $DIR/generic_duplicate_param_use.rs:23:50
|
LL | fn one_const<const N: usize>(t: *mut [u8; N]) -> TwoConsts<N, N> {
| ^^^^^^^^^^^^^^^
|
note: constant used multiple times
--> $DIR/generic_duplicate_param_use.rs:11:22
|
LL | type TwoConsts<const X: usize, const Y: usize> = impl Debug;
| ^ ^
error: aborting due to 3 previous errors

View File

@ -8,10 +8,10 @@ fn main() {}
type Two<T, U> = impl Debug;
fn one<T: Debug>(t: T) -> Two<T, T> {
//~^ defining opaque type use restricts opaque type
t
}
fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
//~^ ERROR concrete type differs from previous defining opaque type use
t
}

View File

@ -1,8 +1,16 @@
error: defining opaque type use restricts opaque type by using the generic parameter `T` twice
error: concrete type differs from previous defining opaque type use
--> $DIR/generic_duplicate_param_use2.rs:14:1
|
LL | / fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
LL | |
LL | | t
LL | | }
| |_^ expected `U`, got `T`
|
note: previous use here
--> $DIR/generic_duplicate_param_use2.rs:10:1
|
LL | / fn one<T: Debug>(t: T) -> Two<T, T> {
LL | |
LL | | t
LL | | }
| |_^

View File

@ -8,15 +8,14 @@ fn main() {}
type Two<T, U> = impl Debug;
fn one<T: Debug>(t: T) -> Two<T, T> {
//~^ defining opaque type use restricts opaque type
t
}
fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
//~^ ERROR concrete type differs from previous defining opaque type use
t
}
fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> {
//~^ concrete type's generic parameters differ from previous defining use
u
}

View File

@ -1,28 +1,19 @@
error: defining opaque type use restricts opaque type by using the generic parameter `T` twice
error: concrete type differs from previous defining opaque type use
--> $DIR/generic_duplicate_param_use3.rs:14:1
|
LL | / fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
LL | |
LL | | t
LL | | }
| |_^ expected `U`, got `T`
|
note: previous use here
--> $DIR/generic_duplicate_param_use3.rs:10:1
|
LL | / fn one<T: Debug>(t: T) -> Two<T, T> {
LL | |
LL | | t
LL | | }
| |_^
error: concrete type's generic parameters differ from previous defining use
--> $DIR/generic_duplicate_param_use3.rs:19:1
|
LL | / fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> {
LL | |
LL | | u
LL | | }
| |_^ expected [`T`], got [`U`]
|
note: previous use here
--> $DIR/generic_duplicate_param_use3.rs:15:1
|
LL | / fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
LL | | t
LL | | }
| |_^
error: aborting due to 2 previous errors
error: aborting due to previous error

View File

@ -8,7 +8,7 @@ fn main() {}
type Two<T, U> = impl Debug;
fn one<T: Debug>(t: T) -> Two<T, T> {
//~^ ERROR defining opaque type use restricts opaque type
//~^ ERROR non-defining opaque type use in defining scope
t
}

View File

@ -1,11 +1,14 @@
error: defining opaque type use restricts opaque type by using the generic parameter `T` twice
--> $DIR/generic_duplicate_param_use4.rs:10:1
error: non-defining opaque type use in defining scope
--> $DIR/generic_duplicate_param_use4.rs:10:27
|
LL | / fn one<T: Debug>(t: T) -> Two<T, T> {
LL | |
LL | | t
LL | | }
| |_^
LL | fn one<T: Debug>(t: T) -> Two<T, T> {
| ^^^^^^^^^
|
note: type used multiple times
--> $DIR/generic_duplicate_param_use4.rs:8:10
|
LL | type Two<T, U> = impl Debug;
| ^ ^
error: aborting due to previous error

View File

@ -1,13 +1,27 @@
#![feature(type_alias_impl_trait)]
#![feature(type_alias_impl_trait, const_generics)]
#![allow(incomplete_features)]
use std::fmt::Debug;
fn main() {}
type Cmp<T> = impl 'static;
//~^ ERROR could not find defining uses
//~^^ ERROR: at least one trait must be specified
type OneTy<T> = impl Debug;
type OneLifetime<'a> = impl Debug;
type OneConst<const X: usize> = impl Debug;
// Not defining uses, because they doesn't define *all* possible generics.
// not a defining use, because it doesn't define *all* possible generics
fn cmp() -> Cmp<u32> { //~ ERROR defining opaque type use does not fully define
fn concrete_ty() -> OneTy<u32> {
//~^ ERROR non-defining opaque type use in defining scope
5u32
}
fn concrete_lifetime() -> OneLifetime<'static> {
//~^ ERROR non-defining opaque type use in defining scope
6u32
}
fn concrete_const() -> OneConst<{123}> {
//~^ ERROR non-defining opaque type use in defining scope
7u32
}

View File

@ -1,22 +1,35 @@
error: at least one trait must be specified
--> $DIR/generic_nondefining_use.rs:5:15
error: non-defining opaque type use in defining scope
--> $DIR/generic_nondefining_use.rs:14:21
|
LL | type Cmp<T> = impl 'static;
| ^^^^^^^^^^^^
LL | fn concrete_ty() -> OneTy<u32> {
| ^^^^^^^^^^
|
note: used non-generic type `u32` for generic parameter
--> $DIR/generic_nondefining_use.rs:8:12
|
LL | type OneTy<T> = impl Debug;
| ^
error: defining opaque type use does not fully define opaque type: generic parameter `T` is specified as concrete type `u32`
--> $DIR/generic_nondefining_use.rs:11:1
error: non-defining opaque type use in defining scope
--> $DIR/generic_nondefining_use.rs:19:27
|
LL | / fn cmp() -> Cmp<u32> {
LL | | 5u32
LL | | }
| |_^
LL | type OneLifetime<'a> = impl Debug;
| -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type
...
LL | fn concrete_lifetime() -> OneLifetime<'static> {
| ^^^^^^^^^^^^^^^^^^^^
error: could not find defining uses
--> $DIR/generic_nondefining_use.rs:5:1
error: non-defining opaque type use in defining scope
--> $DIR/generic_nondefining_use.rs:24:24
|
LL | type Cmp<T> = impl 'static;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | fn concrete_const() -> OneConst<{123}> {
| ^^^^^^^^^^^^^^^
|
note: used non-generic constant `123usize` for generic parameter
--> $DIR/generic_nondefining_use.rs:10:21
|
LL | type OneConst<const X: usize> = impl Debug;
| ^
error: aborting due to 3 previous errors

View File

@ -6,7 +6,6 @@ trait IterBits {
}
type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
//~^ ERROR could not find defining uses
impl<T: Copy, E> IterBits for T
where
@ -18,7 +17,8 @@ where
{
type BitsIter = IterBitsIter<T, E, u8>;
fn iter_bits(self, n: u8) -> Self::BitsIter {
//~^ ERROR defining opaque type use does not fully define opaque type
//~^ ERROR non-defining opaque type use in defining scope
//~| ERROR non-defining opaque type use in defining scope
(0u8..n)
.rev()
.map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())

View File

@ -1,19 +1,26 @@
error: defining opaque type use does not fully define opaque type: generic parameter `I` is specified as concrete type `u8`
--> $DIR/issue-60564.rs:20:5
error: non-defining opaque type use in defining scope
--> $DIR/issue-60564.rs:19:34
|
LL | / fn iter_bits(self, n: u8) -> Self::BitsIter {
LL | |
LL | | (0u8..n)
LL | | .rev()
LL | | .map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
LL | | }
| |_____^
error: could not find defining uses
--> $DIR/issue-60564.rs:8:1
LL | fn iter_bits(self, n: u8) -> Self::BitsIter {
| ^^^^^^^^^^^^^^
|
note: used non-generic type `_` for generic parameter
--> $DIR/issue-60564.rs:8:22
|
LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^
error: non-defining opaque type use in defining scope
--> $DIR/issue-60564.rs:19:34
|
LL | fn iter_bits(self, n: u8) -> Self::BitsIter {
| ^^^^^^^^^^^^^^
|
note: used non-generic type `u8` for generic parameter
--> $DIR/issue-60564.rs:8:25
|
LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
| ^
error: aborting due to 2 previous errors

View File

@ -4,9 +4,9 @@
#![feature(type_alias_impl_trait)]
trait Trait<T> {}
type Alias<'a, U> = impl Trait<U>; //~ ERROR could not find defining uses
type Alias<'a, U> = impl Trait<U>;
fn f<'a>() -> Alias<'a, ()> {}
//~^ ERROR defining opaque type use does not fully define opaque type: generic parameter `U`
//~^ ERROR non-defining opaque type use in defining scope
fn main() {}

View File

@ -1,14 +1,14 @@
error: defining opaque type use does not fully define opaque type: generic parameter `U` is specified as concrete type `()`
--> $DIR/issue-68368-non-defining-use.rs:8:1
error: non-defining opaque type use in defining scope
--> $DIR/issue-68368-non-defining-use.rs:8:15
|
LL | fn f<'a>() -> Alias<'a, ()> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: could not find defining uses
--> $DIR/issue-68368-non-defining-use.rs:7:1
| ^^^^^^^^^^^^^
|
note: used non-generic type `()` for generic parameter
--> $DIR/issue-68368-non-defining-use.rs:7:16
|
LL | type Alias<'a, U> = impl Trait<U>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^
error: aborting due to 2 previous errors
error: aborting due to previous error

View File

@ -7,7 +7,6 @@ fn main() {}
type Two<T, U> = impl Debug;
fn two<T: Debug>(t: T) -> Two<T, u32> {
//~^ ERROR defining opaque type use does not fully define opaque type
(t, 4i8)
}

View File

@ -1,14 +1,5 @@
error: defining opaque type use does not fully define opaque type: generic parameter `U` is specified as concrete type `u32`
--> $DIR/not_a_defining_use.rs:9:1
|
LL | / fn two<T: Debug>(t: T) -> Two<T, u32> {
LL | |
LL | | (t, 4i8)
LL | | }
| |_^
error: concrete type differs from previous defining opaque type use
--> $DIR/not_a_defining_use.rs:30:1
--> $DIR/not_a_defining_use.rs:29:1
|
LL | / fn four<T: Debug, U: Bar>(t: T) -> Two<T, U> {
LL | | (t, <U as Bar>::FOO)
@ -16,12 +7,12 @@ LL | | }
| |_^ expected `(T, i8)`, got `(T, <U as Bar>::Blub)`
|
note: previous use here
--> $DIR/not_a_defining_use.rs:14:1
--> $DIR/not_a_defining_use.rs:9:1
|
LL | / fn three<T: Debug, U>(t: T) -> Two<T, U> {
LL | | (t, 5i8)
LL | / fn two<T: Debug>(t: T) -> Two<T, u32> {
LL | | (t, 4i8)
LL | | }
| |_^
error: aborting due to 2 previous errors
error: aborting due to previous error

View File

@ -26,7 +26,6 @@ const LICENSES: &[&str] = &[
const EXCEPTIONS: &[(&str, &str)] = &[
("mdbook", "MPL-2.0"), // mdbook
("openssl", "Apache-2.0"), // cargo, mdbook
("arrayref", "BSD-2-Clause"), // mdbook via handlebars via pest
("toml-query", "MPL-2.0"), // mdbook
("toml-query_derive", "MPL-2.0"), // mdbook
("is-match", "MPL-2.0"), // mdbook
@ -74,6 +73,9 @@ const WHITELIST: &[&str] = &[
"backtrace",
"backtrace-sys",
"bitflags",
"block-buffer",
"block-padding",
"byte-tools",
"byteorder",
"c2-chacha",
"cc",
@ -87,15 +89,18 @@ const WHITELIST: &[&str] = &[
"crossbeam-queue",
"crossbeam-utils",
"datafrog",
"digest",
"dlmalloc",
"either",
"ena",
"env_logger",
"fake-simd",
"filetime",
"flate2",
"fortanix-sgx-abi",
"fuchsia-zircon",
"fuchsia-zircon-sys",
"generic-array",
"getopts",
"getrandom",
"hashbrown",
@ -111,6 +116,7 @@ const WHITELIST: &[&str] = &[
"lock_api",
"log",
"log_settings",
"md-5",
"measureme",
"memchr",
"memmap",
@ -118,6 +124,7 @@ const WHITELIST: &[&str] = &[
"miniz_oxide",
"nodrop",
"num_cpus",
"opaque-debug",
"parking_lot",
"parking_lot_core",
"pkg-config",
@ -150,6 +157,7 @@ const WHITELIST: &[&str] = &[
"semver-parser",
"serde",
"serde_derive",
"sha-1",
"smallvec",
"stable_deref_trait",
"syn",
@ -159,6 +167,7 @@ const WHITELIST: &[&str] = &[
"termion",
"termize",
"thread_local",
"typenum",
"ucd-util",
"unicode-normalization",
"unicode-script",