diff --git a/src/doc/rustc/src/linker-plugin-lto.md b/src/doc/rustc/src/linker-plugin-lto.md index 2ae726c4ba61d..6f1bbe60569fd 100644 --- a/src/doc/rustc/src/linker-plugin-lto.md +++ b/src/doc/rustc/src/linker-plugin-lto.md @@ -105,5 +105,6 @@ The following table shows known good combinations of toolchain versions. | Rust 1.34 | ✗ | ✓ | | Rust 1.35 | ✗ | ✓ | | Rust 1.36 | ✗ | ✓ | +| Rust 1.37 | ✗ | ✓ | Note that the compatibility policy for this feature might change in the future. diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 607427a85d67a..7ec2295f97e36 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -9,14 +9,22 @@ //! * [`Ord`] and [`PartialOrd`] are traits that allow you to define total and //! partial orderings between values, respectively. Implementing them overloads //! the `<`, `<=`, `>`, and `>=` operators. -//! * [`Ordering`][cmp::Ordering] is an enum returned by the -//! main functions of [`Ord`] and [`PartialOrd`], and describes an ordering. -//! * [`Reverse`][cmp::Reverse] is a struct that allows you to easily reverse -//! an ordering. -//! * [`max`][cmp::max] and [`min`][cmp::min] are functions that build off of -//! [`Ord`] and allow you to find the maximum or minimum of two values. +//! * [`Ordering`] is an enum returned by the main functions of [`Ord`] and +//! [`PartialOrd`], and describes an ordering. +//! * [`Reverse`] is a struct that allows you to easily reverse an ordering. +//! * [`max`] and [`min`] are functions that build off of [`Ord`] and allow you +//! to find the maximum or minimum of two values. //! //! For more details, see the respective documentation of each item in the list. +//! +//! [`Eq`]: trait.Eq.html +//! [`PartialEq`]: trait.PartialEq.html +//! [`Ord`]: trait.Ord.html +//! [`PartialOrd`]: trait.PartialOrd.html +//! [`Ordering`]: enum.Ordering.html +//! [`Reverse`]: struct.Reverse.html +//! [`max`]: fn.max.html +//! [`min`]: fn.min.html #![stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index f50781890ab22..8e1ac6082c8a8 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -66,13 +66,6 @@ impl Iterator for Rev where I: DoubleEndedIterator { { self.iter.rfind(predicate) } - - #[inline] - fn rposition

(&mut self, predicate: P) -> Option where - P: FnMut(Self::Item) -> bool - { - self.iter.position(predicate) - } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs index 6efeaf9ee7d2e..1080fd32a8862 100644 --- a/src/libcore/pin.rs +++ b/src/libcore/pin.rs @@ -462,7 +462,7 @@ impl> Pin

{ /// can ignore the pinning invariants when unwrapping it. /// /// [`Unpin`]: ../../std/marker/trait.Unpin.html - #[unstable(feature = "pin_into_inner", issue = "60245")] + #[stable(feature = "pin_into_inner", since = "1.39.0")] #[inline(always)] pub fn into_inner(pin: Pin

) -> P { pin.pointer @@ -569,7 +569,7 @@ impl Pin

{ /// /// [`Unpin`]: ../../std/marker/trait.Unpin.html /// [`Pin::into_inner`]: #method.into_inner - #[unstable(feature = "pin_into_inner", issue = "60245")] + #[stable(feature = "pin_into_inner", since = "1.39.0")] #[inline(always)] pub unsafe fn into_inner_unchecked(pin: Pin

) -> P { pin.pointer diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index 3a4f76852a0d7..8e0658d87c1fb 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -1688,6 +1688,12 @@ fn test_rposition() { assert!(v.iter().rposition(g).is_none()); } +#[test] +fn test_rev_rposition() { + let v = [0, 0, 1, 1]; + assert_eq!(v.iter().rev().rposition(|&x| x == 1), Some(1)); +} + #[test] #[should_panic] fn test_rposition_panic() { diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs index 2d09013f675a7..937a9ea6c1bd4 100644 --- a/src/librustc/error_codes.rs +++ b/src/librustc/error_codes.rs @@ -39,7 +39,7 @@ Generally, `Self: Sized` is used to indicate that the trait should not be used as a trait object. If the trait comes from your own crate, consider removing this restriction. -### Method references the `Self` type in its arguments or return type +### Method references the `Self` type in its parameters or return type This happens when a trait has a method like the following: diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 773bb8dde0690..b8bd1d73fc28b 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -186,7 +186,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { }); let mut upstream_crates: Vec<_> = cstore.crates_untracked().iter().map(|&cnum| { - let name = cstore.crate_name_untracked(cnum).as_str(); + let name = cstore.crate_name_untracked(cnum).as_interned_str(); let disambiguator = cstore.crate_disambiguator_untracked(cnum).to_fingerprint(); let hash = cstore.crate_hash_untracked(cnum); (name, disambiguator, hash) diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 05e2c7854b49c..ddfca3a4cfb72 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -9,7 +9,7 @@ use std::mem; use syntax::ast; use syntax::feature_gate; use syntax::parse::token; -use syntax::symbol::{InternedString, LocalInternedString}; +use syntax::symbol::InternedString; use syntax::tokenstream; use syntax_pos::SourceFile; @@ -39,27 +39,6 @@ impl<'a> ToStableHashKey> for InternedString { } } -impl<'a> HashStable> for LocalInternedString { - #[inline] - fn hash_stable(&self, - hcx: &mut StableHashingContext<'a>, - hasher: &mut StableHasher) { - let s: &str = &**self; - s.hash_stable(hcx, hasher); - } -} - -impl<'a> ToStableHashKey> for LocalInternedString { - type KeyType = LocalInternedString; - - #[inline] - fn to_stable_hash_key(&self, - _: &StableHashingContext<'a>) - -> LocalInternedString { - self.clone() - } -} - impl<'a> HashStable> for ast::Name { #[inline] fn hash_stable(&self, diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index e684ccfeeb7ed..bf9cb79fb8a10 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -1627,7 +1627,7 @@ impl<'tcx> ObligationCause<'tcx> { MainFunctionType => Error0580("main function has wrong type"), StartFunctionType => Error0308("start function has wrong type"), IntrinsicType => Error0308("intrinsic has wrong type"), - MethodReceiver => Error0308("mismatched method receiver"), + MethodReceiver => Error0308("mismatched `self` parameter type"), // In the case where we have no more specific thing to // say, also take a look at the error code, maybe we can diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index affda256322a4..77df93080cd16 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -33,7 +33,7 @@ use crate::util::common::time; use std::default::Default as StdDefault; use syntax::ast; use syntax::edition; -use syntax_pos::{MultiSpan, Span, symbol::{LocalInternedString, Symbol}}; +use syntax_pos::{MultiSpan, Span, symbol::Symbol}; use errors::DiagnosticBuilder; use crate::hir; use crate::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; @@ -405,7 +405,7 @@ impl LintStore { pub fn check_lint_name( &self, lint_name: &str, - tool_name: Option, + tool_name: Option, ) -> CheckLintNameResult<'_> { let complete_name = if let Some(tool_name) = tool_name { format!("{}::{}", tool_name, lint_name) diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs index 139f4343117af..cbc6dbdba7e6c 100644 --- a/src/librustc/lint/levels.rs +++ b/src/librustc/lint/levels.rs @@ -291,7 +291,7 @@ impl<'a> LintLevelsBuilder<'a> { continue; } - Some(tool_ident.as_str()) + Some(tool_ident.name) } else { None }; diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 5ac99ba147000..8956cbb2baefc 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1808,6 +1808,23 @@ pub enum ProjectionElem { Downcast(Option, VariantIdx), } +impl ProjectionElem { + /// Returns `true` if the target of this projection may refer to a different region of memory + /// than the base. + fn is_indirect(&self) -> bool { + match self { + Self::Deref => true, + + | Self::Field(_, _) + | Self::Index(_) + | Self::ConstantIndex { .. } + | Self::Subslice { .. } + | Self::Downcast(_, _) + => false + } + } +} + /// Alias for projections as they appear in places, where the base is a place /// and the index is a local. pub type PlaceElem<'tcx> = ProjectionElem>; @@ -1869,6 +1886,14 @@ impl<'tcx> Place<'tcx> { } } + /// Returns `true` if this `Place` contains a `Deref` projection. + /// + /// If `Place::is_indirect` returns false, the caller knows that the `Place` refers to the + /// same region of memory as its base. + pub fn is_indirect(&self) -> bool { + self.iterate(|_, mut projections| projections.any(|proj| proj.elem.is_indirect())) + } + /// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or /// a single deref of a local. // diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index b38e1f5f83937..03cc00d87e3cd 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1384,7 +1384,10 @@ impl<'tcx> TyCtxt<'tcx> { let mut reported_violations = FxHashSet::default(); for violation in violations { if reported_violations.insert(violation.clone()) { - err.note(&violation.error_msg()); + match violation.span() { + Some(span) => err.span_label(span, violation.error_msg()), + None => err.note(&violation.error_msg()), + }; } } Some(err) diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 7ea7bf0257cf7..f7f459cd27f68 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -20,7 +20,7 @@ use std::borrow::Cow; use std::iter::{self}; use syntax::ast::{self}; use syntax::symbol::InternedString; -use syntax_pos::Span; +use syntax_pos::{Span, DUMMY_SP}; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub enum ObjectSafetyViolation { @@ -32,10 +32,10 @@ pub enum ObjectSafetyViolation { SupertraitSelf, /// Method has something illegal. - Method(ast::Name, MethodViolationCode), + Method(ast::Name, MethodViolationCode, Span), /// Associated const. - AssocConst(ast::Name), + AssocConst(ast::Name, Span), } impl ObjectSafetyViolation { @@ -46,22 +46,35 @@ impl ObjectSafetyViolation { ObjectSafetyViolation::SupertraitSelf => "the trait cannot use `Self` as a type parameter \ in the supertraits or where-clauses".into(), - ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod) => - format!("method `{}` has no receiver", name).into(), - ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf) => - format!("method `{}` references the `Self` type \ - in its arguments or return type", name).into(), - ObjectSafetyViolation::Method(name, - MethodViolationCode::WhereClauseReferencesSelf(_)) => - format!("method `{}` references the `Self` type in where clauses", name).into(), - ObjectSafetyViolation::Method(name, MethodViolationCode::Generic) => + ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod, _) => + format!("associated function `{}` has no `self` parameter", name).into(), + ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf, _) => format!( + "method `{}` references the `Self` type in its parameters or return type", + name, + ).into(), + ObjectSafetyViolation::Method( + name, + MethodViolationCode::WhereClauseReferencesSelf, + _, + ) => format!("method `{}` references the `Self` type in where clauses", name).into(), + ObjectSafetyViolation::Method(name, MethodViolationCode::Generic, _) => format!("method `{}` has generic type parameters", name).into(), - ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver) => - format!("method `{}`'s receiver cannot be dispatched on", name).into(), - ObjectSafetyViolation::AssocConst(name) => + ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver, _) => + format!("method `{}`'s `self` parameter cannot be dispatched on", name).into(), + ObjectSafetyViolation::AssocConst(name, _) => format!("the trait cannot contain associated consts like `{}`", name).into(), } } + + pub fn span(&self) -> Option { + // When `span` comes from a separate crate, it'll be `DUMMY_SP`. Treat it as `None` so + // diagnostics use a `note` instead of a `span_label`. + match *self { + ObjectSafetyViolation::AssocConst(_, span) | + ObjectSafetyViolation::Method(_, _, span) if span != DUMMY_SP => Some(span), + _ => None, + } + } } /// Reasons a method might not be object-safe. @@ -74,7 +87,7 @@ pub enum MethodViolationCode { ReferencesSelf, /// e.g., `fn foo(&self) where Self: Clone` - WhereClauseReferencesSelf(Span), + WhereClauseReferencesSelf, /// e.g., `fn foo()` Generic, @@ -88,9 +101,10 @@ impl<'tcx> TyCtxt<'tcx> { /// astconv -- currently, `Self` in supertraits. This is needed /// because `object_safety_violations` can't be used during /// type collection. - pub fn astconv_object_safety_violations(self, trait_def_id: DefId) - -> Vec - { + pub fn astconv_object_safety_violations( + self, + trait_def_id: DefId, + ) -> Vec { debug_assert!(self.generics_of(trait_def_id).has_self); let violations = traits::supertrait_def_ids(self, trait_def_id) .filter(|&def_id| self.predicates_reference_self(def_id, true)) @@ -128,7 +142,7 @@ impl<'tcx> TyCtxt<'tcx> { } match self.virtual_call_violation_for_method(trait_def_id, method) { - None | Some(MethodViolationCode::WhereClauseReferencesSelf(_)) => true, + None | Some(MethodViolationCode::WhereClauseReferencesSelf) => true, Some(_) => false, } } @@ -138,12 +152,15 @@ impl<'tcx> TyCtxt<'tcx> { let mut violations: Vec<_> = self.associated_items(trait_def_id) .filter(|item| item.kind == ty::AssocKind::Method) .filter_map(|item| - self.object_safety_violation_for_method(trait_def_id, &item) - .map(|code| ObjectSafetyViolation::Method(item.ident.name, code)) + self.object_safety_violation_for_method(trait_def_id, &item).map(|code| { + ObjectSafetyViolation::Method(item.ident.name, code, item.ident.span) + }) ).filter(|violation| { - if let ObjectSafetyViolation::Method(_, - MethodViolationCode::WhereClauseReferencesSelf(span)) = violation - { + if let ObjectSafetyViolation::Method( + _, + MethodViolationCode::WhereClauseReferencesSelf, + span, + ) = violation { // Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id. // It's also hard to get a use site span, so we use the method definition span. self.lint_node_note( @@ -169,7 +186,7 @@ impl<'tcx> TyCtxt<'tcx> { violations.extend(self.associated_items(trait_def_id) .filter(|item| item.kind == ty::AssocKind::Const) - .map(|item| ObjectSafetyViolation::AssocConst(item.ident.name))); + .map(|item| ObjectSafetyViolation::AssocConst(item.ident.name, item.ident.span))); debug!("object_safety_violations_for_trait(trait_def_id={:?}) = {:?}", trait_def_id, @@ -325,8 +342,7 @@ impl<'tcx> TyCtxt<'tcx> { .visit_tys_shallow(|t| { self.contains_illegal_self_type_reference(trait_def_id, t) }) { - let span = self.def_span(method.def_id); - return Some(MethodViolationCode::WhereClauseReferencesSelf(span)); + return Some(MethodViolationCode::WhereClauseReferencesSelf); } let receiver_ty = self.liberate_late_bound_regions( diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs index 0a42b6b46f2c9..5a988d9509e80 100644 --- a/src/librustc/traits/on_unimplemented.rs +++ b/src/librustc/traits/on_unimplemented.rs @@ -9,10 +9,9 @@ use syntax::ast::{MetaItem, NestedMetaItem}; use syntax::attr; use syntax::symbol::{Symbol, kw, sym}; use syntax_pos::Span; -use syntax_pos::symbol::LocalInternedString; #[derive(Clone, Debug)] -pub struct OnUnimplementedFormatString(LocalInternedString); +pub struct OnUnimplementedFormatString(Symbol); #[derive(Debug)] pub struct OnUnimplementedDirective { @@ -89,19 +88,19 @@ impl<'tcx> OnUnimplementedDirective { if item.check_name(sym::message) && message.is_none() { if let Some(message_) = item.value_str() { message = Some(OnUnimplementedFormatString::try_parse( - tcx, trait_def_id, message_.as_str(), span)?); + tcx, trait_def_id, message_, span)?); continue; } } else if item.check_name(sym::label) && label.is_none() { if let Some(label_) = item.value_str() { label = Some(OnUnimplementedFormatString::try_parse( - tcx, trait_def_id, label_.as_str(), span)?); + tcx, trait_def_id, label_, span)?); continue; } } else if item.check_name(sym::note) && note.is_none() { if let Some(note_) = item.value_str() { note = Some(OnUnimplementedFormatString::try_parse( - tcx, trait_def_id, note_.as_str(), span)?); + tcx, trait_def_id, note_, span)?); continue; } } else if item.check_name(sym::on) && is_root && @@ -154,7 +153,7 @@ impl<'tcx> OnUnimplementedDirective { message: None, subcommands: vec![], label: Some(OnUnimplementedFormatString::try_parse( - tcx, trait_def_id, value.as_str(), attr.span)?), + tcx, trait_def_id, value, attr.span)?), note: None, })) } else { @@ -218,7 +217,7 @@ impl<'tcx> OnUnimplementedFormatString { fn try_parse( tcx: TyCtxt<'tcx>, trait_def_id: DefId, - from: LocalInternedString, + from: Symbol, err_sp: Span, ) -> Result { let result = OnUnimplementedFormatString(from); @@ -234,7 +233,8 @@ impl<'tcx> OnUnimplementedFormatString { ) -> Result<(), ErrorReported> { let name = tcx.item_name(trait_def_id); let generics = tcx.generics_of(trait_def_id); - let parser = Parser::new(&self.0, None, vec![], false); + let s = self.0.as_str(); + let parser = Parser::new(&s, None, vec![], false); let mut result = Ok(()); for token in parser { match token { @@ -294,7 +294,8 @@ impl<'tcx> OnUnimplementedFormatString { }).collect::>(); let empty_string = String::new(); - let parser = Parser::new(&self.0, None, vec![], false); + let s = self.0.as_str(); + let parser = Parser::new(&s, None, vec![], false); parser.map(|p| match p { Piece::String(s) => s, diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 56505c04f0f0c..2da50f37409ae 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -46,7 +46,7 @@ use std::ops::Range; use syntax::ast::{self, Name, Ident, NodeId}; use syntax::attr; use syntax::ext::hygiene::ExpnId; -use syntax::symbol::{kw, sym, Symbol, LocalInternedString, InternedString}; +use syntax::symbol::{kw, sym, Symbol, InternedString}; use syntax_pos::Span; use smallvec; @@ -3386,10 +3386,6 @@ impl SymbolName { name: InternedString::intern(name) } } - - pub fn as_str(&self) -> LocalInternedString { - self.name.as_str() - } } impl fmt::Display for SymbolName { diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 7a77418050cdb..a08c82a0ae82f 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -709,8 +709,10 @@ impl<'tcx> TyCtxt<'tcx> { substs: SubstsRef<'tcx>, ) -> Option> { if self.found_recursion { - None - } else if self.seen_opaque_tys.insert(def_id) { + return None; + } + let substs = substs.fold_with(self); + if self.seen_opaque_tys.insert(def_id) { let generic_ty = self.tcx.type_of(def_id); let concrete_ty = generic_ty.subst(self.tcx, substs); let expanded_ty = self.fold_ty(concrete_ty); diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 894e5c2fd3d93..fc23ef1d47e5b 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -5,7 +5,6 @@ use crate::context::CodegenCx; use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; -use syntax::symbol::LocalInternedString; use rustc_codegen_ssa::common::{IntPredicate, TypeKind, RealPredicate}; use rustc_codegen_ssa::MemFlags; use libc::{c_uint, c_char}; @@ -24,6 +23,7 @@ use std::ffi::CStr; use std::ops::{Deref, Range}; use std::ptr; use std::iter::TrustedLen; +use syntax::symbol::Symbol; // All Builders must have an llfn associated with them #[must_use] @@ -1082,8 +1082,8 @@ impl StaticBuilderMethods for Builder<'a, 'll, 'tcx> { fn static_panic_msg( &mut self, - msg: Option, - filename: LocalInternedString, + msg: Option, + filename: Symbol, line: Self::Value, col: Self::Value, kind: &str, diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs index 2c0a6f631b739..35d5107842d5b 100644 --- a/src/librustc_codegen_llvm/callee.rs +++ b/src/librustc_codegen_llvm/callee.rs @@ -37,7 +37,7 @@ pub fn get_fn( return llfn; } - let sym = tcx.symbol_name(instance).as_str(); + let sym = tcx.symbol_name(instance).name.as_str(); debug!("get_fn({:?}: {:?}) => {}", instance, sig, sym); // Create a fn pointer with the substituted signature. diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index 19f18088579b3..c337e35460e18 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -17,7 +17,7 @@ use rustc_codegen_ssa::mir::place::PlaceRef; use libc::{c_uint, c_char}; -use syntax::symbol::LocalInternedString; +use syntax::symbol::Symbol; use syntax::ast::Mutability; pub use crate::context::CodegenCx; @@ -122,7 +122,7 @@ impl CodegenCx<'ll, 'tcx> { fn const_cstr( &self, - s: LocalInternedString, + s: Symbol, null_terminated: bool, ) -> &'ll Value { unsafe { @@ -130,9 +130,10 @@ impl CodegenCx<'ll, 'tcx> { return llval; } + let s_str = s.as_str(); let sc = llvm::LLVMConstStringInContext(self.llcx, - s.as_ptr() as *const c_char, - s.len() as c_uint, + s_str.as_ptr() as *const c_char, + s_str.len() as c_uint, !null_terminated as Bool); let sym = self.generate_local_symbol_name("str"); let g = self.define_global(&sym[..], self.val_ty(sc)).unwrap_or_else(||{ @@ -147,8 +148,8 @@ impl CodegenCx<'ll, 'tcx> { } } - pub fn const_str_slice(&self, s: LocalInternedString) -> &'ll Value { - let len = s.len(); + pub fn const_str_slice(&self, s: Symbol) -> &'ll Value { + let len = s.as_str().len(); let cs = consts::ptrcast(self.const_cstr(s, false), self.type_ptr_to(self.layout_of(self.tcx.mk_str()).llvm_type(self))); self.const_fat_ptr(cs, self.const_usize(len as u64)) diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index 958666cb8858a..e71d1fc16924b 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -11,12 +11,11 @@ use rustc::mir::interpret::{ConstValue, Allocation, read_target_uint, Pointer, ErrorHandled, GlobalId}; use rustc::mir::mono::MonoItem; use rustc::hir::Node; -use syntax_pos::Span; use rustc_target::abi::HasDataLayout; -use syntax::symbol::sym; -use syntax_pos::symbol::LocalInternedString; use rustc::ty::{self, Ty, Instance}; use rustc_codegen_ssa::traits::*; +use syntax::symbol::{Symbol, sym}; +use syntax_pos::Span; use rustc::ty::layout::{self, Size, Align, LayoutOf}; @@ -122,10 +121,11 @@ fn check_and_apply_linkage( cx: &CodegenCx<'ll, 'tcx>, attrs: &CodegenFnAttrs, ty: Ty<'tcx>, - sym: LocalInternedString, + sym: Symbol, span: Span ) -> &'ll Value { let llty = cx.layout_of(ty).llvm_type(cx); + let sym = sym.as_str(); if let Some(linkage) = attrs.linkage { debug!("get_static: sym={} linkage={:?}", sym, linkage); @@ -221,7 +221,7 @@ impl CodegenCx<'ll, 'tcx> { def_id); let ty = instance.ty(self.tcx); - let sym = self.tcx.symbol_name(instance).as_str(); + let sym = self.tcx.symbol_name(instance).name.as_symbol(); debug!("get_static: sym={} instance={:?}", sym, instance); @@ -232,11 +232,12 @@ impl CodegenCx<'ll, 'tcx> { Node::Item(&hir::Item { ref attrs, span, node: hir::ItemKind::Static(..), .. }) => { - if self.get_declared_value(&sym[..]).is_some() { + let sym_str = sym.as_str(); + if self.get_declared_value(&sym_str).is_some() { span_bug!(span, "Conflicting symbol names for static?"); } - let g = self.define_global(&sym[..], llty).unwrap(); + let g = self.define_global(&sym_str, llty).unwrap(); if !self.tcx.is_reachable_non_generic(def_id) { unsafe { diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index a2aaaddf0931c..58ce97039099e 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -29,7 +29,7 @@ use std::cell::{Cell, RefCell}; use std::iter; use std::str; use std::sync::Arc; -use syntax::symbol::LocalInternedString; +use syntax::symbol::Symbol; use syntax::source_map::{DUMMY_SP, Span}; use crate::abi::Abi; @@ -52,7 +52,7 @@ pub struct CodegenCx<'ll, 'tcx> { pub vtables: RefCell, Option>), &'ll Value>>, /// Cache of constant strings, - pub const_cstr_cache: RefCell>, + pub const_cstr_cache: RefCell>, /// Reverse-direction for const ptrs cast from globals. /// Key is a Value holding a *T, diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 928532a1f4760..d0b607bd88ee4 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -2251,7 +2251,7 @@ pub fn create_global_var_metadata( None } else { let linkage_name = mangled_name_of_instance(cx, Instance::mono(tcx, def_id)); - Some(SmallCStr::new(&linkage_name.as_str())) + Some(SmallCStr::new(&linkage_name.name.as_str())) }; let global_align = cx.align_of(variable_type); diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 548ea0b1036e0..cad2bcdc05fc9 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -290,7 +290,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { let scope_line = span_start(self, span).line; let function_name = CString::new(name).unwrap(); - let linkage_name = SmallCStr::new(&linkage_name.as_str()); + let linkage_name = SmallCStr::new(&linkage_name.name.as_str()); let mut flags = DIFlags::FlagPrototyped; diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index 2d9220f897cff..7e700e6819426 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -121,7 +121,7 @@ fn reachable_non_generics_provider( }) .map(|def_id| { let export_level = if special_runtime_crate { - let name = tcx.symbol_name(Instance::mono(tcx, def_id)).as_str(); + let name = tcx.symbol_name(Instance::mono(tcx, def_id)).name.as_str(); // We can probably do better here by just ensuring that // it has hidden visibility rather than public // visibility, as this is primarily here to ensure it's diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index d2a7571fde1e2..134c321456b6c 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -14,7 +14,7 @@ use crate::traits::*; use std::borrow::Cow; -use syntax::symbol::LocalInternedString; +use syntax::symbol::Symbol; use syntax_pos::Pos; use super::{FunctionCx, LocalRef}; @@ -397,7 +397,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // Get the location information. let loc = bx.sess().source_map().lookup_char_pos(span.lo()); - let filename = LocalInternedString::intern(&loc.file.name.to_string()); + let filename = Symbol::intern(&loc.file.name.to_string()); let line = bx.const_u32(loc.line as u32); let col = bx.const_u32(loc.col.to_usize() as u32 + 1); @@ -418,8 +418,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { vec![file_line_col, index, len]) } _ => { - let str = msg.description(); - let msg_str = LocalInternedString::intern(str); + let msg_str = Symbol::intern(msg.description()); let msg_file_line_col = bx.static_panic_msg( Some(msg_str), filename, @@ -531,7 +530,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let layout = bx.layout_of(ty); if layout.abi.is_uninhabited() { let loc = bx.sess().source_map().lookup_char_pos(span.lo()); - let filename = LocalInternedString::intern(&loc.file.name.to_string()); + let filename = Symbol::intern(&loc.file.name.to_string()); let line = bx.const_u32(loc.line as u32); let col = bx.const_u32(loc.col.to_usize() as u32 + 1); @@ -539,7 +538,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { "Attempted to instantiate uninhabited type {}", ty ); - let msg_str = LocalInternedString::intern(&str); + let msg_str = Symbol::intern(&str); let msg_file_line_col = bx.static_panic_msg( Some(msg_str), filename, diff --git a/src/librustc_codegen_ssa/mono_item.rs b/src/librustc_codegen_ssa/mono_item.rs index 4446f1a3a5ce2..5801963c101ef 100644 --- a/src/librustc_codegen_ssa/mono_item.rs +++ b/src/librustc_codegen_ssa/mono_item.rs @@ -58,7 +58,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { self.to_raw_string(), cx.codegen_unit().name()); - let symbol_name = self.symbol_name(cx.tcx()).as_str(); + let symbol_name = self.symbol_name(cx.tcx()).name.as_str(); debug!("symbol {}", &symbol_name); diff --git a/src/librustc_codegen_ssa/traits/statics.rs b/src/librustc_codegen_ssa/traits/statics.rs index 6983311d797dc..73c4c05397917 100644 --- a/src/librustc_codegen_ssa/traits/statics.rs +++ b/src/librustc_codegen_ssa/traits/statics.rs @@ -1,5 +1,5 @@ use super::BackendTypes; -use syntax_pos::symbol::LocalInternedString; +use syntax_pos::symbol::Symbol; use rustc::hir::def_id::DefId; use rustc::ty::layout::Align; @@ -12,8 +12,8 @@ pub trait StaticBuilderMethods: BackendTypes { fn get_static(&mut self, def_id: DefId) -> Self::Value; fn static_panic_msg( &mut self, - msg: Option, - filename: LocalInternedString, + msg: Option, + filename: Symbol, line: Self::Value, col: Self::Value, kind: &str, diff --git a/src/librustc_codegen_utils/symbol_names_test.rs b/src/librustc_codegen_utils/symbol_names_test.rs index f562744dbe753..51269be4e9f40 100644 --- a/src/librustc_codegen_utils/symbol_names_test.rs +++ b/src/librustc_codegen_utils/symbol_names_test.rs @@ -40,7 +40,7 @@ impl SymbolNamesTest<'tcx> { let instance = Instance::mono(tcx, def_id); let mangled = self.tcx.symbol_name(instance); tcx.sess.span_err(attr.span, &format!("symbol-name({})", mangled)); - if let Ok(demangling) = rustc_demangle::try_demangle(&mangled.as_str()) { + if let Ok(demangling) = rustc_demangle::try_demangle(&mangled.name.as_str()) { tcx.sess.span_err(attr.span, &format!("demangling({})", demangling)); tcx.sess.span_err(attr.span, &format!("demangling-alt({:#})", demangling)); } diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 90e467713968b..39c0698aeec9f 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -398,18 +398,37 @@ impl UnusedParens { } } - fn check_unused_parens_pat(&self, - cx: &EarlyContext<'_>, - value: &ast::Pat, - msg: &str) { - if let ast::PatKind::Paren(_) = value.node { + fn check_unused_parens_pat( + &self, + cx: &EarlyContext<'_>, + value: &ast::Pat, + avoid_or: bool, + avoid_mut: bool, + ) { + use ast::{PatKind, BindingMode::ByValue, Mutability::Mutable}; + + if let PatKind::Paren(inner) = &value.node { + match inner.node { + // The lint visitor will visit each subpattern of `p`. We do not want to lint + // any range pattern no matter where it occurs in the pattern. For something like + // `&(a..=b)`, there is a recursive `check_pat` on `a` and `b`, but we will assume + // that if there are unnecessary parens they serve a purpose of readability. + PatKind::Range(..) => return, + // Avoid `p0 | .. | pn` if we should. + PatKind::Or(..) if avoid_or => return, + // Avoid `mut x` and `mut x @ p` if we should: + PatKind::Ident(ByValue(Mutable), ..) if avoid_mut => return, + // Otherwise proceed with linting. + _ => {} + } + let pattern_text = if let Ok(snippet) = cx.sess().source_map() .span_to_snippet(value.span) { snippet } else { pprust::pat_to_string(value) }; - Self::remove_outer_parens(cx, value.span, &pattern_text, msg, (false, false)); + Self::remove_outer_parens(cx, value.span, &pattern_text, "pattern", (false, false)); } } @@ -474,6 +493,13 @@ impl EarlyLintPass for UnusedParens { fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) { use syntax::ast::ExprKind::*; let (value, msg, followed_by_block, left_pos, right_pos) = match e.node { + Let(ref pats, ..) => { + for p in pats { + self.check_unused_parens_pat(cx, p, false, false); + } + return; + } + If(ref cond, ref block, ..) => { let left = e.span.lo() + syntax_pos::BytePos(2); let right = block.span.lo(); @@ -486,7 +512,8 @@ impl EarlyLintPass for UnusedParens { (cond, "`while` condition", true, Some(left), Some(right)) }, - ForLoop(_, ref cond, ref block, ..) => { + ForLoop(ref pat, ref cond, ref block, ..) => { + self.check_unused_parens_pat(cx, pat, false, false); (cond, "`for` head expression", true, None, Some(block.span.lo())) } @@ -531,26 +558,46 @@ impl EarlyLintPass for UnusedParens { } fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat) { - use ast::PatKind::{Paren, Range}; - // The lint visitor will visit each subpattern of `p`. We do not want to lint any range - // pattern no matter where it occurs in the pattern. For something like `&(a..=b)`, there - // is a recursive `check_pat` on `a` and `b`, but we will assume that if there are - // unnecessary parens they serve a purpose of readability. - if let Paren(ref pat) = p.node { - match pat.node { - Range(..) => {} - _ => self.check_unused_parens_pat(cx, &p, "pattern") - } + use ast::{PatKind::*, Mutability}; + match &p.node { + // Do not lint on `(..)` as that will result in the other arms being useless. + Paren(_) + // The other cases do not contain sub-patterns. + | Wild | Rest | Lit(..) | Mac(..) | Range(..) | Ident(.., None) | Path(..) => return, + // These are list-like patterns; parens can always be removed. + TupleStruct(_, ps) | Tuple(ps) | Slice(ps) | Or(ps) => for p in ps { + self.check_unused_parens_pat(cx, p, false, false); + }, + Struct(_, fps, _) => for f in fps { + self.check_unused_parens_pat(cx, &f.pat, false, false); + }, + // Avoid linting on `i @ (p0 | .. | pn)` and `box (p0 | .. | pn)`, #64106. + Ident(.., Some(p)) | Box(p) => self.check_unused_parens_pat(cx, p, true, false), + // Avoid linting on `&(mut x)` as `&mut x` has a different meaning, #55342. + // Also avoid linting on `& mut? (p0 | .. | pn)`, #64106. + Ref(p, m) => self.check_unused_parens_pat(cx, p, true, *m == Mutability::Immutable), } } fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) { if let ast::StmtKind::Local(ref local) = s.node { + self.check_unused_parens_pat(cx, &local.pat, false, false); + if let Some(ref value) = local.init { self.check_unused_parens_expr(cx, &value, "assigned value", false, None, None); } } } + + fn check_param(&mut self, cx: &EarlyContext<'_>, param: &ast::Param) { + self.check_unused_parens_pat(cx, ¶m.pat, true, false); + } + + fn check_arm(&mut self, cx: &EarlyContext<'_>, arm: &ast::Arm) { + for p in &arm.pats { + self.check_unused_parens_pat(cx, p, false, false); + } + } } declare_lint! { diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index 40ddd65164290..62a3757757b80 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -54,7 +54,7 @@ fn main() { // LLVM are compiled the same way, but for us that's typically the case. // // We *want* detect this cross compiling situation by asking llvm-config - // what it's host-target is. If that's not the TARGET, then we're cross + // what its host-target is. If that's not the TARGET, then we're cross // compiling. Unfortunately `llvm-config` seems either be buggy, or we're // misconfiguring it, because the `i686-pc-windows-gnu` build of LLVM will // report itself with a `--host-target` of `x86_64-pc-windows-gnu`. This @@ -62,7 +62,7 @@ fn main() { // havoc ensues. // // In any case, if we're cross compiling, this generally just means that we - // can't trust all the output of llvm-config becaues it might be targeted + // can't trust all the output of llvm-config because it might be targeted // for the host rather than the target. As a result a bunch of blocks below // are gated on `if !is_crossed` let target = env::var("TARGET").expect("TARGET was not set"); @@ -166,7 +166,7 @@ fn main() { let (llvm_kind, llvm_link_arg) = detect_llvm_link(); - // Link in all LLVM libraries, if we're uwring the "wrong" llvm-config then + // Link in all LLVM libraries, if we're using the "wrong" llvm-config then // we don't pick up system libs because unfortunately they're for the host // of llvm-config, not the target that we're attempting to link. let mut cmd = Command::new(&llvm_config); diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 251d4b727c754..9f25e98052ec4 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -336,7 +336,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let local = &self.body.local_decls[local_index]; match local.name { Some(name) if !local.from_compiler_desugaring() => { - buf.push_str(name.as_str().get()); + buf.push_str(&name.as_str()); Ok(()) } _ => Err(()), diff --git a/src/librustc_mir/borrow_check/path_utils.rs b/src/librustc_mir/borrow_check/path_utils.rs index 43a012e1494f8..bac08090817d9 100644 --- a/src/librustc_mir/borrow_check/path_utils.rs +++ b/src/librustc_mir/borrow_check/path_utils.rs @@ -3,7 +3,7 @@ use crate::borrow_check::places_conflict; use crate::borrow_check::AccessDepth; use crate::dataflow::indexes::BorrowIndex; use rustc::mir::{BasicBlock, Location, Body, Place, PlaceBase}; -use rustc::mir::{ProjectionElem, BorrowKind}; +use rustc::mir::BorrowKind; use rustc::ty::{self, TyCtxt}; use rustc_data_structures::graph::dominators::Dominators; @@ -133,20 +133,11 @@ pub(super) fn is_active<'tcx>( /// Determines if a given borrow is borrowing local data /// This is called for all Yield statements on movable generators pub(super) fn borrow_of_local_data(place: &Place<'_>) -> bool { - place.iterate(|place_base, place_projection| { - match place_base { - PlaceBase::Static(..) => return false, - PlaceBase::Local(..) => {}, - } - - for proj in place_projection { - // Reborrow of already borrowed data is ignored - // Any errors will be caught on the initial borrow - if proj.elem == ProjectionElem::Deref { - return false; - } - } + match place.base { + PlaceBase::Static(_) => false, - true - }) + // Reborrow of already borrowed data is ignored + // Any errors will be caught on the initial borrow + PlaceBase::Local(_) => !place.is_indirect(), + } } diff --git a/src/librustc_mir/dataflow/impls/borrowed_locals.rs b/src/librustc_mir/dataflow/impls/borrowed_locals.rs index d94ebdbae24ae..1c43a553cc3c9 100644 --- a/src/librustc_mir/dataflow/impls/borrowed_locals.rs +++ b/src/librustc_mir/dataflow/impls/borrowed_locals.rs @@ -93,19 +93,10 @@ struct BorrowedLocalsVisitor<'gk> { } fn find_local(place: &Place<'_>) -> Option { - place.iterate(|place_base, place_projection| { - for proj in place_projection { - if proj.elem == ProjectionElem::Deref { - return None; - } - } - - if let PlaceBase::Local(local) = place_base { - Some(*local) - } else { - None - } - }) + match place.base { + PlaceBase::Local(local) if !place.is_indirect() => Some(local), + _ => None, + } } impl<'tcx> Visitor<'tcx> for BorrowedLocalsVisitor<'_> { diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index ad9db4e0aa8d8..c193911247e2b 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -777,7 +777,7 @@ where debug!("CodegenUnit {}:", cgu.name()); for (mono_item, linkage) in cgu.items() { - let symbol_name = mono_item.symbol_name(tcx).as_str(); + let symbol_name = mono_item.symbol_name(tcx).name.as_str(); let symbol_hash_start = symbol_name.rfind('h'); let symbol_hash = symbol_hash_start.map(|i| &symbol_name[i ..]) .unwrap_or(""); diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index fbaa9904d8303..9644815f805d9 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -19,7 +19,7 @@ use crate::astconv::AstConv as _; use errors::{Applicability, DiagnosticBuilder}; use syntax::ast; -use syntax::symbol::{Symbol, LocalInternedString, kw, sym}; +use syntax::symbol::{Symbol, kw, sym}; use syntax::source_map::Span; use syntax::util::lev_distance::find_best_match_for_name; use rustc::hir; @@ -1244,7 +1244,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } _ => { // prevent all specified fields from being suggested - let skip_fields = skip_fields.iter().map(|ref x| x.ident.as_str()); + let skip_fields = skip_fields.iter().map(|ref x| x.ident.name); if let Some(field_name) = Self::suggest_field_name( variant, &field.ident.as_str(), @@ -1288,11 +1288,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Return an hint about the closest match in field names fn suggest_field_name(variant: &'tcx ty::VariantDef, field: &str, - skip: Vec) + skip: Vec) -> Option { let names = variant.fields.iter().filter_map(|field| { // ignore already set fields and private fields from non-local crates - if skip.iter().any(|x| *x == field.ident.as_str()) || + if skip.iter().any(|&x| x == field.ident.name) || (!variant.def_id.is_local() && field.vis != Visibility::Public) { None diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 16903304a1427..b3ce92cb7d922 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1420,8 +1420,8 @@ fn check_opaque_for_cycles<'tcx>( tcx.sess, span, E0733, "recursion in an `async fn` requires boxing", ) - .span_label(span, "an `async fn` cannot invoke itself directly") - .note("a recursive `async fn` must be rewritten to return a boxed future.") + .span_label(span, "recursive `async fn`") + .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`.") .emit(); } else { let mut err = struct_span_err!( diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index f95b3e44bf0f7..ac8ee43dd0801 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -762,19 +762,19 @@ fn check_opaque_types<'fcx, 'tcx>( substituted_predicates } +const HELP_FOR_SELF_TYPE: &str = + "consider changing to `self`, `&self`, `&mut self`, `self: Box`, \ + `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one \ + of the previous types except `Self`)"; + fn check_method_receiver<'fcx, 'tcx>( fcx: &FnCtxt<'fcx, 'tcx>, method_sig: &hir::MethodSig, method: &ty::AssocItem, self_ty: Ty<'tcx>, ) { - const HELP_FOR_SELF_TYPE: &str = - "consider changing to `self`, `&self`, `&mut self`, `self: Box`, \ - `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one \ - of the previous types except `Self`)"; // Check that the method has a valid receiver type, given the type `Self`. - debug!("check_method_receiver({:?}, self_ty={:?})", - method, self_ty); + debug!("check_method_receiver({:?}, self_ty={:?})", method, self_ty); if !method.method_has_self_argument { return; @@ -805,12 +805,7 @@ fn check_method_receiver<'fcx, 'tcx>( if fcx.tcx.features().arbitrary_self_types { if !receiver_is_valid(fcx, span, receiver_ty, self_ty, true) { // Report error; `arbitrary_self_types` was enabled. - fcx.tcx.sess.diagnostic().mut_span_err( - span, &format!("invalid method receiver type: {:?}", receiver_ty) - ).note("type of `self` must be `Self` or a type that dereferences to it") - .help(HELP_FOR_SELF_TYPE) - .code(DiagnosticId::Error("E0307".into())) - .emit(); + e0307(fcx, span, receiver_ty); } } else { if !receiver_is_valid(fcx, span, receiver_ty, self_ty, false) { @@ -830,17 +825,22 @@ fn check_method_receiver<'fcx, 'tcx>( .emit(); } else { // Report error; would not have worked with `arbitrary_self_types`. - fcx.tcx.sess.diagnostic().mut_span_err( - span, &format!("invalid method receiver type: {:?}", receiver_ty) - ).note("type must be `Self` or a type that dereferences to it") - .help(HELP_FOR_SELF_TYPE) - .code(DiagnosticId::Error("E0307".into())) - .emit(); + e0307(fcx, span, receiver_ty); } } } } +fn e0307(fcx: &FnCtxt<'fcx, 'tcx>, span: Span, receiver_ty: Ty<'_>) { + fcx.tcx.sess.diagnostic().mut_span_err( + span, + &format!("invalid `self` parameter type: {:?}", receiver_ty) + ).note("type of `self` must be `Self` or a type that dereferences to it") + .help(HELP_FOR_SELF_TYPE) + .code(DiagnosticId::Error("E0307".into())) + .emit(); +} + /// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If /// `arbitrary_self_types` is enabled, `receiver_ty` must transitively deref to `self_ty`, possibly /// through a `*const/mut T` raw pointer. If the feature is not enabled, the requirements are more diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs index b52183d4b1b56..093446d28533e 100644 --- a/src/librustc_typeck/error_codes.rs +++ b/src/librustc_typeck/error_codes.rs @@ -212,7 +212,7 @@ match string { E0033: r##" This error indicates that a pointer to a trait type cannot be implicitly dereferenced by a pattern. Every trait defines a type, but because the -size of trait implementors isn't fixed, this type has no compile-time size. +size of trait implementers isn't fixed, this type has no compile-time size. Therefore, all accesses to trait types must be through pointers. If you encounter this error you should try to avoid dereferencing the pointer. @@ -2425,6 +2425,87 @@ struct Bar { x: Foo } ``` "##, +E0307: r##" +This error indicates that the `self` parameter in a method has an invalid +"reciever type". + +Methods take a special first parameter, of which there are three variants: +`self`, `&self`, and `&mut self`. These are syntactic sugar for +`self: Self`, `self: &Self`, and `self: &mut Self` respectively. + +``` +# struct Foo; +trait Trait { + fn foo(&self); +// ^^^^^ `self` here is a reference to the receiver object +} + +impl Trait for Foo { + fn foo(&self) {} +// ^^^^^ the receiver type is `&Foo` +} +``` + +The type `Self` acts as an alias to the type of the current trait +implementer, or "receiver type". Besides the already mentioned `Self`, +`&Self` and `&mut Self` valid receiver types, the following are also valid: +`self: Box`, `self: Rc`, `self: Arc`, and `self: Pin

` +(where P is one of the previous types except `Self`). Note that `Self` can +also be the underlying implementing type, like `Foo` in the following +example: + +``` +# struct Foo; +# trait Trait { +# fn foo(&self); +# } +impl Trait for Foo { + fn foo(self: &Foo) {} +} +``` + +E0307 will be emitted by the compiler when using an invalid reciver type, +like in the following example: + +```compile_fail,E0307 +# struct Foo; +# struct Bar; +# trait Trait { +# fn foo(&self); +# } +impl Trait for Foo { + fn foo(self: &Bar) {} +} +``` + +The nightly feature [Arbintrary self types][AST] extends the accepted +set of receiver types to also include any type that can dereference to +`Self`: + +``` +#![feature(arbitrary_self_types)] + +struct Foo; +struct Bar; + +// Because you can dereference `Bar` into `Foo`... +impl std::ops::Deref for Bar { + type Target = Foo; + + fn deref(&self) -> &Foo { + &Foo + } +} + +impl Foo { + fn foo(self: Bar) {} +// ^^^^^^^^^ ...it can be used as the receiver type +} +``` + +[AST]: https://doc.rust-lang.org/unstable-book/language-features/arbitrary-self-types.html +"##, + E0321: r##" A cross-crate opt-out trait was implemented on something which wasn't a struct or enum type. Erroneous code example: @@ -4851,7 +4932,6 @@ register_diagnostics! { // E0247, // E0248, // value used as a type, now reported earlier during resolution as E0412 // E0249, - E0307, // invalid method `self` type // E0319, // trait impls for defaulted traits allowed just for structs/enums // E0372, // coherence not object safe E0377, // the trait `CoerceUnsized` may only be implemented for a coercion diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 5060f368229bb..0386dbd490d03 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -371,6 +371,14 @@ where loop { if g.len == g.buf.len() { unsafe { + // FIXME(danielhenrymantilla): #42788 + // + // - This creates a (mut) reference to a slice of + // _uninitialized_ integers, which is **undefined behavior** + // + // - Only the standard library gets to soundly "ignore" this, + // based on its privileged knowledge of unstable rustc + // internals; g.buf.reserve(reservation_size(r)); let capacity = g.buf.capacity(); g.buf.set_len(capacity); diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index c3882bacf87eb..71050b0dcd1f5 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -244,7 +244,6 @@ #![feature(cfg_target_has_atomic)] #![feature(cfg_target_thread_local)] #![feature(char_error_internals)] -#![feature(checked_duration_since)] #![feature(clamp)] #![feature(compiler_builtins_lib)] #![feature(concat_idents)] diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 98371b9ba3d7e..d59085cd44a6f 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -221,7 +221,6 @@ impl Instant { /// # Examples /// /// ```no_run - /// #![feature(checked_duration_since)] /// use std::time::{Duration, Instant}; /// use std::thread::sleep; /// @@ -231,7 +230,7 @@ impl Instant { /// println!("{:?}", new_now.checked_duration_since(now)); /// println!("{:?}", now.checked_duration_since(new_now)); // None /// ``` - #[unstable(feature = "checked_duration_since", issue = "58402")] + #[stable(feature = "checked_duration_since", since = "1.39.0")] pub fn checked_duration_since(&self, earlier: Instant) -> Option { self.0.checked_sub_instant(&earlier.0) } @@ -242,7 +241,6 @@ impl Instant { /// # Examples /// /// ```no_run - /// #![feature(checked_duration_since)] /// use std::time::{Duration, Instant}; /// use std::thread::sleep; /// @@ -252,7 +250,7 @@ impl Instant { /// println!("{:?}", new_now.saturating_duration_since(now)); /// println!("{:?}", now.saturating_duration_since(new_now)); // 0ns /// ``` - #[unstable(feature = "checked_duration_since", issue = "58402")] + #[stable(feature = "checked_duration_since", since = "1.39.0")] pub fn saturating_duration_since(&self, earlier: Instant) -> Duration { self.checked_duration_since(earlier).unwrap_or(Duration::new(0, 0)) } diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs index 5b9f0f1df6718..e502a08f4b253 100644 --- a/src/libsyntax/parse/parser/expr.rs +++ b/src/libsyntax/parse/parser/expr.rs @@ -889,6 +889,36 @@ impl<'a> Parser<'a> { hi = path.span; return Ok(self.mk_expr(lo.to(hi), ExprKind::Path(Some(qself), path), attrs)); } + if self.token.is_path_start() { + let path = self.parse_path(PathStyle::Expr)?; + + // `!`, as an operator, is prefix, so we know this isn't that + if self.eat(&token::Not) { + // MACRO INVOCATION expression + let (delim, tts) = self.expect_delimited_token_tree()?; + hi = self.prev_span; + ex = ExprKind::Mac(Mac { + path, + tts, + delim, + span: lo.to(hi), + prior_type_ascription: self.last_type_ascription, + }); + } else if self.check(&token::OpenDelim(token::Brace)) { + if let Some(expr) = self.maybe_parse_struct_expr(lo, &path, &attrs) { + return expr; + } else { + hi = path.span; + ex = ExprKind::Path(None, path); + } + } else { + hi = path.span; + ex = ExprKind::Path(None, path); + } + + let expr = self.mk_expr(lo.to(hi), ex, attrs); + return self.maybe_recover_from_bad_qpath(expr, true); + } if self.check_keyword(kw::Move) || self.check_keyword(kw::Static) { return self.parse_lambda_expr(attrs); } @@ -1007,32 +1037,6 @@ impl<'a> Parser<'a> { let (await_hi, e_kind) = self.parse_incorrect_await_syntax(lo, self.prev_span)?; hi = await_hi; ex = e_kind; - } else if self.token.is_path_start() { - let path = self.parse_path(PathStyle::Expr)?; - - // `!`, as an operator, is prefix, so we know this isn't that - if self.eat(&token::Not) { - // MACRO INVOCATION expression - let (delim, tts) = self.expect_delimited_token_tree()?; - hi = self.prev_span; - ex = ExprKind::Mac(Mac { - path, - tts, - delim, - span: lo.to(hi), - prior_type_ascription: self.last_type_ascription, - }); - } else if self.check(&token::OpenDelim(token::Brace)) { - if let Some(expr) = self.maybe_parse_struct_expr(lo, &path, &attrs) { - return expr; - } else { - hi = path.span; - ex = ExprKind::Path(None, path); - } - } else { - hi = path.span; - ex = ExprKind::Path(None, path); - } } else { if !self.unclosed_delims.is_empty() && self.check(&token::Semi) { // Don't complain about bare semicolons after unclosed braces diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index f44716e013ec8..3a4dc1f5a096b 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -818,10 +818,14 @@ impl Ident { with_interner(|interner| interner.is_gensymed(self.name)) } + /// Convert the name to a `LocalInternedString`. This is a slowish + /// operation because it requires locking the symbol interner. pub fn as_str(self) -> LocalInternedString { self.name.as_str() } + /// Convert the name to an `InternedString`. This is a slowish operation + /// because it requires locking the symbol interner. pub fn as_interned_str(self) -> InternedString { self.name.as_interned_str() } @@ -916,6 +920,25 @@ impl Symbol { with_interner(|interner| interner.intern(string)) } + /// Access the symbol's chars. This is a slowish operation because it + /// requires locking the symbol interner. + pub fn with R, R>(self, f: F) -> R { + with_interner(|interner| { + f(interner.get(self)) + }) + } + + /// Access two symbols' chars. This is a slowish operation because it + /// requires locking the symbol interner, but it is faster than calling + /// `with()` twice. + fn with2 R, R>(self, other: Symbol, f: F) -> R { + with_interner(|interner| { + f(interner.get(self), interner.get(other)) + }) + } + + /// Convert to a `LocalInternedString`. This is a slowish operation because + /// it requires locking the symbol interner. pub fn as_str(self) -> LocalInternedString { with_interner(|interner| unsafe { LocalInternedString { @@ -924,6 +947,8 @@ impl Symbol { }) } + /// Convert to an `InternedString`. This is a slowish operation because it + /// requires locking the symbol interner. pub fn as_interned_str(self) -> InternedString { with_interner(|interner| InternedString { symbol: interner.interned(self) @@ -1152,39 +1177,11 @@ fn with_interner T>(f: F) -> T { // FIXME: ensure that the interner outlives any thread which uses // `LocalInternedString`, by creating a new thread right after constructing the // interner. -#[derive(Clone, Copy, Hash, PartialOrd, Eq, Ord)] +#[derive(Clone, Copy, Eq, PartialOrd, Ord)] pub struct LocalInternedString { string: &'static str, } -impl LocalInternedString { - /// Maps a string to its interned representation. - pub fn intern(string: &str) -> Self { - let string = with_interner(|interner| { - let symbol = interner.intern(string); - interner.strings[symbol.0.as_usize()] - }); - LocalInternedString { - string: unsafe { std::mem::transmute::<&str, &str>(string) } - } - } - - pub fn as_interned_str(self) -> InternedString { - InternedString { - symbol: Symbol::intern(self.string) - } - } - - #[inline] - pub fn get(&self) -> &str { - // This returns a valid string since we ensure that `self` outlives the interner - // by creating the interner on a thread which outlives threads which can access it. - // This type cannot move to a thread which outlives the interner since it does - // not implement Send. - self.string - } -} - impl std::convert::AsRef for LocalInternedString where str: std::convert::AsRef @@ -1246,18 +1243,6 @@ impl fmt::Display for LocalInternedString { } } -impl Decodable for LocalInternedString { - fn decode(d: &mut D) -> Result { - Ok(LocalInternedString::intern(&d.read_str()?)) - } -} - -impl Encodable for LocalInternedString { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_str(self.string) - } -} - /// An alternative to `Symbol` that is focused on string contents. It has two /// main differences to `Symbol`. /// @@ -1285,28 +1270,19 @@ impl InternedString { } pub fn with R, R>(self, f: F) -> R { - let str = with_interner(|interner| { - interner.get(self.symbol) as *const str - }); - // This is safe because the interner keeps string alive until it is dropped. - // We can access it because we know the interner is still alive since we use a - // scoped thread local to access it, and it was alive at the beginning of this scope - unsafe { f(&*str) } + self.symbol.with(f) } fn with2 R, R>(self, other: &InternedString, f: F) -> R { - let (self_str, other_str) = with_interner(|interner| { - (interner.get(self.symbol) as *const str, - interner.get(other.symbol) as *const str) - }); - // This is safe for the same reason that `with` is safe. - unsafe { f(&*self_str, &*other_str) } + self.symbol.with2(other.symbol, f) } pub fn as_symbol(self) -> Symbol { self.symbol } + /// Convert to a `LocalInternedString`. This is a slowish operation because it + /// requires locking the symbol interner. pub fn as_str(self) -> LocalInternedString { self.symbol.as_str() } diff --git a/src/test/ui/associated-const/associated-const-in-trait.stderr b/src/test/ui/associated-const/associated-const-in-trait.stderr index dff268a55c909..a5d7fc5b70246 100644 --- a/src/test/ui/associated-const/associated-const-in-trait.stderr +++ b/src/test/ui/associated-const/associated-const-in-trait.stderr @@ -1,10 +1,11 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/associated-const-in-trait.rs:9:6 | +LL | const N: usize; + | - the trait cannot contain associated consts like `N` +... LL | impl dyn Trait { | ^^^^^^^^^ the trait `Trait` cannot be made into an object - | - = note: the trait cannot contain associated consts like `N` error: aborting due to previous error diff --git a/src/test/ui/async-await/mutually-recursive-async-impl-trait-type.rs b/src/test/ui/async-await/mutually-recursive-async-impl-trait-type.rs new file mode 100644 index 0000000000000..bb2a61f03ce1f --- /dev/null +++ b/src/test/ui/async-await/mutually-recursive-async-impl-trait-type.rs @@ -0,0 +1,13 @@ +// edition:2018 +// Test that impl trait does not allow creating recursive types that are +// otherwise forbidden when using `async` and `await`. + +async fn rec_1() { //~ ERROR recursion in an `async fn` + rec_2().await; +} + +async fn rec_2() { //~ ERROR recursion in an `async fn` + rec_1().await; +} + +fn main() {} diff --git a/src/test/ui/async-await/mutually-recursive-async-impl-trait-type.stderr b/src/test/ui/async-await/mutually-recursive-async-impl-trait-type.stderr new file mode 100644 index 0000000000000..9249308936e54 --- /dev/null +++ b/src/test/ui/async-await/mutually-recursive-async-impl-trait-type.stderr @@ -0,0 +1,19 @@ +error[E0733]: recursion in an `async fn` requires boxing + --> $DIR/mutually-recursive-async-impl-trait-type.rs:5:18 + | +LL | async fn rec_1() { + | ^ recursive `async fn` + | + = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`. + +error[E0733]: recursion in an `async fn` requires boxing + --> $DIR/mutually-recursive-async-impl-trait-type.rs:9:18 + | +LL | async fn rec_2() { + | ^ recursive `async fn` + | + = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`. + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0733`. diff --git a/src/test/ui/async-await/recursive-async-impl-trait-type.stderr b/src/test/ui/async-await/recursive-async-impl-trait-type.stderr index 8781a9c444d0a..9ee014021804e 100644 --- a/src/test/ui/async-await/recursive-async-impl-trait-type.stderr +++ b/src/test/ui/async-await/recursive-async-impl-trait-type.stderr @@ -2,9 +2,9 @@ error[E0733]: recursion in an `async fn` requires boxing --> $DIR/recursive-async-impl-trait-type.rs:5:40 | LL | async fn recursive_async_function() -> () { - | ^^ an `async fn` cannot invoke itself directly + | ^^ recursive `async fn` | - = note: a recursive `async fn` must be rewritten to return a boxed future. + = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`. error: aborting due to previous error diff --git a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.old.stderr b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.old.stderr index c38d7456a9952..18a7cea95bdb9 100644 --- a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.old.stderr +++ b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.old.stderr @@ -1,10 +1,10 @@ error[E0038]: the trait `NotObjectSafe` cannot be made into an object --> $DIR/coherence-impl-trait-for-trait-object-safe.rs:11:6 | +LL | trait NotObjectSafe { fn eq(&self, other: Self); } + | -- method `eq` references the `Self` type in its parameters or return type LL | impl NotObjectSafe for dyn NotObjectSafe { } | ^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object - | - = note: method `eq` references the `Self` type in its arguments or return type error: aborting due to previous error diff --git a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.re.stderr b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.re.stderr index c38d7456a9952..18a7cea95bdb9 100644 --- a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.re.stderr +++ b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.re.stderr @@ -1,10 +1,10 @@ error[E0038]: the trait `NotObjectSafe` cannot be made into an object --> $DIR/coherence-impl-trait-for-trait-object-safe.rs:11:6 | +LL | trait NotObjectSafe { fn eq(&self, other: Self); } + | -- method `eq` references the `Self` type in its parameters or return type LL | impl NotObjectSafe for dyn NotObjectSafe { } | ^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object - | - = note: method `eq` references the `Self` type in its arguments or return type error: aborting due to previous error diff --git a/src/test/ui/did_you_mean/issue-40006.stderr b/src/test/ui/did_you_mean/issue-40006.stderr index 87e48cd1e1cd9..5b384045a486a 100644 --- a/src/test/ui/did_you_mean/issue-40006.stderr +++ b/src/test/ui/did_you_mean/issue-40006.stderr @@ -61,8 +61,9 @@ error[E0038]: the trait `X` cannot be made into an object | LL | impl dyn X { | ^^^^^ the trait `X` cannot be made into an object - | - = note: method `xxx` has no receiver +... +LL | fn xxx() { ### } + | --- associated function `xxx` has no `self` parameter error: aborting due to 9 previous errors diff --git a/src/test/ui/error-codes/E0033-teach.rs b/src/test/ui/error-codes/E0033-teach.rs index 6a27b07fa8b77..1943965139423 100644 --- a/src/test/ui/error-codes/E0033-teach.rs +++ b/src/test/ui/error-codes/E0033-teach.rs @@ -1,14 +1,13 @@ // compile-flags: -Z teach trait SomeTrait { - fn foo(); + fn foo(); //~ associated function `foo` has no `self` parameter } fn main() { let trait_obj: &dyn SomeTrait = SomeTrait; //~^ ERROR expected value, found trait `SomeTrait` //~| ERROR E0038 - //~| method `foo` has no receiver let &invalid = trait_obj; //~^ ERROR E0033 diff --git a/src/test/ui/error-codes/E0033-teach.stderr b/src/test/ui/error-codes/E0033-teach.stderr index fb630de7fc147..80f3d4441bd9f 100644 --- a/src/test/ui/error-codes/E0033-teach.stderr +++ b/src/test/ui/error-codes/E0033-teach.stderr @@ -7,13 +7,14 @@ LL | let trait_obj: &dyn SomeTrait = SomeTrait; error[E0038]: the trait `SomeTrait` cannot be made into an object --> $DIR/E0033-teach.rs:8:20 | +LL | fn foo(); + | --- associated function `foo` has no `self` parameter +... LL | let trait_obj: &dyn SomeTrait = SomeTrait; | ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object - | - = note: method `foo` has no receiver error[E0033]: type `&dyn SomeTrait` cannot be dereferenced - --> $DIR/E0033-teach.rs:13:9 + --> $DIR/E0033-teach.rs:12:9 | LL | let &invalid = trait_obj; | ^^^^^^^^ type `&dyn SomeTrait` cannot be dereferenced diff --git a/src/test/ui/error-codes/E0033.rs b/src/test/ui/error-codes/E0033.rs index 582600e110ba0..e5f0530f45ff8 100644 --- a/src/test/ui/error-codes/E0033.rs +++ b/src/test/ui/error-codes/E0033.rs @@ -1,12 +1,11 @@ trait SomeTrait { - fn foo(); + fn foo(); //~ associated function `foo` has no `self` parameter } fn main() { let trait_obj: &dyn SomeTrait = SomeTrait; //~^ ERROR expected value, found trait `SomeTrait` //~| ERROR E0038 - //~| method `foo` has no receiver let &invalid = trait_obj; //~^ ERROR E0033 diff --git a/src/test/ui/error-codes/E0033.stderr b/src/test/ui/error-codes/E0033.stderr index fe9f45d86a6a0..c2843796cc851 100644 --- a/src/test/ui/error-codes/E0033.stderr +++ b/src/test/ui/error-codes/E0033.stderr @@ -7,13 +7,14 @@ LL | let trait_obj: &dyn SomeTrait = SomeTrait; error[E0038]: the trait `SomeTrait` cannot be made into an object --> $DIR/E0033.rs:6:20 | +LL | fn foo(); + | --- associated function `foo` has no `self` parameter +... LL | let trait_obj: &dyn SomeTrait = SomeTrait; | ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object - | - = note: method `foo` has no receiver error[E0033]: type `&dyn SomeTrait` cannot be dereferenced - --> $DIR/E0033.rs:11:9 + --> $DIR/E0033.rs:10:9 | LL | let &invalid = trait_obj; | ^^^^^^^^ type `&dyn SomeTrait` cannot be dereferenced diff --git a/src/test/ui/error-codes/E0038.stderr b/src/test/ui/error-codes/E0038.stderr index e3d7593e42a71..5c4d6d53c4626 100644 --- a/src/test/ui/error-codes/E0038.stderr +++ b/src/test/ui/error-codes/E0038.stderr @@ -1,10 +1,11 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/E0038.rs:5:1 | +LL | fn foo(&self) -> Self; + | --- method `foo` references the `Self` type in its parameters or return type +... LL | fn call_foo(x: Box) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` cannot be made into an object - | - = note: method `foo` references the `Self` type in its arguments or return type error: aborting due to previous error diff --git a/src/test/ui/explicit/explicit-self-lifetime-mismatch.rs b/src/test/ui/explicit/explicit-self-lifetime-mismatch.rs index 82c64bcf6a767..9ab8e13893bc7 100644 --- a/src/test/ui/explicit/explicit-self-lifetime-mismatch.rs +++ b/src/test/ui/explicit/explicit-self-lifetime-mismatch.rs @@ -6,11 +6,11 @@ struct Foo<'a,'b> { impl<'a,'b> Foo<'a,'b> { fn bar(self: Foo<'b,'a> - //~^ ERROR mismatched method receiver + //~^ ERROR mismatched `self` parameter type //~| expected type `Foo<'a, 'b>` //~| found type `Foo<'b, 'a>` //~| lifetime mismatch - //~| ERROR mismatched method receiver + //~| ERROR mismatched `self` parameter type //~| expected type `Foo<'a, 'b>` //~| found type `Foo<'b, 'a>` //~| lifetime mismatch diff --git a/src/test/ui/explicit/explicit-self-lifetime-mismatch.stderr b/src/test/ui/explicit/explicit-self-lifetime-mismatch.stderr index e6f9eded9a4f3..4bf2d573d4f96 100644 --- a/src/test/ui/explicit/explicit-self-lifetime-mismatch.stderr +++ b/src/test/ui/explicit/explicit-self-lifetime-mismatch.stderr @@ -1,4 +1,4 @@ -error[E0308]: mismatched method receiver +error[E0308]: mismatched `self` parameter type --> $DIR/explicit-self-lifetime-mismatch.rs:8:12 | LL | Foo<'b,'a> @@ -17,7 +17,7 @@ note: ...does not necessarily outlive the lifetime 'a as defined on the impl at LL | impl<'a,'b> Foo<'a,'b> { | ^^ -error[E0308]: mismatched method receiver +error[E0308]: mismatched `self` parameter type --> $DIR/explicit-self-lifetime-mismatch.rs:8:12 | LL | Foo<'b,'a> diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type--through-non-recursize.rs b/src/test/ui/impl-trait/recursive-impl-trait-type--through-non-recursize.rs new file mode 100644 index 0000000000000..cfd9c0ec5b45b --- /dev/null +++ b/src/test/ui/impl-trait/recursive-impl-trait-type--through-non-recursize.rs @@ -0,0 +1,25 @@ +// Test that impl trait does not allow creating recursive types that are +// otherwise forbidden. Even when there's an opaque type in another crate +// hiding this. + +fn id(t: T) -> impl Sized { t } + +fn recursive_id() -> impl Sized { //~ ERROR opaque type expands to a recursive type + id(recursive_id2()) +} + +fn recursive_id2() -> impl Sized { //~ ERROR opaque type expands to a recursive type + id(recursive_id()) +} + +fn wrap(t: T) -> impl Sized { (t,) } + +fn recursive_wrap() -> impl Sized { //~ ERROR opaque type expands to a recursive type + wrap(recursive_wrap2()) +} + +fn recursive_wrap2() -> impl Sized { //~ ERROR opaque type expands to a recursive type + wrap(recursive_wrap()) +} + +fn main() {} diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type--through-non-recursize.stderr b/src/test/ui/impl-trait/recursive-impl-trait-type--through-non-recursize.stderr new file mode 100644 index 0000000000000..7572c6c1bf057 --- /dev/null +++ b/src/test/ui/impl-trait/recursive-impl-trait-type--through-non-recursize.stderr @@ -0,0 +1,35 @@ +error[E0720]: opaque type expands to a recursive type + --> $DIR/recursive-impl-trait-type--through-non-recursize.rs:7:22 + | +LL | fn recursive_id() -> impl Sized { + | ^^^^^^^^^^ expands to a recursive type + | + = note: type resolves to itself + +error[E0720]: opaque type expands to a recursive type + --> $DIR/recursive-impl-trait-type--through-non-recursize.rs:11:23 + | +LL | fn recursive_id2() -> impl Sized { + | ^^^^^^^^^^ expands to a recursive type + | + = note: type resolves to itself + +error[E0720]: opaque type expands to a recursive type + --> $DIR/recursive-impl-trait-type--through-non-recursize.rs:17:24 + | +LL | fn recursive_wrap() -> impl Sized { + | ^^^^^^^^^^ expands to a recursive type + | + = note: expanded type is `((impl Sized,),)` + +error[E0720]: opaque type expands to a recursive type + --> $DIR/recursive-impl-trait-type--through-non-recursize.rs:21:25 + | +LL | fn recursive_wrap2() -> impl Sized { + | ^^^^^^^^^^ expands to a recursive type + | + = note: expanded type is `((impl Sized,),)` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0720`. diff --git a/src/test/ui/issues/issue-17740.rs b/src/test/ui/issues/issue-17740.rs index c131b895849ae..b47568400c3b7 100644 --- a/src/test/ui/issues/issue-17740.rs +++ b/src/test/ui/issues/issue-17740.rs @@ -4,11 +4,11 @@ struct Foo<'a> { impl <'a> Foo<'a>{ fn bar(self: &mut Foo) { - //~^ mismatched method receiver + //~^ mismatched `self` parameter type //~| expected type `Foo<'a>` //~| found type `Foo<'_>` //~| lifetime mismatch - //~| mismatched method receiver + //~| mismatched `self` parameter type //~| expected type `Foo<'a>` //~| found type `Foo<'_>` //~| lifetime mismatch diff --git a/src/test/ui/issues/issue-17740.stderr b/src/test/ui/issues/issue-17740.stderr index 7ab0fa4d818b0..b8a0a0676319a 100644 --- a/src/test/ui/issues/issue-17740.stderr +++ b/src/test/ui/issues/issue-17740.stderr @@ -1,4 +1,4 @@ -error[E0308]: mismatched method receiver +error[E0308]: mismatched `self` parameter type --> $DIR/issue-17740.rs:6:18 | LL | fn bar(self: &mut Foo) { @@ -23,7 +23,7 @@ note: ...does not necessarily outlive the lifetime 'a as defined on the impl at LL | impl <'a> Foo<'a>{ | ^^ -error[E0308]: mismatched method receiver +error[E0308]: mismatched `self` parameter type --> $DIR/issue-17740.rs:6:18 | LL | fn bar(self: &mut Foo) { diff --git a/src/test/ui/issues/issue-17905-2.rs b/src/test/ui/issues/issue-17905-2.rs index 259d945018938..44279cc867b46 100644 --- a/src/test/ui/issues/issue-17905-2.rs +++ b/src/test/ui/issues/issue-17905-2.rs @@ -6,8 +6,8 @@ impl Pair< isize > { fn say(self: &Pair<&str, isize>) { -//~^ ERROR mismatched method receiver -//~| ERROR mismatched method receiver +//~^ ERROR mismatched `self` parameter type +//~| ERROR mismatched `self` parameter type println!("{:?}", self); } } diff --git a/src/test/ui/issues/issue-17905-2.stderr b/src/test/ui/issues/issue-17905-2.stderr index e3909e0c1253f..585bc9c14883b 100644 --- a/src/test/ui/issues/issue-17905-2.stderr +++ b/src/test/ui/issues/issue-17905-2.stderr @@ -1,4 +1,4 @@ -error[E0308]: mismatched method receiver +error[E0308]: mismatched `self` parameter type --> $DIR/issue-17905-2.rs:8:18 | LL | fn say(self: &Pair<&str, isize>) { @@ -21,7 +21,7 @@ note: ...does not necessarily outlive the lifetime '_ as defined on the impl at LL | &str, | ^ -error[E0308]: mismatched method receiver +error[E0308]: mismatched `self` parameter type --> $DIR/issue-17905-2.rs:8:18 | LL | fn say(self: &Pair<&str, isize>) { diff --git a/src/test/ui/issues/issue-18959.stderr b/src/test/ui/issues/issue-18959.stderr index 63c33b7f4472d..d5e7092801ecd 100644 --- a/src/test/ui/issues/issue-18959.stderr +++ b/src/test/ui/issues/issue-18959.stderr @@ -1,10 +1,11 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/issue-18959.rs:11:1 | +LL | pub trait Foo { fn foo(&self, ext_thing: &T); } + | --- method `foo` has generic type parameters +... LL | fn foo(b: &dyn Bar) { | ^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object - | - = note: method `foo` has generic type parameters error: aborting due to previous error diff --git a/src/test/ui/issues/issue-19380.stderr b/src/test/ui/issues/issue-19380.stderr index 27e3ff57bf9ab..92bfdf1f26e93 100644 --- a/src/test/ui/issues/issue-19380.stderr +++ b/src/test/ui/issues/issue-19380.stderr @@ -1,10 +1,11 @@ error[E0038]: the trait `Qiz` cannot be made into an object --> $DIR/issue-19380.rs:11:3 | +LL | fn qiz(); + | --- associated function `qiz` has no `self` parameter +... LL | foos: &'static [&'static (dyn Qiz + 'static)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Qiz` cannot be made into an object - | - = note: method `qiz` has no receiver error: aborting due to previous error diff --git a/src/test/ui/issues/issue-19538.stderr b/src/test/ui/issues/issue-19538.stderr index e5da0a9b0dac3..5415a45f7d621 100644 --- a/src/test/ui/issues/issue-19538.stderr +++ b/src/test/ui/issues/issue-19538.stderr @@ -1,18 +1,21 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/issue-19538.rs:17:15 | +LL | fn foo(&self, val: T); + | --- method `foo` has generic type parameters +... LL | let test: &mut dyn Bar = &mut thing; | ^^^^^^^^^^^^ the trait `Bar` cannot be made into an object - | - = note: method `foo` has generic type parameters error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/issue-19538.rs:17:30 | +LL | fn foo(&self, val: T); + | --- method `foo` has generic type parameters +... LL | let test: &mut dyn Bar = &mut thing; | ^^^^^^^^^^ the trait `Bar` cannot be made into an object | - = note: method `foo` has generic type parameters = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&mut dyn Bar>` for `&mut Thing` error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-50781.stderr b/src/test/ui/issues/issue-50781.stderr index c98f78c51ee5f..02475ea97e3d1 100644 --- a/src/test/ui/issues/issue-50781.stderr +++ b/src/test/ui/issues/issue-50781.stderr @@ -1,8 +1,8 @@ error: the trait `X` cannot be made into an object - --> $DIR/issue-50781.rs:6:5 + --> $DIR/issue-50781.rs:6:8 | LL | fn foo(&self) where Self: Trait; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^ | note: lint level defined here --> $DIR/issue-50781.rs:1:9 diff --git a/src/test/ui/issues/issue-56806.rs b/src/test/ui/issues/issue-56806.rs index b6454e578e6af..b1dac26d65a15 100644 --- a/src/test/ui/issues/issue-56806.rs +++ b/src/test/ui/issues/issue-56806.rs @@ -1,7 +1,6 @@ pub trait Trait { fn dyn_instead_of_self(self: Box); - //~^ ERROR invalid method receiver type: std::boxed::Box<(dyn Trait + 'static)> + //~^ ERROR invalid `self` parameter type } -pub fn main() { -} +pub fn main() {} diff --git a/src/test/ui/issues/issue-56806.stderr b/src/test/ui/issues/issue-56806.stderr index fae6a26720f36..a4f9aadcfef3e 100644 --- a/src/test/ui/issues/issue-56806.stderr +++ b/src/test/ui/issues/issue-56806.stderr @@ -1,11 +1,12 @@ -error[E0307]: invalid method receiver type: std::boxed::Box<(dyn Trait + 'static)> +error[E0307]: invalid `self` parameter type: std::boxed::Box<(dyn Trait + 'static)> --> $DIR/issue-56806.rs:2:34 | LL | fn dyn_instead_of_self(self: Box); | ^^^^^^^^^^^^^^ | - = note: type must be `Self` or a type that dereferences to it + = note: type of `self` must be `Self` or a type that dereferences to it = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error: aborting due to previous error +For more information about this error, try `rustc --explain E0307`. diff --git a/src/test/ui/lint/issue-54538-unused-parens-lint.rs b/src/test/ui/lint/issue-54538-unused-parens-lint.rs index eda9e2cdfaa2f..c442c39fe010e 100644 --- a/src/test/ui/lint/issue-54538-unused-parens-lint.rs +++ b/src/test/ui/lint/issue-54538-unused-parens-lint.rs @@ -1,25 +1,75 @@ -// build-pass (FIXME(62277): could be check-pass?) +#![feature(box_patterns)] + +#![feature(or_patterns)] +//~^ WARN the feature `or_patterns` is incomplete #![allow(ellipsis_inclusive_range_patterns)] #![allow(unreachable_patterns)] #![allow(unused_variables)] -#![warn(unused_parens)] +#![deny(unused_parens)] + +fn lint_on_top_level() { + let (a) = 0; //~ ERROR unnecessary parentheses around pattern + for (a) in 0..1 {} //~ ERROR unnecessary parentheses around pattern + if let (a) = 0 {} //~ ERROR unnecessary parentheses around pattern + while let (a) = 0 {} //~ ERROR unnecessary parentheses around pattern + fn foo((a): u8) {} //~ ERROR unnecessary parentheses around pattern + let _ = |(a): u8| 0; //~ ERROR unnecessary parentheses around pattern +} + +// Don't lint in these cases (#64106). +fn or_patterns_no_lint() { + match Box::new(0) { + box (0 | 1) => {} // Should not lint as `box 0 | 1` binds as `(box 0) | 1`. + _ => {} + } + + match 0 { + x @ (0 | 1) => {} // Should not lint as `x @ 0 | 1` binds as `(x @ 0) | 1`. + _ => {} + } + + if let &(0 | 1) = &0 {} // Should also not lint. + if let &mut (0 | 1) = &mut 0 {} // Same. + + fn foo((Ok(a) | Err(a)): Result) {} // Doesn't parse if we remove parens for now. + //~^ ERROR identifier `a` is bound more than once + + let _ = |(Ok(a) | Err(a)): Result| 1; // `|Ok(a) | Err(a)| 1` parses as bit-or. + //~^ ERROR identifier `a` is bound more than once +} + +fn or_patterns_will_lint() { + if let (0 | 1) = 0 {} //~ ERROR unnecessary parentheses around pattern + if let ((0 | 1),) = (0,) {} //~ ERROR unnecessary parentheses around pattern + if let [(0 | 1)] = [0] {} //~ ERROR unnecessary parentheses around pattern + if let 0 | (1 | 2) = 0 {} //~ ERROR unnecessary parentheses around pattern + struct TS(u8); + if let TS((0 | 1)) = TS(0) {} //~ ERROR unnecessary parentheses around pattern + struct NS { f: u8 } + if let NS { f: (0 | 1) } = (NS { f: 0 }) {} //~ ERROR unnecessary parentheses around pattern +} + +// Don't lint on `&(mut x)` because `&mut x` means something else (#55342). +fn deref_mut_binding_no_lint() { + let &(mut x) = &0; +} fn main() { match 1 { - (_) => {} //~ WARNING: unnecessary parentheses around pattern - (y) => {} //~ WARNING: unnecessary parentheses around pattern - (ref r) => {} //~ WARNING: unnecessary parentheses around pattern - (e @ 1...2) => {} //~ WARNING: unnecessary parentheses around outer pattern - (1...2) => {} // Non ambiguous range pattern should not warn + (_) => {} //~ ERROR unnecessary parentheses around pattern + (y) => {} //~ ERROR unnecessary parentheses around pattern + (ref r) => {} //~ ERROR unnecessary parentheses around pattern + (e @ 1...2) => {} //~ ERROR unnecessary parentheses around pattern + (1...2) => {} // Non ambiguous range pattern should not warn e @ (3...4) => {} // Non ambiguous range pattern should not warn } match &1 { - (e @ &(1...2)) => {} //~ WARNING: unnecessary parentheses around outer pattern - &(_) => {} //~ WARNING: unnecessary parentheses around pattern - e @ &(1...2) => {} // Ambiguous range pattern should not warn - &(1...2) => {} // Ambiguous range pattern should not warn + (e @ &(1...2)) => {} //~ ERROR unnecessary parentheses around pattern + &(_) => {} //~ ERROR unnecessary parentheses around pattern + e @ &(1...2) => {} // Ambiguous range pattern should not warn + &(1...2) => {} // Ambiguous range pattern should not warn } match &1 { @@ -28,19 +78,19 @@ fn main() { } match 1 { - (_) => {} //~ WARNING: unnecessary parentheses around pattern - (y) => {} //~ WARNING: unnecessary parentheses around pattern - (ref r) => {} //~ WARNING: unnecessary parentheses around pattern - (e @ 1..=2) => {} //~ WARNING: unnecessary parentheses around outer pattern - (1..=2) => {} // Non ambiguous range pattern should not warn + (_) => {} //~ ERROR unnecessary parentheses around pattern + (y) => {} //~ ERROR unnecessary parentheses around pattern + (ref r) => {} //~ ERROR unnecessary parentheses around pattern + (e @ 1..=2) => {} //~ ERROR unnecessary parentheses around pattern + (1..=2) => {} // Non ambiguous range pattern should not warn e @ (3..=4) => {} // Non ambiguous range pattern should not warn } match &1 { - (e @ &(1..=2)) => {} //~ WARNING: unnecessary parentheses around outer pattern - &(_) => {} //~ WARNING: unnecessary parentheses around pattern - e @ &(1..=2) => {} // Ambiguous range pattern should not warn - &(1..=2) => {} // Ambiguous range pattern should not warn + (e @ &(1..=2)) => {} //~ ERROR unnecessary parentheses around pattern + &(_) => {} //~ ERROR unnecessary parentheses around pattern + e @ &(1..=2) => {} // Ambiguous range pattern should not warn + &(1..=2) => {} // Ambiguous range pattern should not warn } match &1 { diff --git a/src/test/ui/lint/issue-54538-unused-parens-lint.stderr b/src/test/ui/lint/issue-54538-unused-parens-lint.stderr index 3b312198952a5..a3e0fb938b3c6 100644 --- a/src/test/ui/lint/issue-54538-unused-parens-lint.stderr +++ b/src/test/ui/lint/issue-54538-unused-parens-lint.stderr @@ -1,78 +1,173 @@ -warning: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:10:9 +error[E0416]: identifier `a` is bound more than once in the same pattern + --> $DIR/issue-54538-unused-parens-lint.rs:35:25 | -LL | (_) => {} +LL | fn foo((Ok(a) | Err(a)): Result) {} // Doesn't parse if we remove parens for now. + | ^ used in a pattern more than once + +error[E0416]: identifier `a` is bound more than once in the same pattern + --> $DIR/issue-54538-unused-parens-lint.rs:38:27 + | +LL | let _ = |(Ok(a) | Err(a)): Result| 1; // `|Ok(a) | Err(a)| 1` parses as bit-or. + | ^ used in a pattern more than once + +warning: the feature `or_patterns` is incomplete and may cause the compiler to crash + --> $DIR/issue-54538-unused-parens-lint.rs:3:12 + | +LL | #![feature(or_patterns)] + | ^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:12:9 + | +LL | let (a) = 0; | ^^^ help: remove these parentheses | note: lint level defined here - --> $DIR/issue-54538-unused-parens-lint.rs:6:9 + --> $DIR/issue-54538-unused-parens-lint.rs:9:9 | -LL | #![warn(unused_parens)] +LL | #![deny(unused_parens)] | ^^^^^^^^^^^^^ -warning: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:11:9 +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:13:9 + | +LL | for (a) in 0..1 {} + | ^^^ help: remove these parentheses + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:14:12 + | +LL | if let (a) = 0 {} + | ^^^ help: remove these parentheses + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:15:15 + | +LL | while let (a) = 0 {} + | ^^^ help: remove these parentheses + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:16:12 + | +LL | fn foo((a): u8) {} + | ^^^ help: remove these parentheses + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:17:14 + | +LL | let _ = |(a): u8| 0; + | ^^^ help: remove these parentheses + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:43:12 + | +LL | if let (0 | 1) = 0 {} + | ^^^^^^^ help: remove these parentheses + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:44:13 + | +LL | if let ((0 | 1),) = (0,) {} + | ^^^^^^^ help: remove these parentheses + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:45:13 + | +LL | if let [(0 | 1)] = [0] {} + | ^^^^^^^ help: remove these parentheses + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:46:16 + | +LL | if let 0 | (1 | 2) = 0 {} + | ^^^^^^^ help: remove these parentheses + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:48:15 + | +LL | if let TS((0 | 1)) = TS(0) {} + | ^^^^^^^ help: remove these parentheses + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:50:20 + | +LL | if let NS { f: (0 | 1) } = (NS { f: 0 }) {} + | ^^^^^^^ help: remove these parentheses + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:60:9 + | +LL | (_) => {} + | ^^^ help: remove these parentheses + +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:61:9 | LL | (y) => {} | ^^^ help: remove these parentheses -warning: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:12:9 +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:62:9 | LL | (ref r) => {} | ^^^^^^^ help: remove these parentheses -warning: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:13:9 +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:63:9 | LL | (e @ 1...2) => {} | ^^^^^^^^^^^ help: remove these parentheses -warning: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:19:9 +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:69:9 | LL | (e @ &(1...2)) => {} | ^^^^^^^^^^^^^^ help: remove these parentheses -warning: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:20:10 +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:70:10 | LL | &(_) => {} | ^^^ help: remove these parentheses -warning: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:31:9 +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:81:9 | LL | (_) => {} | ^^^ help: remove these parentheses -warning: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:32:9 +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:82:9 | LL | (y) => {} | ^^^ help: remove these parentheses -warning: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:33:9 +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:83:9 | LL | (ref r) => {} | ^^^^^^^ help: remove these parentheses -warning: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:34:9 +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:84:9 | LL | (e @ 1..=2) => {} | ^^^^^^^^^^^ help: remove these parentheses -warning: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:40:9 +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:90:9 | LL | (e @ &(1..=2)) => {} | ^^^^^^^^^^^^^^ help: remove these parentheses -warning: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:41:10 +error: unnecessary parentheses around pattern + --> $DIR/issue-54538-unused-parens-lint.rs:91:10 | LL | &(_) => {} | ^^^ help: remove these parentheses +error: aborting due to 26 previous errors + +For more information about this error, try `rustc --explain E0416`. diff --git a/src/test/ui/object-safety/object-safety-associated-consts.stderr b/src/test/ui/object-safety/object-safety-associated-consts.stderr index 55f9e3f9f138b..7d5aa00356e0b 100644 --- a/src/test/ui/object-safety/object-safety-associated-consts.stderr +++ b/src/test/ui/object-safety/object-safety-associated-consts.stderr @@ -1,10 +1,11 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-associated-consts.rs:9:1 | +LL | const X: usize; + | - the trait cannot contain associated consts like `X` +... LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object - | - = note: the trait cannot contain associated consts like `X` error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-generics.stderr b/src/test/ui/object-safety/object-safety-generics.stderr index d66cdb98448d4..b25e0052e4163 100644 --- a/src/test/ui/object-safety/object-safety-generics.stderr +++ b/src/test/ui/object-safety/object-safety-generics.stderr @@ -1,18 +1,20 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-generics.rs:14:1 | +LL | fn bar(&self, t: T); + | --- method `bar` has generic type parameters +... LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object - | - = note: method `bar` has generic type parameters error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-generics.rs:19:1 | +LL | fn bar(&self, t: T); + | --- method `bar` has generic type parameters +... LL | fn make_bar_explicit(t: &T) -> &dyn Bar { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object - | - = note: method `bar` has generic type parameters error: aborting due to 2 previous errors diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.stderr index c0c471c2b1e72..971e79cb0210f 100644 --- a/src/test/ui/object-safety/object-safety-mentions-Self.stderr +++ b/src/test/ui/object-safety/object-safety-mentions-Self.stderr @@ -1,18 +1,20 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-mentions-Self.rs:17:1 | +LL | fn bar(&self, x: &Self); + | --- method `bar` references the `Self` type in its parameters or return type +... LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object - | - = note: method `bar` references the `Self` type in its arguments or return type error[E0038]: the trait `Baz` cannot be made into an object --> $DIR/object-safety-mentions-Self.rs:22:1 | +LL | fn bar(&self) -> Self; + | --- method `bar` references the `Self` type in its parameters or return type +... LL | fn make_baz(t: &T) -> &dyn Baz { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Baz` cannot be made into an object - | - = note: method `bar` references the `Self` type in its arguments or return type error: aborting due to 2 previous errors diff --git a/src/test/ui/object-safety/object-safety-no-static.stderr b/src/test/ui/object-safety/object-safety-no-static.stderr index da8dd657c2a9d..0de783f60ea47 100644 --- a/src/test/ui/object-safety/object-safety-no-static.stderr +++ b/src/test/ui/object-safety/object-safety-no-static.stderr @@ -1,10 +1,11 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/object-safety-no-static.rs:8:1 | +LL | fn foo(); + | --- associated function `foo` has no `self` parameter +... LL | fn foo_implicit(b: Box) -> Box { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object - | - = note: method `foo` has no receiver error: aborting due to previous error diff --git a/src/test/ui/resolve/issue-3907-2.stderr b/src/test/ui/resolve/issue-3907-2.stderr index 968c1f3e463d0..63ac11dc8ae01 100644 --- a/src/test/ui/resolve/issue-3907-2.stderr +++ b/src/test/ui/resolve/issue-3907-2.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `issue_3907::Foo` cannot be made into an object LL | fn bar(_x: Foo) {} | ^^^^^^^^^^^^^^^ the trait `issue_3907::Foo` cannot be made into an object | - = note: method `bar` has no receiver + = note: associated function `bar` has no `self` parameter error: aborting due to previous error diff --git a/src/test/ui/rfc-2565-param-attrs/auxiliary/ident-mac.rs b/src/test/ui/rfc-2565-param-attrs/auxiliary/ident-mac.rs new file mode 100644 index 0000000000000..b62cf31205fd3 --- /dev/null +++ b/src/test/ui/rfc-2565-param-attrs/auxiliary/ident-mac.rs @@ -0,0 +1,11 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn id(_: TokenStream, input: TokenStream) -> TokenStream { input } diff --git a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs new file mode 100644 index 0000000000000..8defa26e48d8d --- /dev/null +++ b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs @@ -0,0 +1,60 @@ +// aux-build:ident-mac.rs + +#![feature(param_attrs)] +#![feature(c_variadic)] + +extern crate ident_mac; +use ident_mac::id; + +struct W(u8); + +extern "C" { fn ffi(#[id] arg1: i32, #[id] ...); } +//~^ ERROR the attribute `id` is currently unknown to the compiler +//~| ERROR the attribute `id` is currently unknown to the compiler + +unsafe extern "C" fn cvar(arg1: i32, #[id] mut args: ...) {} +//~^ ERROR the attribute `id` is currently unknown to the compiler + +type Alias = extern "C" fn(#[id] u8, #[id] ...); + //~^ ERROR the attribute `id` is currently unknown to the compiler + //~| ERROR the attribute `id` is currently unknown to the compiler + +fn free(#[id] arg1: u8) { + //~^ ERROR the attribute `id` is currently unknown to the compiler + let lam = |#[id] W(x), #[id] y| (); + //~^ ERROR the attribute `id` is currently unknown to the compiler + //~| ERROR the attribute `id` is currently unknown to the compiler +} + +impl W { + fn inherent1(#[id] self, #[id] arg1: u8) {} + //~^ ERROR the attribute `id` is currently unknown to the compiler + //~| ERROR the attribute `id` is currently unknown to the compiler + fn inherent2(#[id] &self, #[id] arg1: u8) {} + //~^ ERROR the attribute `id` is currently unknown to the compiler + //~| ERROR the attribute `id` is currently unknown to the compiler + fn inherent3<'a>(#[id] &'a mut self, #[id] arg1: u8) {} + //~^ ERROR the attribute `id` is currently unknown to the compiler + //~| ERROR the attribute `id` is currently unknown to the compiler + fn inherent4<'a>(#[id] self: Box, #[id] arg1: u8) {} + //~^ ERROR the attribute `id` is currently unknown to the compiler + //~| ERROR the attribute `id` is currently unknown to the compiler +} + +trait A { + fn trait1(#[id] self, #[id] arg1: u8); + //~^ ERROR the attribute `id` is currently unknown to the compiler + //~| ERROR the attribute `id` is currently unknown to the compiler + fn trait2(#[id] &self, #[id] arg1: u8); + //~^ ERROR the attribute `id` is currently unknown to the compiler + //~| ERROR the attribute `id` is currently unknown to the compiler + fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8); + //~^ ERROR the attribute `id` is currently unknown to the compiler + //~| ERROR the attribute `id` is currently unknown to the compiler + fn trait4<'a>(#[id] self: Box, #[id] arg1: u8, #[id] Vec); + //~^ ERROR the attribute `id` is currently unknown to the compiler + //~| ERROR the attribute `id` is currently unknown to the compiler + //~| ERROR the attribute `id` is currently unknown to the compiler +} + +fn main() {} diff --git a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr new file mode 100644 index 0000000000000..69b9a46b3d502 --- /dev/null +++ b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr @@ -0,0 +1,228 @@ +error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/proc-macro-cannot-be-used.rs:11:21 + | +LL | extern "C" { fn ffi(#[id] arg1: i32, #[id] ...); } + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + +error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/proc-macro-cannot-be-used.rs:11:38 + | +LL | extern "C" { fn ffi(#[id] arg1: i32, #[id] ...); } + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + +error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/proc-macro-cannot-be-used.rs:15:38 + | +LL | unsafe extern "C" fn cvar(arg1: i32, #[id] mut args: ...) {} + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + +error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/proc-macro-cannot-be-used.rs:18:28 + | +LL | type Alias = extern "C" fn(#[id] u8, #[id] ...); + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + +error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/proc-macro-cannot-be-used.rs:18:38 + | +LL | type Alias = extern "C" fn(#[id] u8, #[id] ...); + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + +error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/proc-macro-cannot-be-used.rs:22:9 + | +LL | fn free(#[id] arg1: u8) { + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + +error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/proc-macro-cannot-be-used.rs:24:16 + | +LL | let lam = |#[id] W(x), #[id] y| (); + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + +error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/proc-macro-cannot-be-used.rs:24:28 + | +LL | let lam = |#[id] W(x), #[id] y| (); + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + +error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/proc-macro-cannot-be-used.rs:30:18 + | +LL | fn inherent1(#[id] self, #[id] arg1: u8) {} + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + +error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/proc-macro-cannot-be-used.rs:30:30 + | +LL | fn inherent1(#[id] self, #[id] arg1: u8) {} + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + +error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/proc-macro-cannot-be-used.rs:33:18 + | +LL | fn inherent2(#[id] &self, #[id] arg1: u8) {} + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + +error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/proc-macro-cannot-be-used.rs:33:31 + | +LL | fn inherent2(#[id] &self, #[id] arg1: u8) {} + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + +error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/proc-macro-cannot-be-used.rs:36:22 + | +LL | fn inherent3<'a>(#[id] &'a mut self, #[id] arg1: u8) {} + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + +error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/proc-macro-cannot-be-used.rs:36:42 + | +LL | fn inherent3<'a>(#[id] &'a mut self, #[id] arg1: u8) {} + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + +error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/proc-macro-cannot-be-used.rs:39:22 + | +LL | fn inherent4<'a>(#[id] self: Box, #[id] arg1: u8) {} + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + +error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/proc-macro-cannot-be-used.rs:39:45 + | +LL | fn inherent4<'a>(#[id] self: Box, #[id] arg1: u8) {} + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + +error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/proc-macro-cannot-be-used.rs:45:15 + | +LL | fn trait1(#[id] self, #[id] arg1: u8); + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + +error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/proc-macro-cannot-be-used.rs:45:27 + | +LL | fn trait1(#[id] self, #[id] arg1: u8); + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + +error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/proc-macro-cannot-be-used.rs:48:15 + | +LL | fn trait2(#[id] &self, #[id] arg1: u8); + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + +error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/proc-macro-cannot-be-used.rs:48:28 + | +LL | fn trait2(#[id] &self, #[id] arg1: u8); + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + +error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/proc-macro-cannot-be-used.rs:51:19 + | +LL | fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8); + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + +error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/proc-macro-cannot-be-used.rs:51:39 + | +LL | fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8); + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + +error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/proc-macro-cannot-be-used.rs:54:19 + | +LL | fn trait4<'a>(#[id] self: Box, #[id] arg1: u8, #[id] Vec); + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + +error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/proc-macro-cannot-be-used.rs:54:42 + | +LL | fn trait4<'a>(#[id] self: Box, #[id] arg1: u8, #[id] Vec); + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + +error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/proc-macro-cannot-be-used.rs:54:58 + | +LL | fn trait4<'a>(#[id] self: Box, #[id] arg1: u8, #[id] Vec); + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + +error: aborting due to 25 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.stderr index e45bc2657f1ea..e6eba377a9578 100644 --- a/src/test/ui/self/arbitrary-self-types-not-object-safe.stderr +++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.stderr @@ -1,18 +1,21 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/arbitrary-self-types-not-object-safe.rs:31:32 | +LL | fn foo(self: &Rc) -> usize; + | --- method `foo`'s `self` parameter cannot be dispatched on +... LL | let x = Rc::new(5usize) as Rc; | ^^^^^^^^^^^ the trait `Foo` cannot be made into an object - | - = note: method `foo`'s receiver cannot be dispatched on error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/arbitrary-self-types-not-object-safe.rs:31:13 | +LL | fn foo(self: &Rc) -> usize; + | --- method `foo`'s `self` parameter cannot be dispatched on +... LL | let x = Rc::new(5usize) as Rc; | ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object | - = note: method `foo`'s receiver cannot be dispatched on = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::rc::Rc` error: aborting due to 2 previous errors diff --git a/src/test/ui/span/issue-27522.rs b/src/test/ui/span/issue-27522.rs index 5c9893f64a6ee..7a0cfb679ed67 100644 --- a/src/test/ui/span/issue-27522.rs +++ b/src/test/ui/span/issue-27522.rs @@ -3,7 +3,7 @@ struct SomeType {} trait Foo { - fn handler(self: &SomeType); //~ ERROR invalid method receiver type + fn handler(self: &SomeType); //~ ERROR invalid `self` parameter type } fn main() {} diff --git a/src/test/ui/span/issue-27522.stderr b/src/test/ui/span/issue-27522.stderr index 88dfee1cada3f..8a254a9685543 100644 --- a/src/test/ui/span/issue-27522.stderr +++ b/src/test/ui/span/issue-27522.stderr @@ -1,11 +1,12 @@ -error[E0307]: invalid method receiver type: &SomeType +error[E0307]: invalid `self` parameter type: &SomeType --> $DIR/issue-27522.rs:6:22 | LL | fn handler(self: &SomeType); | ^^^^^^^^^ | - = note: type must be `Self` or a type that dereferences to it + = note: type of `self` must be `Self` or a type that dereferences to it = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error: aborting due to previous error +For more information about this error, try `rustc --explain E0307`. diff --git a/src/test/ui/traits/trait-item-privacy.stderr b/src/test/ui/traits/trait-item-privacy.stderr index ce2919c8e7741..16ea7bdb0807d 100644 --- a/src/test/ui/traits/trait-item-privacy.stderr +++ b/src/test/ui/traits/trait-item-privacy.stderr @@ -110,12 +110,17 @@ LL | C::A; error[E0038]: the trait `assoc_const::C` cannot be made into an object --> $DIR/trait-item-privacy.rs:101:5 | +LL | const A: u8 = 0; + | - the trait cannot contain associated consts like `A` +... +LL | const B: u8 = 0; + | - the trait cannot contain associated consts like `B` +... +LL | const C: u8 = 0; + | - the trait cannot contain associated consts like `C` +... LL | C::A; | ^^^^ the trait `assoc_const::C` cannot be made into an object - | - = note: the trait cannot contain associated consts like `C` - = note: the trait cannot contain associated consts like `B` - = note: the trait cannot contain associated consts like `A` error[E0223]: ambiguous associated type --> $DIR/trait-item-privacy.rs:115:12 diff --git a/src/test/ui/traits/trait-object-safety.stderr b/src/test/ui/traits/trait-object-safety.stderr index 68edc17870534..3ac1e96b30c95 100644 --- a/src/test/ui/traits/trait-object-safety.stderr +++ b/src/test/ui/traits/trait-object-safety.stderr @@ -1,19 +1,22 @@ error[E0038]: the trait `Tr` cannot be made into an object --> $DIR/trait-object-safety.rs:15:22 | +LL | fn foo(); + | --- associated function `foo` has no `self` parameter +... LL | let _: &dyn Tr = &St; | ^^^ the trait `Tr` cannot be made into an object | - = note: method `foo` has no receiver = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Tr>` for `&St` error[E0038]: the trait `Tr` cannot be made into an object --> $DIR/trait-object-safety.rs:15:12 | +LL | fn foo(); + | --- associated function `foo` has no `self` parameter +... LL | let _: &dyn Tr = &St; | ^^^^^^^ the trait `Tr` cannot be made into an object - | - = note: method `foo` has no receiver error: aborting due to 2 previous errors diff --git a/src/test/ui/traits/trait-test-2.stderr b/src/test/ui/traits/trait-test-2.stderr index 5d5251925a1ae..83c2c06527493 100644 --- a/src/test/ui/traits/trait-test-2.stderr +++ b/src/test/ui/traits/trait-test-2.stderr @@ -13,20 +13,25 @@ LL | 10.blah::(); error[E0038]: the trait `bar` cannot be made into an object --> $DIR/trait-test-2.rs:11:16 | +LL | trait bar { fn dup(&self) -> Self; fn blah(&self); } + | --- ---- method `blah` has generic type parameters + | | + | method `dup` references the `Self` type in its parameters or return type +... LL | (box 10 as Box).dup(); | ^^^^^^^^^^^^ the trait `bar` cannot be made into an object - | - = note: method `dup` references the `Self` type in its arguments or return type - = note: method `blah` has generic type parameters error[E0038]: the trait `bar` cannot be made into an object --> $DIR/trait-test-2.rs:11:6 | +LL | trait bar { fn dup(&self) -> Self; fn blah(&self); } + | --- ---- method `blah` has generic type parameters + | | + | method `dup` references the `Self` type in its parameters or return type +... LL | (box 10 as Box).dup(); | ^^^^^^ the trait `bar` cannot be made into an object | - = note: method `dup` references the `Self` type in its arguments or return type - = note: method `blah` has generic type parameters = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::boxed::Box<{integer}>` error: aborting due to 4 previous errors diff --git a/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr index 58727ea0fef99..b315fe9df8afd 100644 --- a/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr +++ b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr @@ -13,10 +13,11 @@ LL | let y = x as dyn MyAdd; error[E0038]: the trait `MyAdd` cannot be made into an object --> $DIR/type-parameter-defaults-referencing-Self-ppaux.rs:14:18 | +LL | trait MyAdd { fn add(&self, other: &Rhs) -> Self; } + | --- method `add` references the `Self` type in its parameters or return type +... LL | let y = x as dyn MyAdd; | ^^^^^^^^^^^^^^ the trait `MyAdd` cannot be made into an object - | - = note: method `add` references the `Self` type in its arguments or return type error: aborting due to 2 previous errors diff --git a/src/test/ui/ufcs/ufcs-explicit-self-bad.rs b/src/test/ui/ufcs/ufcs-explicit-self-bad.rs index c6ff94a5e7606..bdb8e197fbe49 100644 --- a/src/test/ui/ufcs/ufcs-explicit-self-bad.rs +++ b/src/test/ui/ufcs/ufcs-explicit-self-bad.rs @@ -6,7 +6,7 @@ struct Foo { impl Foo { fn foo(self: isize, x: isize) -> isize { - //~^ ERROR invalid method receiver type + //~^ ERROR invalid `self` parameter type self.f + x } } @@ -17,11 +17,11 @@ struct Bar { impl Bar { fn foo(self: Bar, x: isize) -> isize { - //~^ ERROR invalid method receiver type + //~^ ERROR invalid `self` parameter type x } fn bar(self: &Bar, x: isize) -> isize { - //~^ ERROR invalid method receiver type + //~^ ERROR invalid `self` parameter type x } } @@ -34,14 +34,14 @@ trait SomeTrait { impl<'a, T> SomeTrait for &'a Bar { fn dummy1(self: &&'a Bar) { } - fn dummy2(self: &Bar) {} //~ ERROR mismatched method receiver - //~^ ERROR mismatched method receiver + fn dummy2(self: &Bar) {} //~ ERROR mismatched `self` parameter type + //~^ ERROR mismatched `self` parameter type fn dummy3(self: &&Bar) {} - //~^ ERROR mismatched method receiver + //~^ ERROR mismatched `self` parameter type //~| expected type `&'a Bar` //~| found type `&Bar` //~| lifetime mismatch - //~| ERROR mismatched method receiver + //~| ERROR mismatched `self` parameter type //~| expected type `&'a Bar` //~| found type `&Bar` //~| lifetime mismatch diff --git a/src/test/ui/ufcs/ufcs-explicit-self-bad.stderr b/src/test/ui/ufcs/ufcs-explicit-self-bad.stderr index 6da20e37577b0..b2fe1b281fc99 100644 --- a/src/test/ui/ufcs/ufcs-explicit-self-bad.stderr +++ b/src/test/ui/ufcs/ufcs-explicit-self-bad.stderr @@ -1,31 +1,31 @@ -error[E0307]: invalid method receiver type: isize +error[E0307]: invalid `self` parameter type: isize --> $DIR/ufcs-explicit-self-bad.rs:8:18 | LL | fn foo(self: isize, x: isize) -> isize { | ^^^^^ | - = note: type must be `Self` or a type that dereferences to it + = note: type of `self` must be `Self` or a type that dereferences to it = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) -error[E0307]: invalid method receiver type: Bar +error[E0307]: invalid `self` parameter type: Bar --> $DIR/ufcs-explicit-self-bad.rs:19:18 | LL | fn foo(self: Bar, x: isize) -> isize { | ^^^^^^^^^^ | - = note: type must be `Self` or a type that dereferences to it + = note: type of `self` must be `Self` or a type that dereferences to it = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) -error[E0307]: invalid method receiver type: &Bar +error[E0307]: invalid `self` parameter type: &Bar --> $DIR/ufcs-explicit-self-bad.rs:23:18 | LL | fn bar(self: &Bar, x: isize) -> isize { | ^^^^^^^^^^^ | - = note: type must be `Self` or a type that dereferences to it + = note: type of `self` must be `Self` or a type that dereferences to it = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) -error[E0308]: mismatched method receiver +error[E0308]: mismatched `self` parameter type --> $DIR/ufcs-explicit-self-bad.rs:37:21 | LL | fn dummy2(self: &Bar) {} @@ -44,7 +44,7 @@ note: ...does not necessarily outlive the lifetime 'a as defined on the impl at LL | impl<'a, T> SomeTrait for &'a Bar { | ^^ -error[E0308]: mismatched method receiver +error[E0308]: mismatched `self` parameter type --> $DIR/ufcs-explicit-self-bad.rs:37:21 | LL | fn dummy2(self: &Bar) {} @@ -63,7 +63,7 @@ note: ...does not necessarily outlive the anonymous lifetime #1 defined on the m LL | fn dummy2(self: &Bar) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0308]: mismatched method receiver +error[E0308]: mismatched `self` parameter type --> $DIR/ufcs-explicit-self-bad.rs:39:21 | LL | fn dummy3(self: &&Bar) {} @@ -82,7 +82,7 @@ note: ...does not necessarily outlive the lifetime 'a as defined on the impl at LL | impl<'a, T> SomeTrait for &'a Bar { | ^^ -error[E0308]: mismatched method receiver +error[E0308]: mismatched `self` parameter type --> $DIR/ufcs-explicit-self-bad.rs:39:21 | LL | fn dummy3(self: &&Bar) {} @@ -103,4 +103,5 @@ LL | fn dummy3(self: &&Bar) {} error: aborting due to 7 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0307, E0308. +For more information about an error, try `rustc --explain E0307`. diff --git a/src/test/ui/rfc-2166-underscore-imports/auxiliary/duplicate.rs b/src/test/ui/underscore-imports/auxiliary/duplicate.rs similarity index 100% rename from src/test/ui/rfc-2166-underscore-imports/auxiliary/duplicate.rs rename to src/test/ui/underscore-imports/auxiliary/duplicate.rs diff --git a/src/test/ui/rfc-2166-underscore-imports/auxiliary/underscore-imports.rs b/src/test/ui/underscore-imports/auxiliary/underscore-imports.rs similarity index 100% rename from src/test/ui/rfc-2166-underscore-imports/auxiliary/underscore-imports.rs rename to src/test/ui/underscore-imports/auxiliary/underscore-imports.rs diff --git a/src/test/ui/rfc-2166-underscore-imports/basic.rs b/src/test/ui/underscore-imports/basic.rs similarity index 100% rename from src/test/ui/rfc-2166-underscore-imports/basic.rs rename to src/test/ui/underscore-imports/basic.rs diff --git a/src/test/ui/rfc-2166-underscore-imports/basic.stderr b/src/test/ui/underscore-imports/basic.stderr similarity index 100% rename from src/test/ui/rfc-2166-underscore-imports/basic.stderr rename to src/test/ui/underscore-imports/basic.stderr diff --git a/src/test/ui/underscore-imports/cycle.rs b/src/test/ui/underscore-imports/cycle.rs new file mode 100644 index 0000000000000..bacf9b2d5a96a --- /dev/null +++ b/src/test/ui/underscore-imports/cycle.rs @@ -0,0 +1,18 @@ +// Check that cyclic glob imports are allowed with underscore imports + +// check-pass + +mod x { + pub use crate::y::*; + pub use std::ops::Deref as _; +} + +mod y { + pub use crate::x::*; + pub use std::ops::Deref as _; +} + +pub fn main() { + use x::*; + (&0).deref(); +} diff --git a/src/test/ui/rfc-2166-underscore-imports/duplicate.rs b/src/test/ui/underscore-imports/duplicate.rs similarity index 100% rename from src/test/ui/rfc-2166-underscore-imports/duplicate.rs rename to src/test/ui/underscore-imports/duplicate.rs diff --git a/src/test/ui/rfc-2166-underscore-imports/intercrate.rs b/src/test/ui/underscore-imports/intercrate.rs similarity index 100% rename from src/test/ui/rfc-2166-underscore-imports/intercrate.rs rename to src/test/ui/underscore-imports/intercrate.rs diff --git a/src/test/ui/underscore-imports/shadow.rs b/src/test/ui/underscore-imports/shadow.rs new file mode 100644 index 0000000000000..325f2001b9ede --- /dev/null +++ b/src/test/ui/underscore-imports/shadow.rs @@ -0,0 +1,23 @@ +// Check that underscore imports don't cause glob imports to be unshadowed + +mod a { + pub use std::ops::Deref as Shadow; +} + +mod b { + pub use crate::a::*; + macro_rules! m { + ($i:ident) => { pub struct $i; } + } + m!(Shadow); +} + +mod c { + use crate::b::Shadow as _; // Only imports the struct + + fn f(x: &()) { + x.deref(); //~ ERROR no method named `deref` found + } +} + +fn main() {} diff --git a/src/test/ui/underscore-imports/shadow.stderr b/src/test/ui/underscore-imports/shadow.stderr new file mode 100644 index 0000000000000..92adca2c70490 --- /dev/null +++ b/src/test/ui/underscore-imports/shadow.stderr @@ -0,0 +1,13 @@ +error[E0599]: no method named `deref` found for type `&()` in the current scope + --> $DIR/shadow.rs:19:11 + | +LL | x.deref(); + | ^^^^^ + | + = help: items from traits can only be used if the trait is in scope + = note: the following trait is implemented but not in scope, perhaps add a `use` for it: + `use std::ops::Deref;` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/rfc-2166-underscore-imports/unused-2018.rs b/src/test/ui/underscore-imports/unused-2018.rs similarity index 100% rename from src/test/ui/rfc-2166-underscore-imports/unused-2018.rs rename to src/test/ui/underscore-imports/unused-2018.rs diff --git a/src/test/ui/rfc-2166-underscore-imports/unused-2018.stderr b/src/test/ui/underscore-imports/unused-2018.stderr similarity index 100% rename from src/test/ui/rfc-2166-underscore-imports/unused-2018.stderr rename to src/test/ui/underscore-imports/unused-2018.stderr diff --git a/src/test/ui/wf/wf-object-safe.stderr b/src/test/ui/wf/wf-object-safe.stderr index 3b264ecd580ec..0d8441f87e7e7 100644 --- a/src/test/ui/wf/wf-object-safe.stderr +++ b/src/test/ui/wf/wf-object-safe.stderr @@ -1,10 +1,11 @@ error[E0038]: the trait `A` cannot be made into an object --> $DIR/wf-object-safe.rs:9:13 | +LL | fn foo(&self, _x: &Self); + | --- method `foo` references the `Self` type in its parameters or return type +... LL | let _x: &dyn A; | ^^^^^^ the trait `A` cannot be made into an object - | - = note: method `foo` references the `Self` type in its arguments or return type error: aborting due to previous error diff --git a/src/tools/tidy/src/features/tests.rs b/src/tools/tidy/src/features/tests.rs index fa7a931ec865c..994523ac1abce 100644 --- a/src/tools/tidy/src/features/tests.rs +++ b/src/tools/tidy/src/features/tests.rs @@ -2,8 +2,8 @@ use super::*; #[test] fn test_find_attr_val() { - let s = r#"#[unstable(feature = "checked_duration_since", issue = "58402")]"#; - assert_eq!(find_attr_val(s, "feature"), Some("checked_duration_since")); + let s = r#"#[unstable(feature = "tidy_test_never_used_anywhere_else", issue = "58402")]"#; + assert_eq!(find_attr_val(s, "feature"), Some("tidy_test_never_used_anywhere_else")); assert_eq!(find_attr_val(s, "issue"), Some("58402")); assert_eq!(find_attr_val(s, "since"), None); }