diff options
| author | Baoshan <pangbw@gmail.com> | 2019-09-05 22:42:04 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-09-05 22:42:04 -0700 |
| commit | 414d1047291348b5b8bf49e1d76fec978238d89f (patch) | |
| tree | 7894264d7d7758bbfe15952b598cabd05da75911 /src/librustc | |
| parent | 109e16e8574a4fc47bf7c1d26b6000731002bc34 (diff) | |
| parent | 618768492f0c731fcb770dc2d178abe840846419 (diff) | |
| download | rust-414d1047291348b5b8bf49e1d76fec978238d89f.tar.gz rust-414d1047291348b5b8bf49e1d76fec978238d89f.zip | |
Merge pull request #17 from rust-lang/master
sync with rust-lang/rust master branch
Diffstat (limited to 'src/librustc')
| -rw-r--r-- | src/librustc/Cargo.toml | 2 | ||||
| -rw-r--r-- | src/librustc/error_codes.rs | 2 | ||||
| -rw-r--r-- | src/librustc/hir/map/collector.rs | 2 | ||||
| -rw-r--r-- | src/librustc/ich/impls_syntax.rs | 23 | ||||
| -rw-r--r-- | src/librustc/infer/error_reporting/mod.rs | 13 | ||||
| -rw-r--r-- | src/librustc/lint/context.rs | 4 | ||||
| -rw-r--r-- | src/librustc/lint/levels.rs | 2 | ||||
| -rw-r--r-- | src/librustc/mir/mod.rs | 25 | ||||
| -rw-r--r-- | src/librustc/traits/error_reporting.rs | 5 | ||||
| -rw-r--r-- | src/librustc/traits/object_safety.rs | 72 | ||||
| -rw-r--r-- | src/librustc/traits/on_unimplemented.rs | 19 | ||||
| -rw-r--r-- | src/librustc/ty/mod.rs | 6 | ||||
| -rw-r--r-- | src/librustc/ty/util.rs | 6 |
13 files changed, 105 insertions, 76 deletions
diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 0222a3dde7a..a479fabafc0 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -21,7 +21,7 @@ scoped-tls = "1.0" log = { version = "0.4", features = ["release_max_level_info", "std"] } rustc-rayon = "0.2.0" rustc-rayon-core = "0.2.0" -polonius-engine = "0.9.0" +polonius-engine = "0.10.0" rustc_apfloat = { path = "../librustc_apfloat" } rustc_target = { path = "../librustc_target" } rustc_macros = { path = "../librustc_macros" } diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs index 2d09013f675..937a9ea6c1b 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 773bb8dde06..b8bd1d73fc2 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 05e2c7854b4..ddfca3a4cfb 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<StableHashingContext<'a>> for InternedString { } } -impl<'a> HashStable<StableHashingContext<'a>> for LocalInternedString { - #[inline] - fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a>, - hasher: &mut StableHasher<W>) { - let s: &str = &**self; - s.hash_stable(hcx, hasher); - } -} - -impl<'a> ToStableHashKey<StableHashingContext<'a>> for LocalInternedString { - type KeyType = LocalInternedString; - - #[inline] - fn to_stable_hash_key(&self, - _: &StableHashingContext<'a>) - -> LocalInternedString { - self.clone() - } -} - impl<'a> HashStable<StableHashingContext<'a>> for ast::Name { #[inline] fn hash_stable<W: StableHasherResult>(&self, diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index e684ccfeeb7..5883be6e268 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -1136,12 +1136,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { if let Some((expected, found)) = expected_found { match (terr, is_simple_error, expected == found) { (&TypeError::Sorts(ref values), false, true) => { + let sort_string = | a_type: Ty<'tcx> | + if let ty::Opaque(def_id, _) = a_type.sty { + format!(" (opaque type at {})", self.tcx.sess.source_map() + .mk_substr_filename(self.tcx.def_span(def_id))) + } else { + format!(" ({})", a_type.sort_string(self.tcx)) + }; diag.note_expected_found_extra( &"type", expected, found, - &format!(" ({})", values.expected.sort_string(self.tcx)), - &format!(" ({})", values.found.sort_string(self.tcx)), + &sort_string(values.expected), + &sort_string(values.found), ); } (_, false, _) => { @@ -1627,7 +1634,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 affda256322..77df93080cd 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<LocalInternedString>, + tool_name: Option<Symbol>, ) -> 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 139f4343117..cbc6dbdba7e 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 5ac99ba1470..8956cbb2bae 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1808,6 +1808,23 @@ pub enum ProjectionElem<V, T> { Downcast(Option<Symbol>, VariantIdx), } +impl<V, T> ProjectionElem<V, T> { + /// 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<Local, Ty<'tcx>>; @@ -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 b38e1f5f839..03cc00d87e3 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 7ea7bf0257c..f7f459cd27f 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<Span> { + // 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<A>()` 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<ObjectSafetyViolation> - { + pub fn astconv_object_safety_violations( + self, + trait_def_id: DefId, + ) -> Vec<ObjectSafetyViolation> { 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 0a42b6b46f2..5a988d9509e 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<Self, ErrorReported> { 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::<FxHashMap<Symbol, String>>(); 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 56505c04f0f..2da50f37409 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 7a77418050c..a08c82a0ae8 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<Ty<'tcx>> { 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); |
