diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index 931c28f1ca98e..b1ee636644ec7 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -99,7 +99,7 @@ objdir=$root_dir/obj mkdir -p $HOME/.cargo mkdir -p $objdir/tmp -mkdir $objdir/cores +mkdir -p $objdir/cores args= if [ "$SCCACHE_BUCKET" != "" ]; then diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index 19bdcbc6ad63e..0ae45b3123259 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -103,7 +103,7 @@ impl LeafNode { } fn is_shared_root(&self) -> bool { - self as *const _ == &EMPTY_ROOT_NODE as *const _ as *const LeafNode + ptr::eq(self, &EMPTY_ROOT_NODE as *const _ as *const _) } } diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index 04d14f40b850b..dbcb63addb846 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -97,7 +97,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { let name = self.extract_type_name(&ty); let mut err_span = span; - let mut labels = vec![(span, format!("cannot infer type for `{}`", name))]; + let mut labels = vec![( + span, + if &name == "_" { + "cannot infer type".to_string() + } else { + format!("cannot infer type for `{}`", name) + }, + )]; let mut local_visitor = FindLocalByTypeVisitor { infcx: &self, diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 8efce297a9117..c16029d33205e 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -39,7 +39,7 @@ use hir::intravisit; use hir; use lint::builtin::BuiltinLintDiagnostics; use session::{Session, DiagnosticMessageId}; -use std::hash; +use std::{hash, ptr}; use syntax::ast; use syntax::codemap::{MultiSpan, ExpnFormat}; use syntax::edition::Edition; @@ -354,7 +354,7 @@ pub struct LintId { impl PartialEq for LintId { fn eq(&self, other: &LintId) -> bool { - (self.lint as *const Lint) == (other.lint as *const Lint) + ptr::eq(self.lint, other.lint) } } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 178f0d3cdcbc1..bd24b93f0293f 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -47,7 +47,7 @@ use std::ops::Deref; use rustc_data_structures::sync::{self, Lrc, ParallelIterator, par_iter}; use std::slice; use std::vec::IntoIter; -use std::mem; +use std::{mem, ptr}; use syntax::ast::{self, DUMMY_NODE_ID, Name, Ident, NodeId}; use syntax::attr; use syntax::ext::hygiene::Mark; @@ -527,8 +527,7 @@ impl<'tcx> PartialOrd for TyS<'tcx> { impl<'tcx> PartialEq for TyS<'tcx> { #[inline] fn eq(&self, other: &TyS<'tcx>) -> bool { - // (self as *const _) == (other as *const _) - (self as *const TyS<'tcx>) == (other as *const TyS<'tcx>) + ptr::eq(self, other) } } impl<'tcx> Eq for TyS<'tcx> {} @@ -678,7 +677,7 @@ impl PartialOrd for Slice where T: PartialOrd { impl PartialEq for Slice { #[inline] fn eq(&self, other: &Slice) -> bool { - (self as *const _) == (other as *const _) + ptr::eq(self, other) } } impl Eq for Slice {} @@ -1730,7 +1729,7 @@ impl Ord for AdtDef { impl PartialEq for AdtDef { // AdtDef are always interned and this is part of TyS equality #[inline] - fn eq(&self, other: &Self) -> bool { self as *const _ == other as *const _ } + fn eq(&self, other: &Self) -> bool { ptr::eq(self, other) } } impl Eq for AdtDef {} diff --git a/src/librustc/ty/query/job.rs b/src/librustc/ty/query/job.rs index a54deeca293d8..56a8c13a8d3b8 100644 --- a/src/librustc/ty/query/job.rs +++ b/src/librustc/ty/query/job.rs @@ -20,7 +20,7 @@ use ty::query::plumbing::CycleError; use ty::context::TyCtxt; use errors::Diagnostic; use std::process; -use std::fmt; +use std::{fmt, ptr}; use std::collections::HashSet; #[cfg(parallel_queries)] use { @@ -124,7 +124,7 @@ impl<'tcx> QueryJob<'tcx> { while let Some(job) = current_job { cycle.insert(0, job.info.clone()); - if &*job as *const _ == self as *const _ { + if ptr::eq(&*job, self) { // This is the end of the cycle // The span entry we included was for the usage // of the cycle itself, and not part of the cycle diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs index a33f8b569d0a8..60b5cf2ec7651 100644 --- a/src/librustc_codegen_llvm/back/lto.rs +++ b/src/librustc_codegen_llvm/back/lto.rs @@ -759,20 +759,6 @@ impl ThinModule { cgcx.save_temp_bitcode(&module, "thin-lto-after-pm"); timeline.record("thin-done"); - // FIXME: this is a hack around a bug in LLVM right now. Discovered in - // #46910 it was found out that on 32-bit MSVC LLVM will hit a codegen - // error if there's an available_externally function in the LLVM module. - // Typically we don't actually use these functions but ThinLTO makes - // heavy use of them when inlining across modules. - // - // Tracked upstream at https://bugs.llvm.org/show_bug.cgi?id=35736 this - // function call (and its definition on the C++ side of things) - // shouldn't be necessary eventually and we can safetly delete these few - // lines. - llvm::LLVMRustThinLTORemoveAvailableExternally(llmod); - cgcx.save_temp_bitcode(&module, "thin-lto-after-rm-ae"); - timeline.record("no-ae"); - Ok(module) } } diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index b386f887d77f1..ef0d57c7b7ce7 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -56,29 +56,30 @@ extern crate rustc_cratesio_shim; pub use rustc_serialize::hex::ToHex; -pub mod array_vec; pub mod accumulate_vec; -pub mod small_vec; +pub mod array_vec; pub mod base_n; pub mod bitslice; pub mod bitvec; +pub mod flock; +pub mod fx; +pub mod graph; pub mod indexed_set; pub mod indexed_vec; pub mod obligation_forest; +pub mod owning_ref; +pub mod ptr_key; pub mod sip128; +pub mod small_vec; pub mod snapshot_map; pub use ena::snapshot_vec; +pub mod sorted_map; pub mod stable_hasher; -pub mod transitive_relation; -pub use ena::unify; -pub mod fx; -pub mod tuple_slice; -pub mod graph; -pub mod flock; pub mod sync; -pub mod owning_ref; pub mod tiny_list; -pub mod sorted_map; +pub mod transitive_relation; +pub mod tuple_slice; +pub use ena::unify; pub mod work_queue; pub struct OnDrop(pub F); diff --git a/src/librustc_data_structures/ptr_key.rs b/src/librustc_data_structures/ptr_key.rs new file mode 100644 index 0000000000000..6835dab38df0a --- /dev/null +++ b/src/librustc_data_structures/ptr_key.rs @@ -0,0 +1,45 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::{hash, ptr}; +use std::ops::Deref; + +/// A wrapper around reference that compares and hashes like a pointer. +/// Can be used as a key in sets/maps indexed by pointers to avoid `unsafe`. +#[derive(Debug)] +pub struct PtrKey<'a, T: 'a>(pub &'a T); + +impl<'a, T> Clone for PtrKey<'a, T> { + fn clone(&self) -> Self { *self } +} + +impl<'a, T> Copy for PtrKey<'a, T> {} + +impl<'a, T> PartialEq for PtrKey<'a, T> { + fn eq(&self, rhs: &Self) -> bool { + ptr::eq(self.0, rhs.0) + } +} + +impl<'a, T> Eq for PtrKey<'a, T> {} + +impl<'a, T> hash::Hash for PtrKey<'a, T> { + fn hash(&self, hasher: &mut H) { + (self.0 as *const T).hash(hasher) + } +} + +impl<'a, T> Deref for PtrKey<'a, T> { + type Target = T; + + fn deref(&self) -> &Self::Target { + self.0 + } +} diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index b4483557dd33f..8d04438eea290 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -1791,7 +1791,6 @@ extern "C" { CU1: *mut *mut c_void, CU2: *mut *mut c_void); pub fn LLVMRustThinLTOPatchDICompileUnit(M: ModuleRef, CU: *mut c_void); - pub fn LLVMRustThinLTORemoveAvailableExternally(M: ModuleRef); pub fn LLVMRustLinkerNew(M: ModuleRef) -> LinkerRef; pub fn LLVMRustLinkerAdd(linker: LinkerRef, diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index e00919547fc43..da2847dc55793 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -651,7 +651,7 @@ impl<'a> Resolver<'a> { binding: &'a NameBinding<'a>, span: Span, allow_shadowing: bool) { - if self.global_macros.insert(name, binding).is_some() && !allow_shadowing { + if self.macro_prelude.insert(name, binding).is_some() && !allow_shadowing { let msg = format!("`{}` is already in scope", name); let note = "macro-expanded `#[macro_use]`s may not shadow existing macros (see RFC 1560)"; @@ -704,8 +704,7 @@ impl<'a> Resolver<'a> { } else { for (name, span) in legacy_imports.imports { let ident = Ident::with_empty_ctxt(name); - let result = self.resolve_ident_in_module(module, ident, MacroNS, - false, false, span); + let result = self.resolve_ident_in_module(module, ident, MacroNS, false, span); if let Ok(binding) = result { let directive = macro_use_directive(span); self.potentially_unused_imports.push(directive); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index d98434796d5bd..9fe25aaa6c01f 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1393,7 +1393,7 @@ pub struct Resolver<'a> { crate_loader: &'a mut dyn CrateLoader, macro_names: FxHashSet, - global_macros: FxHashMap>, + macro_prelude: FxHashMap>, pub all_macros: FxHashMap, lexical_macro_resolutions: Vec<(Ident, &'a Cell>)>, macro_map: FxHashMap>, @@ -1715,7 +1715,7 @@ impl<'a> Resolver<'a> { crate_loader, macro_names: FxHashSet(), - global_macros: FxHashMap(), + macro_prelude: FxHashMap(), all_macros: FxHashMap(), lexical_macro_resolutions: Vec::new(), macro_map: FxHashMap(), @@ -2002,7 +2002,6 @@ impl<'a> Resolver<'a> { module: Module<'a>, mut ident: Ident, ns: Namespace, - ignore_unresolved_invocations: bool, record_used: bool, span: Span) -> Result<&'a NameBinding<'a>, Determinacy> { @@ -2012,7 +2011,7 @@ impl<'a> Resolver<'a> { self.current_module = self.macro_def_scope(def); } let result = self.resolve_ident_in_module_unadjusted( - module, ident, ns, ignore_unresolved_invocations, record_used, span, + module, ident, ns, false, record_used, span, ); self.current_module = orig_current_module; result @@ -2518,7 +2517,7 @@ impl<'a> Resolver<'a> { // If there is a TraitRef in scope for an impl, then the method must be in the // trait. if let Some((module, _)) = self.current_trait_ref { - if self.resolve_ident_in_module(module, ident, ns, false, false, span).is_err() { + if self.resolve_ident_in_module(module, ident, ns, false, span).is_err() { let path = &self.current_trait_ref.as_ref().unwrap().1.path; resolve_error(self, span, err(ident.name, &path_names_to_string(path))); } @@ -3225,7 +3224,7 @@ impl<'a> Resolver<'a> { }; } } - let is_global = self.global_macros.get(&path[0].name).cloned() + let is_global = self.macro_prelude.get(&path[0].name).cloned() .map(|binding| binding.get_macro(self).kind() == MacroKind::Bang).unwrap_or(false); if primary_ns != MacroNS && (is_global || self.macro_names.contains(&path[0].modern())) { @@ -3468,7 +3467,7 @@ impl<'a> Resolver<'a> { } let binding = if let Some(module) = module { - self.resolve_ident_in_module(module, ident, ns, false, record_used, path_span) + self.resolve_ident_in_module(module, ident, ns, record_used, path_span) } else if opt_ns == Some(MacroNS) { self.resolve_lexical_macro_path_segment(ident, ns, record_used, path_span) .map(MacroBinding::binding) @@ -3762,7 +3761,7 @@ impl<'a> Resolver<'a> { // Look for associated items in the current trait. if let Some((module, _)) = self.current_trait_ref { if let Ok(binding) = - self.resolve_ident_in_module(module, ident, ns, false, false, module.span) { + self.resolve_ident_in_module(module, ident, ns, false, module.span) { let def = binding.def(); if filter_fn(def) { return Some(if self.has_self.contains(&def.def_id()) { @@ -4075,7 +4074,7 @@ impl<'a> Resolver<'a> { let mut found_traits = Vec::new(); // Look for the current trait. if let Some((module, _)) = self.current_trait_ref { - if self.resolve_ident_in_module(module, ident, ns, false, false, module.span).is_ok() { + if self.resolve_ident_in_module(module, ident, ns, false, module.span).is_ok() { let def_id = module.def_id().unwrap(); found_traits.push(TraitCandidate { def_id: def_id, import_id: None }); } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index f076d884f6099..0ad652b4710ce 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -220,7 +220,7 @@ impl<'a> base::Resolver for Resolver<'a> { vis: ty::Visibility::Invisible, expansion: Mark::root(), }); - self.global_macros.insert(ident.name, binding); + self.macro_prelude.insert(ident.name, binding); } fn resolve_imports(&mut self) { @@ -238,7 +238,7 @@ impl<'a> base::Resolver for Resolver<'a> { attr::mark_known(&attrs[i]); } - match self.global_macros.get(&name).cloned() { + match self.macro_prelude.get(&name).cloned() { Some(binding) => match *binding.get_macro(self) { MultiModifier(..) | MultiDecorator(..) | SyntaxExtension::AttrProcMacro(..) => { return Some(attrs.remove(i)) @@ -274,7 +274,7 @@ impl<'a> base::Resolver for Resolver<'a> { } let trait_name = traits[j].segments[0].ident.name; let legacy_name = Symbol::intern(&format!("derive_{}", trait_name)); - if !self.global_macros.contains_key(&legacy_name) { + if !self.macro_prelude.contains_key(&legacy_name) { continue } let span = traits.remove(j).span; @@ -565,7 +565,7 @@ impl<'a> Resolver<'a> { module, ident, ns, true, record_used, path_span, ).map(MacroBinding::Modern) } else { - self.global_macros.get(&ident.name).cloned().ok_or(determinacy) + self.macro_prelude.get(&ident.name).cloned().ok_or(determinacy) .map(MacroBinding::Global) }; self.current_module = orig_current_module; @@ -588,8 +588,7 @@ impl<'a> Resolver<'a> { return potential_illegal_shadower; } } - if binding.expansion != Mark::root() || - (binding.is_glob_import() && module.unwrap().def().is_some()) { + if binding.is_glob_import() || binding.expansion != Mark::root() { potential_illegal_shadower = result; } else { return result; @@ -652,7 +651,7 @@ impl<'a> Resolver<'a> { let binding = if let Some(binding) = binding { MacroBinding::Legacy(binding) - } else if let Some(binding) = self.global_macros.get(&ident.name).cloned() { + } else if let Some(binding) = self.macro_prelude.get(&ident.name).cloned() { if !self.use_extern_macros { self.record_use(ident, MacroNS, binding, DUMMY_SP); } @@ -762,8 +761,8 @@ impl<'a> Resolver<'a> { // Then check global macros. }.or_else(|| { // FIXME: get_macro needs an &mut Resolver, can we do it without cloning? - let global_macros = self.global_macros.clone(); - let names = global_macros.iter().filter_map(|(name, binding)| { + let macro_prelude = self.macro_prelude.clone(); + let names = macro_prelude.iter().filter_map(|(name, binding)| { if binding.get_macro(self).kind() == kind { Some(name) } else { diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 0ee17ebc48704..50eb89be69011 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -17,6 +17,7 @@ use Resolver; use {names_to_string, module_to_string}; use {resolve_error, ResolutionError}; +use rustc_data_structures::ptr_key::PtrKey; use rustc::ty; use rustc::lint::builtin::BuiltinLintDiagnostics; use rustc::lint::builtin::{DUPLICATE_MACRO_EXPORTS, PUB_USE_OF_PRIVATE_EXTERN_CRATE}; @@ -104,67 +105,20 @@ impl<'a> ImportDirective<'a> { #[derive(Clone, Default, Debug)] /// Records information about the resolution of a name in a namespace of a module. pub struct NameResolution<'a> { - /// The single imports that define the name in the namespace. - single_imports: SingleImports<'a>, + /// Single imports that may define the name in the namespace. + /// Import directives are arena-allocated, so it's ok to use pointers as keys. + single_imports: FxHashSet>>, /// The least shadowable known binding for this name, or None if there are no known bindings. pub binding: Option<&'a NameBinding<'a>>, - shadows_glob: Option<&'a NameBinding<'a>>, -} - -#[derive(Clone, Debug)] -enum SingleImports<'a> { - /// No single imports can define the name in the namespace. - None, - /// Only the given single import can define the name in the namespace. - MaybeOne(&'a ImportDirective<'a>), - /// Only one of these two single imports can define the name in the namespace. - MaybeTwo(&'a ImportDirective<'a>, &'a ImportDirective<'a>), - /// At least one single import will define the name in the namespace. - AtLeastOne, -} - -impl<'a> Default for SingleImports<'a> { - /// Creates a `SingleImports<'a>` of None type. - fn default() -> Self { - SingleImports::None - } -} - -impl<'a> SingleImports<'a> { - fn add_directive(&mut self, directive: &'a ImportDirective<'a>, use_extern_macros: bool) { - match *self { - SingleImports::None => *self = SingleImports::MaybeOne(directive), - SingleImports::MaybeOne(directive_one) => *self = if use_extern_macros { - SingleImports::MaybeTwo(directive_one, directive) - } else { - SingleImports::AtLeastOne - }, - // If three single imports can define the name in the namespace, we can assume that at - // least one of them will define it since otherwise we'd get duplicate errors in one of - // other namespaces. - SingleImports::MaybeTwo(..) => *self = SingleImports::AtLeastOne, - SingleImports::AtLeastOne => {} - }; - } - - fn directive_failed(&mut self, dir: &'a ImportDirective<'a>) { - match *self { - SingleImports::None => unreachable!(), - SingleImports::MaybeOne(_) => *self = SingleImports::None, - SingleImports::MaybeTwo(dir1, dir2) => - *self = SingleImports::MaybeOne(if ptr::eq(dir1, dir) { dir1 } else { dir2 }), - SingleImports::AtLeastOne => {} - } - } + shadowed_glob: Option<&'a NameBinding<'a>>, } impl<'a> NameResolution<'a> { // Returns the binding for the name if it is known or None if it not known. fn binding(&self) -> Option<&'a NameBinding<'a>> { - self.binding.and_then(|binding| match self.single_imports { - SingleImports::None => Some(binding), - _ if !binding.is_glob_import() => Some(binding), - _ => None, // The binding could be shadowed by a single import, so it is not known. + self.binding.and_then(|binding| { + if !binding.is_glob_import() || + self.single_imports.is_empty() { Some(binding) } else { None } }) } } @@ -177,7 +131,7 @@ impl<'a> Resolver<'a> { } /// Attempts to resolve `ident` in namespaces `ns` of `module`. - /// Invariant: if `record_used` is `Some`, import resolution must be complete. + /// Invariant: if `record_used` is `Some`, expansion and import resolution must be complete. pub fn resolve_ident_in_module_unadjusted(&mut self, module: Module<'a>, ident: Ident, @@ -194,7 +148,7 @@ impl<'a> Resolver<'a> { if record_used { if let Some(binding) = resolution.binding { - if let Some(shadowed_glob) = resolution.shadows_glob { + if let Some(shadowed_glob) = resolution.shadowed_glob { let name = ident.name; // Forbid expanded shadowing to avoid time travel. if restricted_shadowing && @@ -227,81 +181,72 @@ impl<'a> Resolver<'a> { if usable { Ok(binding) } else { Err(Determined) } }; - // Items and single imports are not shadowable. + // Items and single imports are not shadowable, if we have one, then it's determined. if let Some(binding) = resolution.binding { if !binding.is_glob_import() { return check_usable(self, binding); } } - // Check if a single import can still define the name. - let resolve_single_import = |this: &mut Self, directive: &'a ImportDirective<'a>| { - let module = match directive.imported_module.get() { - Some(module) => module, - None => return false, - }; - let ident = match directive.subclass { + // --- From now on we either have a glob resolution or no resolution. --- + + // Check if one of single imports can still define the name, + // if it can then our result is not determined and can be invalidated. + for single_import in &resolution.single_imports { + if !self.is_accessible(single_import.vis.get()) { + continue; + } + let module = unwrap_or!(single_import.imported_module.get(), return Err(Undetermined)); + let ident = match single_import.subclass { SingleImport { source, .. } => source, _ => unreachable!(), }; - match this.resolve_ident_in_module(module, ident, ns, false, false, path_span) { - Err(Determined) => {} - _ => return false, - } - true - }; - match resolution.single_imports { - SingleImports::AtLeastOne => return Err(Undetermined), - SingleImports::MaybeOne(directive) => { - let accessible = self.is_accessible(directive.vis.get()); - if accessible { - if !resolve_single_import(self, directive) { - return Err(Undetermined) - } - } - } - SingleImports::MaybeTwo(directive1, directive2) => { - let accessible1 = self.is_accessible(directive1.vis.get()); - let accessible2 = self.is_accessible(directive2.vis.get()); - if accessible1 && accessible2 { - if !resolve_single_import(self, directive1) && - !resolve_single_import(self, directive2) { - return Err(Undetermined) - } - } else if accessible1 { - if !resolve_single_import(self, directive1) { - return Err(Undetermined) - } - } else { - if !resolve_single_import(self, directive2) { - return Err(Undetermined) - } - } + match self.resolve_ident_in_module(module, ident, ns, false, path_span) { + Err(Determined) => continue, + Ok(_) | Err(Undetermined) => return Err(Undetermined), } - SingleImports::None => {}, } - let no_unresolved_invocations = - restricted_shadowing || module.unresolved_invocations.borrow().is_empty(); - match resolution.binding { - // In `MacroNS`, expanded bindings do not shadow (enforced in `try_define`). - Some(binding) if no_unresolved_invocations || ns == MacroNS => - return check_usable(self, binding), - None if no_unresolved_invocations => {} - _ => return Err(Undetermined), + // So we have a resolution that's from a glob import. This resolution is determined + // if it cannot be shadowed by some new item/import expanded from a macro. + // This happens either if there are no unexpanded macros, or expanded names cannot + // shadow globs (that happens in macro namespace or with restricted shadowing). + let unexpanded_macros = !module.unresolved_invocations.borrow().is_empty(); + if let Some(binding) = resolution.binding { + if !unexpanded_macros || ns == MacroNS || restricted_shadowing { + return check_usable(self, binding); + } else { + return Err(Undetermined); + } } - // Check if the globs are determined - if restricted_shadowing && module.def().is_some() { + // --- From now on we have no resolution. --- + + // Now we are in situation when new item/import can appear only from a glob or a macro + // expansion. With restricted shadowing names from globs and macro expansions cannot + // shadow names from outer scopes, so we can freely fallback from module search to search + // in outer scopes. To continue search in outer scopes we have to lie a bit and return + // `Determined` to `resolve_lexical_macro_path_segment` even if the correct answer + // for in-module resolution could be `Undetermined`. + if restricted_shadowing { return Err(Determined); } - for directive in module.globs.borrow().iter() { - if !self.is_accessible(directive.vis.get()) { + + // Check if one of unexpanded macros can still define the name, + // if it can then our "no resolution" result is not determined and can be invalidated. + if unexpanded_macros { + return Err(Undetermined); + } + + // Check if one of glob imports can still define the name, + // if it can then our "no resolution" result is not determined and can be invalidated. + for glob_import in module.globs.borrow().iter() { + if !self.is_accessible(glob_import.vis.get()) { continue } - let module = unwrap_or!(directive.imported_module.get(), return Err(Undetermined)); + let module = unwrap_or!(glob_import.imported_module.get(), return Err(Undetermined)); let (orig_current_module, mut ident) = (self.current_module, ident.modern()); - match ident.span.glob_adjust(module.expansion, directive.span.ctxt().modern()) { + match ident.span.glob_adjust(module.expansion, glob_import.span.ctxt().modern()) { Some(Some(def)) => self.current_module = self.macro_def_scope(def), Some(None) => {} None => continue, @@ -310,11 +255,13 @@ impl<'a> Resolver<'a> { module, ident, ns, false, false, path_span, ); self.current_module = orig_current_module; - if let Err(Undetermined) = result { - return Err(Undetermined); + match result { + Err(Determined) => continue, + Ok(_) | Err(Undetermined) => return Err(Undetermined), } } + // No resolution and no one else can define the name - determinate error. Err(Determined) } @@ -348,7 +295,7 @@ impl<'a> Resolver<'a> { SingleImport { target, type_ns_only, .. } => { self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS { let mut resolution = this.resolution(current_module, target, ns).borrow_mut(); - resolution.single_imports.add_directive(directive, this.use_extern_macros); + resolution.single_imports.insert(PtrKey(directive)); }); } // We don't add prelude imports to the globs since they only affect lexical scopes, @@ -401,7 +348,7 @@ impl<'a> Resolver<'a> { if binding.is_glob_import() { if !old_binding.is_glob_import() && !(ns == MacroNS && old_binding.expansion != Mark::root()) { - resolution.shadows_glob = Some(binding); + resolution.shadowed_glob = Some(binding); } else if binding.def() != old_binding.def() { resolution.binding = Some(this.ambiguity(old_binding, binding)); } else if !old_binding.vis.is_at_least(binding.vis, &*this) { @@ -414,7 +361,7 @@ impl<'a> Resolver<'a> { resolution.binding = Some(this.ambiguity(binding, old_binding)); } else { resolution.binding = Some(binding); - resolution.shadows_glob = Some(old_binding); + resolution.shadowed_glob = Some(old_binding); } } else { return Err(old_binding); @@ -455,7 +402,7 @@ impl<'a> Resolver<'a> { _ if old_binding.is_some() => return t, None => return t, Some(binding) => match old_binding { - Some(old_binding) if old_binding as *const _ == binding as *const _ => return t, + Some(old_binding) if ptr::eq(old_binding, binding) => return t, _ => (binding, t), } } @@ -630,7 +577,6 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { source, ns, false, - false, directive.span)); } else { return @@ -641,7 +587,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { Err(Undetermined) => indeterminate = true, Err(Determined) => { this.update_resolution(parent, target, ns, |_, resolution| { - resolution.single_imports.directive_failed(directive) + resolution.single_imports.remove(&PtrKey(directive)); }); } Ok(binding) if !binding.is_importable() => { @@ -803,7 +749,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { if all_ns_err { let mut all_ns_failed = true; self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS { - match this.resolve_ident_in_module(module, ident, ns, false, true, span) { + match this.resolve_ident_in_module(module, ident, ns, true, span) { Ok(_) => all_ns_failed = false, _ => {} } @@ -827,7 +773,8 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { _ => Some(&i.name), } }, - NameResolution { single_imports: SingleImports::None, .. } => None, + NameResolution { ref single_imports, .. } + if single_imports.is_empty() => None, _ => Some(&i.name), } }); @@ -973,7 +920,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { let mut reexports = Vec::new(); let mut exported_macro_names = FxHashMap(); - if module as *const _ == self.graph_root as *const _ { + if ptr::eq(module, self.graph_root) { let macro_exports = mem::replace(&mut self.macro_exports, Vec::new()); for export in macro_exports.into_iter().rev() { if let Some(later_span) = exported_macro_names.insert(export.ident.modern(), diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index aef3beeccdf9c..fd8f394a600f0 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -777,11 +777,50 @@ fn prepend_attrs(sess: &ParseSess, for attr in attrs { assert_eq!(attr.style, ast::AttrStyle::Outer, "inner attributes should prevent cached tokens from existing"); - // FIXME: Avoid this pretty-print + reparse hack as bove - let name = FileName::MacroExpansion; - let source = pprust::attr_to_string(attr); - let stream = parse_stream_from_source_str(name, source, sess, Some(span)); - builder.push(stream); + + if attr.is_sugared_doc { + let stream = parse_stream_from_source_str( + FileName::MacroExpansion, + pprust::attr_to_string(attr), + sess, + Some(span), + ); + builder.push(stream); + continue + } + + // synthesize # [ $path $tokens ] manually here + let mut brackets = tokenstream::TokenStreamBuilder::new(); + + // For simple paths, push the identifier directly + if attr.path.segments.len() == 1 && attr.path.segments[0].args.is_none() { + let ident = attr.path.segments[0].ident; + let token = Ident(ident, ident.as_str().starts_with("r#")); + brackets.push(tokenstream::TokenTree::Token(ident.span, token)); + + // ... and for more complicated paths, fall back to a reparse hack that + // should eventually be removed. + } else { + let stream = parse_stream_from_source_str( + FileName::MacroExpansion, + pprust::path_to_string(&attr.path), + sess, + Some(span), + ); + brackets.push(stream); + } + + brackets.push(attr.tokens.clone()); + + let tokens = tokenstream::Delimited { + delim: DelimToken::Bracket, + tts: brackets.build().into(), + }; + // The span we list here for `#` and for `[ ... ]` are both wrong in + // that it encompasses more than each token, but it hopefully is "good + // enough" for now at least. + builder.push(tokenstream::TokenTree::Token(attr.span, Pound)); + builder.push(tokenstream::TokenTree::Delimited(attr.span, tokens)); } builder.push(tokens.clone()); Some(builder.build()) diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index a00ff3b345d11..2f28c5b32fb88 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -1228,15 +1228,6 @@ LLVMRustThinLTOPatchDICompileUnit(LLVMModuleRef Mod, DICompileUnit *Unit) { MD->addOperand(Unit); } -extern "C" void -LLVMRustThinLTORemoveAvailableExternally(LLVMModuleRef Mod) { - Module *M = unwrap(Mod); - for (Function &F : M->functions()) { - if (F.hasAvailableExternallyLinkage()) - F.deleteBody(); - } -} - #else extern "C" bool @@ -1328,9 +1319,4 @@ LLVMRustThinLTOPatchDICompileUnit(LLVMModuleRef Mod) { report_fatal_error("ThinLTO not available"); } -extern "C" void -LLVMRustThinLTORemoveAvailableExternally(LLVMModuleRef Mod) { - report_fatal_error("ThinLTO not available"); -} - #endif // LLVM_VERSION_GE(4, 0) diff --git a/src/test/run-pass/const-block.rs b/src/test/run-pass/const-block.rs index e56d01d7ba8ce..e6f191ea9522f 100644 --- a/src/test/run-pass/const-block.rs +++ b/src/test/run-pass/const-block.rs @@ -39,13 +39,6 @@ static BLOCK_FN: fn(usize) -> usize = { foo:: }; static BLOCK_ENUM_CONSTRUCTOR: fn(usize) -> Option = { Some }; -// FIXME #13972 -// static BLOCK_UNSAFE_SAFE_PTR: &'static isize = unsafe { &*(0xdeadbeef as *const isize) }; -// static BLOCK_UNSAFE_SAFE_PTR_2: &'static isize = unsafe { -// const X: *const isize = 0xdeadbeef as *const isize; -// &*X -// }; - pub fn main() { assert_eq!(BLOCK_INTEGRAL, 1); assert_eq!(BLOCK_EXPLICIT_UNIT, ()); @@ -58,7 +51,4 @@ pub fn main() { assert_eq!(BLOCK_FN_INFERRED(300), 300); assert_eq!(BLOCK_FN(300), 300); assert_eq!(BLOCK_ENUM_CONSTRUCTOR(200), Some(200)); - // FIXME #13972 - // assert_eq!(BLOCK_UNSAFE_SAFE_PTR as *const isize as usize, 0xdeadbeef); - // assert_eq!(BLOCK_UNSAFE_SAFE_PTR_2 as *const isize as usize, 0xdeadbeef); } diff --git a/src/test/run-pass/issue-33264.rs b/src/test/run-pass/issue-33264.rs new file mode 100644 index 0000000000000..38f5595c8ee09 --- /dev/null +++ b/src/test/run-pass/issue-33264.rs @@ -0,0 +1,37 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(dead_code, non_upper_case_globals)] +#![feature(asm)] + +#[repr(C)] +pub struct D32x4(f32,f32,f32,f32); + +impl D32x4 { + fn add(&self, vec: Self) -> Self { + unsafe { + let ret: Self; + asm!(" + movaps $1, %xmm1 + movaps $2, %xmm2 + addps %xmm1, %xmm2 + movaps $xmm1, $0 + " + : "=r"(ret) + : "1"(self), "2"(vec) + : "xmm1", "xmm2" + ); + ret + } + } +} + +fn main() { } + diff --git a/src/test/run-pass/issue-34784.rs b/src/test/run-pass/issue-34784.rs new file mode 100644 index 0000000000000..903a2bb07ba52 --- /dev/null +++ b/src/test/run-pass/issue-34784.rs @@ -0,0 +1,21 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const C: *const u8 = &0; + +fn foo(x: *const u8) { + match x { + C => {} + _ => {} + } +} + +fn main() {} + diff --git a/src/test/run-pass/issue-44005.rs b/src/test/run-pass/issue-44005.rs new file mode 100644 index 0000000000000..a53026f36ab70 --- /dev/null +++ b/src/test/run-pass/issue-44005.rs @@ -0,0 +1,39 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub trait Foo<'a> { + type Bar; + fn foo(&'a self) -> Self::Bar; +} + +impl<'a, 'b, T: 'a> Foo<'a> for &'b T { + type Bar = &'a T; + fn foo(&'a self) -> &'a T { + self + } +} + +pub fn uncallable(x: T, f: F) + where T: for<'a> Foo<'a>, + F: for<'a> Fn(>::Bar) +{ + f(x.foo()); +} + +pub fn catalyst(x: &i32) { + broken(x, |_| {}) +} + +pub fn broken(x: &i32, f: F) { + uncallable(x, |y| f(y)); +} + +fn main() { } + diff --git a/src/test/ui-fulldeps/proc-macro/attribute-spans-preserved.rs b/src/test/ui-fulldeps/proc-macro/attribute-spans-preserved.rs new file mode 100644 index 0000000000000..e1401653ba356 --- /dev/null +++ b/src/test/ui-fulldeps/proc-macro/attribute-spans-preserved.rs @@ -0,0 +1,22 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:attribute-spans-preserved.rs + +#![feature(use_extern_macros)] + +extern crate attribute_spans_preserved as foo; + +use foo::foo; + +#[ foo ( let y: u32 = "z"; ) ] //~ ERROR: mismatched types +#[ bar let x: u32 = "y"; ] //~ ERROR: mismatched types +fn main() { +} diff --git a/src/test/ui-fulldeps/proc-macro/attribute-spans-preserved.stderr b/src/test/ui-fulldeps/proc-macro/attribute-spans-preserved.stderr new file mode 100644 index 0000000000000..fe62bd23b87c9 --- /dev/null +++ b/src/test/ui-fulldeps/proc-macro/attribute-spans-preserved.stderr @@ -0,0 +1,21 @@ +error[E0308]: mismatched types + --> $DIR/attribute-spans-preserved.rs:19:23 + | +LL | #[ foo ( let y: u32 = "z"; ) ] //~ ERROR: mismatched types + | ^^^ expected u32, found reference + | + = note: expected type `u32` + found type `&'static str` + +error[E0308]: mismatched types + --> $DIR/attribute-spans-preserved.rs:20:21 + | +LL | #[ bar let x: u32 = "y"; ] //~ ERROR: mismatched types + | ^^^ expected u32, found reference + | + = note: expected type `u32` + found type `&'static str` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui-fulldeps/proc-macro/attribute-spans-preserved.stdout b/src/test/ui-fulldeps/proc-macro/attribute-spans-preserved.stdout new file mode 100644 index 0000000000000..33dc064ef680f --- /dev/null +++ b/src/test/ui-fulldeps/proc-macro/attribute-spans-preserved.stdout @@ -0,0 +1 @@ +fn main ( ) { let y : u32 = "z" ; let x : u32 = "y" ; } diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/attribute-spans-preserved.rs b/src/test/ui-fulldeps/proc-macro/auxiliary/attribute-spans-preserved.rs new file mode 100644 index 0000000000000..e725cc7afb82b --- /dev/null +++ b/src/test/ui-fulldeps/proc-macro/auxiliary/attribute-spans-preserved.rs @@ -0,0 +1,44 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::*; + +#[proc_macro_attribute] +pub fn foo(attr: TokenStream, f: TokenStream) -> TokenStream { + let mut tokens = f.into_iter(); + assert_eq!(tokens.next().unwrap().to_string(), "#"); + let next_attr = match tokens.next().unwrap() { + TokenTree::Group(g) => g, + _ => panic!(), + }; + + let fn_tok = tokens.next().unwrap(); + let ident_tok = tokens.next().unwrap(); + let args_tok = tokens.next().unwrap(); + let body = tokens.next().unwrap(); + + let new_body = attr.into_iter() + .chain(next_attr.stream().into_iter().skip(1)); + + let tokens = vec![ + fn_tok, + ident_tok, + args_tok, + Group::new(Delimiter::Brace, new_body.collect()).into(), + ].into_iter().collect::(); + println!("{}", tokens); + return tokens +} diff --git a/src/test/ui/error-codes/E0282.stderr b/src/test/ui/error-codes/E0282.stderr index f1319f4139585..6862e2d8688fd 100644 --- a/src/test/ui/error-codes/E0282.stderr +++ b/src/test/ui/error-codes/E0282.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed LL | let x = "hello".chars().rev().collect(); //~ ERROR E0282 | ^ | | - | cannot infer type for `_` + | cannot infer type | consider giving `x` a type error: aborting due to previous error diff --git a/src/test/ui/imports/glob-shadowing.rs b/src/test/ui/imports/glob-shadowing.rs new file mode 100644 index 0000000000000..e4f55137e660f --- /dev/null +++ b/src/test/ui/imports/glob-shadowing.rs @@ -0,0 +1,44 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(decl_macro)] + +mod m { + pub macro env($e: expr) { $e } + pub macro fenv() { 0 } +} + +mod glob_in_normal_module { + use m::*; + fn check() { + let x = env!("PATH"); //~ ERROR `env` is ambiguous + } +} + +mod glob_in_block_module { + fn block() { + use m::*; + fn check() { + let x = env!("PATH"); //~ ERROR `env` is ambiguous + } + } +} + +mod glob_shadows_item { + pub macro fenv($e: expr) { $e } + fn block() { + use m::*; + fn check() { + let x = fenv!(); //~ ERROR `fenv` is ambiguous + } + } +} + +fn main() {} diff --git a/src/test/ui/imports/glob-shadowing.stderr b/src/test/ui/imports/glob-shadowing.stderr new file mode 100644 index 0000000000000..7f61cd6c76d6a --- /dev/null +++ b/src/test/ui/imports/glob-shadowing.stderr @@ -0,0 +1,49 @@ +error[E0659]: `env` is ambiguous + --> $DIR/glob-shadowing.rs:21:17 + | +LL | let x = env!("PATH"); //~ ERROR `env` is ambiguous + | ^^^ + | +note: `env` could refer to the name imported here + --> $DIR/glob-shadowing.rs:19:9 + | +LL | use m::*; + | ^^^^ + = note: `env` is also a builtin macro + = note: consider adding an explicit import of `env` to disambiguate + +error[E0659]: `env` is ambiguous + --> $DIR/glob-shadowing.rs:29:21 + | +LL | let x = env!("PATH"); //~ ERROR `env` is ambiguous + | ^^^ + | +note: `env` could refer to the name imported here + --> $DIR/glob-shadowing.rs:27:13 + | +LL | use m::*; + | ^^^^ + = note: `env` is also a builtin macro + = note: consider adding an explicit import of `env` to disambiguate + +error[E0659]: `fenv` is ambiguous + --> $DIR/glob-shadowing.rs:39:21 + | +LL | let x = fenv!(); //~ ERROR `fenv` is ambiguous + | ^^^^ + | +note: `fenv` could refer to the name imported here + --> $DIR/glob-shadowing.rs:37:13 + | +LL | use m::*; + | ^^^^ +note: `fenv` could also refer to the name defined here + --> $DIR/glob-shadowing.rs:35:5 + | +LL | pub macro fenv($e: expr) { $e } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: consider adding an explicit import of `fenv` to disambiguate + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0659`. diff --git a/src/test/ui/issue-12187-1.stderr b/src/test/ui/issue-12187-1.stderr index 7d4df2901fe3c..94afd6aab574f 100644 --- a/src/test/ui/issue-12187-1.stderr +++ b/src/test/ui/issue-12187-1.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed LL | let &v = new(); | -^ | || - | |cannot infer type for `_` + | |cannot infer type | consider giving the pattern a type error: aborting due to previous error diff --git a/src/test/ui/issue-12187-2.stderr b/src/test/ui/issue-12187-2.stderr index f7ecbd4477293..90b41e397c6d0 100644 --- a/src/test/ui/issue-12187-2.stderr +++ b/src/test/ui/issue-12187-2.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed LL | let &v = new(); | -^ | || - | |cannot infer type for `_` + | |cannot infer type | consider giving the pattern a type error: aborting due to previous error diff --git a/src/test/ui/issue-15965.stderr b/src/test/ui/issue-15965.stderr index 216c6460c77d1..3162556986e2b 100644 --- a/src/test/ui/issue-15965.stderr +++ b/src/test/ui/issue-15965.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed LL | / { return () } LL | | //~^ ERROR type annotations needed [E0282] LL | | () - | |______^ cannot infer type for `_` + | |______^ cannot infer type | = note: type must be known at this point diff --git a/src/test/ui/issue-18159.stderr b/src/test/ui/issue-18159.stderr index 894660f1ebfbd..084e859111bf1 100644 --- a/src/test/ui/issue-18159.stderr +++ b/src/test/ui/issue-18159.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed LL | let x; //~ ERROR type annotations needed | ^ | | - | cannot infer type for `_` + | cannot infer type | consider giving `x` a type error: aborting due to previous error diff --git a/src/test/ui/issue-20261.stderr b/src/test/ui/issue-20261.stderr index a7a7ea7c69b69..6cdddcff92913 100644 --- a/src/test/ui/issue-20261.stderr +++ b/src/test/ui/issue-20261.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed LL | for (ref i,) in [].iter() { | --------- the element type for this iterator is not specified LL | i.clone(); - | ^^^^^ cannot infer type for `_` + | ^^^^^ cannot infer type | = note: type must be known at this point diff --git a/src/test/ui/issue-2151.stderr b/src/test/ui/issue-2151.stderr index 592c4f424b048..516c5287b319a 100644 --- a/src/test/ui/issue-2151.stderr +++ b/src/test/ui/issue-2151.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed LL | let x = panic!(); | - consider giving `x` a type LL | x.clone(); //~ ERROR type annotations needed - | ^ cannot infer type for `_` + | ^ cannot infer type | = note: type must be known at this point diff --git a/src/test/ui/issue-23041.stderr b/src/test/ui/issue-23041.stderr index f89bce09c7ed3..e97a97fec09f2 100644 --- a/src/test/ui/issue-23041.stderr +++ b/src/test/ui/issue-23041.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed --> $DIR/issue-23041.rs:16:22 | LL | b.downcast_ref::_>(); //~ ERROR E0282 - | ^^^^^^^^ cannot infer type for `_` + | ^^^^^^^^ cannot infer type error: aborting due to previous error diff --git a/src/test/ui/issue-24013.stderr b/src/test/ui/issue-24013.stderr index 324e705e5a1dd..5729bdf2064f5 100644 --- a/src/test/ui/issue-24013.stderr +++ b/src/test/ui/issue-24013.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed --> $DIR/issue-24013.rs:15:20 | LL | unsafe {swap::<&mut _>(transmute(&a), transmute(&b))}; - | ^^^^^^ cannot infer type for `_` + | ^^^^^^ cannot infer type error: aborting due to previous error diff --git a/src/test/ui/issue-34784.rs b/src/test/ui/issue-34784.rs new file mode 100644 index 0000000000000..5c510b4a10d83 --- /dev/null +++ b/src/test/ui/issue-34784.rs @@ -0,0 +1,20 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const C: *const [u8; 4] = b"abcd"; + +fn main() { + match C { + C => {} + //~^ ERROR this expression will panic at runtime + _ => {} + } +} + diff --git a/src/test/ui/issue-34784.stderr b/src/test/ui/issue-34784.stderr new file mode 100644 index 0000000000000..065f9b6b6c9da --- /dev/null +++ b/src/test/ui/issue-34784.stderr @@ -0,0 +1,10 @@ +error: this expression will panic at runtime + --> $DIR/issue-34784.rs:15:9 + | +LL | C => {} + | ^ "pointer arithmetic or comparison" needs an rfc before being allowed inside constants + | + = note: #[deny(const_err)] on by default + +error: aborting due to previous error + diff --git a/src/test/ui/issue-42060.rs b/src/test/ui/issue-42060.rs new file mode 100644 index 0000000000000..23df42d03c4e0 --- /dev/null +++ b/src/test/ui/issue-42060.rs @@ -0,0 +1,22 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let thing = (); + let other: typeof(thing) = thing; //~ ERROR attempt to use a non-constant value in a constant + //~^ ERROR `typeof` is a reserved keyword but unimplemented [E0516] +} + +fn f(){ + let q = 1; + ::N //~ ERROR attempt to use a non-constant value in a constant + //~^ ERROR `typeof` is a reserved keyword but unimplemented [E0516] +} + diff --git a/src/test/ui/issue-42060.stderr b/src/test/ui/issue-42060.stderr new file mode 100644 index 0000000000000..69abac8ee7e3a --- /dev/null +++ b/src/test/ui/issue-42060.stderr @@ -0,0 +1,28 @@ +error[E0435]: attempt to use a non-constant value in a constant + --> $DIR/issue-42060.rs:13:23 + | +LL | let other: typeof(thing) = thing; //~ ERROR attempt to use a non-constant value in a constant + | ^^^^^ non-constant value + +error[E0435]: attempt to use a non-constant value in a constant + --> $DIR/issue-42060.rs:19:13 + | +LL | ::N //~ ERROR attempt to use a non-constant value in a constant + | ^ non-constant value + +error[E0516]: `typeof` is a reserved keyword but unimplemented + --> $DIR/issue-42060.rs:13:16 + | +LL | let other: typeof(thing) = thing; //~ ERROR attempt to use a non-constant value in a constant + | ^^^^^^^^^^^^^ reserved keyword + +error[E0516]: `typeof` is a reserved keyword but unimplemented + --> $DIR/issue-42060.rs:19:6 + | +LL | ::N //~ ERROR attempt to use a non-constant value in a constant + | ^^^^^^^^^ reserved keyword + +error: aborting due to 4 previous errors + +Some errors occurred: E0435, E0516. +For more information about an error, try `rustc --explain E0435`. diff --git a/src/test/ui/issue-43196.rs b/src/test/ui/issue-43196.rs new file mode 100644 index 0000000000000..ff53c9a5a5498 --- /dev/null +++ b/src/test/ui/issue-43196.rs @@ -0,0 +1,17 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + | +} +//~^ ERROR expected `|`, found `}` +| +//~^ ERROR expected item, found `|` + diff --git a/src/test/ui/issue-43196.stderr b/src/test/ui/issue-43196.stderr new file mode 100644 index 0000000000000..2418f517168a4 --- /dev/null +++ b/src/test/ui/issue-43196.stderr @@ -0,0 +1,16 @@ +error: expected `|`, found `}` + --> $DIR/issue-43196.rs:13:1 + | +LL | | + | - expected `|` here +LL | } + | ^ unexpected token + +error: expected item, found `|` + --> $DIR/issue-43196.rs:15:1 + | +LL | | + | ^ expected item + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/issue-7813.stderr b/src/test/ui/issue-7813.stderr index 34837e90e4f79..3ab01982057b4 100644 --- a/src/test/ui/issue-7813.stderr +++ b/src/test/ui/issue-7813.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed --> $DIR/issue-7813.rs:12:13 | LL | let v = &[]; //~ ERROR type annotations needed - | - ^^^ cannot infer type for `_` + | - ^^^ cannot infer type | | | consider giving `v` a type diff --git a/src/test/ui/span/issue-42234-unknown-receiver-type.stderr b/src/test/ui/span/issue-42234-unknown-receiver-type.stderr index e1e13e9256dcd..d2d5a4a4b1265 100644 --- a/src/test/ui/span/issue-42234-unknown-receiver-type.stderr +++ b/src/test/ui/span/issue-42234-unknown-receiver-type.stderr @@ -13,7 +13,7 @@ error[E0282]: type annotations needed | LL | / data.iter() //~ ERROR 22:5: 23:20: type annotations needed LL | | .sum::<_>() - | |___________________^ cannot infer type for `_` + | |___________________^ cannot infer type | = note: type must be known at this point diff --git a/src/test/ui/span/method-and-field-eager-resolution.stderr b/src/test/ui/span/method-and-field-eager-resolution.stderr index 21e19828a99cf..8a8c1e467b9fa 100644 --- a/src/test/ui/span/method-and-field-eager-resolution.stderr +++ b/src/test/ui/span/method-and-field-eager-resolution.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed LL | let mut x = Default::default(); | ----- consider giving `x` a type LL | x.0; - | ^ cannot infer type for `_` + | ^ cannot infer type | = note: type must be known at this point @@ -14,7 +14,7 @@ error[E0282]: type annotations needed LL | let mut x = Default::default(); | ----- consider giving `x` a type LL | x[0]; - | ^ cannot infer type for `_` + | ^ cannot infer type | = note: type must be known at this point diff --git a/src/test/ui/type-check/cannot_infer_local_or_array.stderr b/src/test/ui/type-check/cannot_infer_local_or_array.stderr index 90191ae67451f..bfdd614e50d31 100644 --- a/src/test/ui/type-check/cannot_infer_local_or_array.stderr +++ b/src/test/ui/type-check/cannot_infer_local_or_array.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed --> $DIR/cannot_infer_local_or_array.rs:12:13 | LL | let x = []; //~ ERROR type annotations needed - | - ^^ cannot infer type for `_` + | - ^^ cannot infer type | | | consider giving `x` a type