diff options
Diffstat (limited to 'src')
41 files changed, 720 insertions, 470 deletions
diff --git a/src/doc/unstable-book/src/compiler-flags/src-hash-algorithm.md b/src/doc/unstable-book/src/compiler-flags/src-hash-algorithm.md new file mode 100644 index 00000000000..5a7d0655a44 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/src-hash-algorithm.md @@ -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. diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index a9e21c056a3..700f25d35bc 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -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( diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 1d61d95cc6b..aeb34e5c9c9 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -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( diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index a8cc34e1854..02bf1aded3b 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -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); diff --git a/src/librustc_middle/ich/impls_syntax.rs b/src/librustc_middle/ich/impls_syntax.rs index c5a4b53b10d..300aac19e51 100644 --- a/src/librustc_middle/ich/impls_syntax.rs +++ b/src/librustc_middle/ich/impls_syntax.rs @@ -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: _, diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs index 901365ef691..9b182333907 100644 --- a/src/librustc_middle/ty/mod.rs +++ b/src/librustc_middle/ty/mod.rs @@ -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"), } } } diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs index 54481bd124d..58a03dbe388 100644 --- a/src/librustc_session/config.rs +++ b/src/librustc_session/config.rs @@ -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); diff --git a/src/librustc_session/options.rs b/src/librustc_session/options.rs index 432f1e17ab3..3962e30335d 100644 --- a/src/librustc_session/options.rs +++ b/src/librustc_session/options.rs @@ -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`)"), } diff --git a/src/librustc_session/session.rs b/src/librustc_session/session.rs index 98d0fa74d62..1c5d19db49c 100644 --- a/src/librustc_session/session.rs +++ b/src/librustc_session/session.rs @@ -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 diff --git a/src/librustc_span/Cargo.toml b/src/librustc_span/Cargo.toml index c3fa2331d2b..1c2721260d6 100644 --- a/src/librustc_span/Cargo.toml +++ b/src/librustc_span/Cargo.toml @@ -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" diff --git a/src/librustc_span/lib.rs b/src/librustc_span/lib.rs index 3bcc20d36e7..0d9f3f214fb 100644 --- a/src/librustc_span/lib.rs +++ b/src/librustc_span/lib.rs @@ -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; } diff --git a/src/librustc_span/source_map.rs b/src/librustc_span/source_map.rs index 57e68320f3f..49e2144b3e3 100644 --- a/src/librustc_span/source_map.rs +++ b/src/librustc_span/source_map.rs @@ -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, diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 30a53cbc397..b0ff17ad56d 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -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", + ) + .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", + "non-defining opaque type use in defining scope", ) - .span_note(spans, "lifetime used multiple times") + .span_note(spans, &format!("{} used multiple times", descr)) .emit(); } } diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs index e6099b98dc8..d45c8270068 100644 --- a/src/librustc_typeck/collect/type_of.rs +++ b/src/librustc_typeck/collect/type_of.rs @@ -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"); diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs index 8c6548cd3c5..e80d16bb0c7 100644 --- a/src/libserialize/serialize.rs +++ b/src/libserialize/serialize.rs @@ -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>>, diff --git a/src/libstd/sys/hermit/mod.rs b/src/libstd/sys/hermit/mod.rs index 1e4a53abdc7..958532b8fc4 100644 --- a/src/libstd/sys/hermit/mod.rs +++ b/src/libstd/sys/hermit/mod.rs @@ -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))] diff --git a/src/libstd/sys/hermit/net.rs b/src/libstd/sys/hermit/net.rs index 82917e71be1..377c3132c5a 100644 --- a/src/libstd/sys/hermit/net.rs +++ b/src/libstd/sys/hermit/net.rs @@ -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(()) } } diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 799adb41882..21094b32520 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -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 diff --git a/src/test/codegen/remap_path_prefix/main.rs b/src/test/codegen/remap_path_prefix/main.rs index 4724dc3c3e5..20475bab0fc 100644 --- a/src/test/codegen/remap_path_prefix/main.rs +++ b/src/test/codegen/remap_path_prefix/main.rs @@ -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: "" diff --git a/src/test/codegen/remap_path_prefix/xcrate-generic.rs b/src/test/codegen/remap_path_prefix/xcrate-generic.rs index 30d6112fd02..7a9d2ca9b6b 100644 --- a/src/test/codegen/remap_path_prefix/xcrate-generic.rs +++ b/src/test/codegen/remap_path_prefix/xcrate-generic.rs @@ -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: "" diff --git a/src/test/codegen/src-hash-algorithm/src-hash-algorithm-md5.rs b/src/test/codegen/src-hash-algorithm/src-hash-algorithm-md5.rs new file mode 100644 index 00000000000..64be1127786 --- /dev/null +++ b/src/test/codegen/src-hash-algorithm/src-hash-algorithm-md5.rs @@ -0,0 +1,6 @@ +// compile-flags: -g -Z src-hash-algorithm=md5 + +#![crate_type = "lib"] + +pub fn test() {} +// CHECK: checksumkind: CSK_MD5 diff --git a/src/test/codegen/src-hash-algorithm/src-hash-algorithm-sha1.rs b/src/test/codegen/src-hash-algorithm/src-hash-algorithm-sha1.rs new file mode 100644 index 00000000000..54e07152142 --- /dev/null +++ b/src/test/codegen/src-hash-algorithm/src-hash-algorithm-sha1.rs @@ -0,0 +1,6 @@ +// compile-flags: -g -Z src-hash-algorithm=sha1 + +#![crate_type = "lib"] + +pub fn test() {} +// CHECK: checksumkind: CSK_SHA1 diff --git a/src/test/ui/type-alias-impl-trait/bound_reduction2.rs b/src/test/ui/type-alias-impl-trait/bound_reduction2.rs index 1becb1e83a5..0a4cc9b7fe8 100644 --- a/src/test/ui/type-alias-impl-trait/bound_reduction2.rs +++ b/src/test/ui/type-alias-impl-trait/bound_reduction2.rs @@ -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> { () } diff --git a/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr b/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr index aff558569ea..b871f79aa1d 100644 --- a/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr +++ b/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr @@ -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`. diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs index 165e320be5e..4503607a836 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs @@ -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 } diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr index e1794034e20..b4757e2763d 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr @@ -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 - | -LL | / fn one<T: Debug>(t: T) -> Two<T, T> { -LL | | -LL | | t -LL | | } - | |_^ +error: non-defining opaque type use in defining scope + --> $DIR/generic_duplicate_param_use.rs:13:30 + | +LL | fn one_ty<T: Debug>(t: T) -> TwoTys<T, T> { + | ^^^^^^^^^^^^ + | +note: type used multiple times + --> $DIR/generic_duplicate_param_use.rs:9:13 + | +LL | type TwoTys<T, U> = impl Debug; + | ^ ^ -error: could not find defining uses - --> $DIR/generic_duplicate_param_use.rs:8:1 +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 Two<T, U> = impl Debug; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type TwoConsts<const X: usize, const Y: usize> = impl Debug; + | ^ ^ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs index 0adce817c5c..2b98d8fc63a 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs @@ -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 } diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr index a9a51fa0b4b..8170c671f68 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr @@ -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 | | } | |_^ diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs index 8d3e7f9f424..d9133fd11f7 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs @@ -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 } diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr index 04dcdc295f9..86dd3368400 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr @@ -1,28 +1,19 @@ -error: defining opaque type use restricts opaque type by using the generic parameter `T` twice - --> $DIR/generic_duplicate_param_use3.rs:10:1 +error: concrete type differs from previous defining opaque type use + --> $DIR/generic_duplicate_param_use3.rs:14:1 | -LL | / fn one<T: Debug>(t: T) -> Two<T, T> { +LL | / fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> { 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`] + | |_^ expected `U`, got `T` | note: previous use here - --> $DIR/generic_duplicate_param_use3.rs:15:1 + --> $DIR/generic_duplicate_param_use3.rs:10:1 | -LL | / fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> { +LL | / fn one<T: Debug>(t: T) -> Two<T, T> { LL | | t LL | | } | |_^ -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs index 65f7d7f485d..40388c3b6c8 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs @@ -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 } diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr index 082177b8212..fcf01f5164a 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr @@ -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 diff --git a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs index 60106eba175..b1782120f84 100644 --- a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs +++ b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs @@ -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 +} diff --git a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr index b952aaa79cc..b0ffc4a5ef6 100644 --- a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr @@ -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 | fn concrete_const() -> OneConst<{123}> { + | ^^^^^^^^^^^^^^^ + | +note: used non-generic constant `123usize` for generic parameter + --> $DIR/generic_nondefining_use.rs:10:21 | -LL | type Cmp<T> = impl 'static; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type OneConst<const X: usize> = impl Debug; + | ^ error: aborting due to 3 previous errors diff --git a/src/test/ui/type-alias-impl-trait/issue-60564.rs b/src/test/ui/type-alias-impl-trait/issue-60564.rs index 73acc92172b..4eb7f7836d8 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60564.rs +++ b/src/test/ui/type-alias-impl-trait/issue-60564.rs @@ -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()) diff --git a/src/test/ui/type-alias-impl-trait/issue-60564.stderr b/src/test/ui/type-alias-impl-trait/issue-60564.stderr index 9de3e759e15..55984609437 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60564.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-60564.stderr @@ -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 | | } - | |_____^ +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: could not find defining uses - --> $DIR/issue-60564.rs:8:1 +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 diff --git a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs index d00f8d7a901..3b6decbe9c6 100644 --- a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs +++ b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs @@ -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() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr index b585942406f..c2fa54f50f8 100644 --- a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr @@ -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 diff --git a/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs b/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs index ca00e582d34..02485b24e7b 100644 --- a/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs +++ b/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs @@ -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) } diff --git a/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr b/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr index d68f1bd30a0..cce861b76c9 100644 --- a/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr +++ b/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr @@ -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 diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index a221184fab0..62dc965b55f 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -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", |
