diff --git a/src/doc/unstable-book/src/language-features/generators.md b/src/doc/unstable-book/src/language-features/generators.md index 8bc62418b3969..7b865c9c679bc 100644 --- a/src/doc/unstable-book/src/language-features/generators.md +++ b/src/doc/unstable-book/src/language-features/generators.md @@ -87,7 +87,7 @@ Feedback on the design and usage is always appreciated! The `Generator` trait in `std::ops` currently looks like: -``` +```rust # #![feature(arbitrary_self_types, generator_trait)] # use std::ops::GeneratorState; # use std::pin::Pin; @@ -107,7 +107,7 @@ point for executing the `Generator` itself. The return value of `resume`, `GeneratorState`, looks like: -``` +```rust pub enum GeneratorState { Yielded(Y), Complete(R), diff --git a/src/libcore/convert/mod.rs b/src/libcore/convert/mod.rs index 47ab8715cfa14..eef9ee7cb0093 100644 --- a/src/libcore/convert/mod.rs +++ b/src/libcore/convert/mod.rs @@ -41,6 +41,7 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::fmt; +use crate::hash::{Hash, Hasher}; mod num; @@ -746,3 +747,10 @@ impl From for Infallible { x } } + +#[stable(feature = "convert_infallible_hash", since = "1.44.0")] +impl Hash for Infallible { + fn hash(&self, _: &mut H) { + match *self {} + } +} diff --git a/src/librustc_lexer/src/lib.rs b/src/librustc_lexer/src/lib.rs index fcb7475cc2e89..5ccfc1b276bfa 100644 --- a/src/librustc_lexer/src/lib.rs +++ b/src/librustc_lexer/src/lib.rs @@ -148,6 +148,10 @@ pub enum LiteralKind { pub struct UnvalidatedRawStr { /// The prefix (`r###"`) is valid valid_start: bool, + + /// The postfix (`"###`) is valid + valid_end: bool, + /// The number of leading `#` n_start_hashes: usize, /// The number of trailing `#`. `n_end_hashes` <= `n_start_hashes` @@ -197,7 +201,7 @@ impl UnvalidatedRawStr { let n_start_safe: u16 = self.n_start_hashes.try_into().map_err(|_| LexRawStrError::TooManyDelimiters)?; - if self.n_start_hashes > self.n_end_hashes { + if self.n_start_hashes > self.n_end_hashes || !self.valid_end { Err(LexRawStrError::NoTerminator { expected: self.n_start_hashes, found: self.n_end_hashes, @@ -687,6 +691,7 @@ impl Cursor<'_> { _ => { return UnvalidatedRawStr { valid_start, + valid_end: false, n_start_hashes, n_end_hashes: 0, possible_terminator_offset, @@ -702,6 +707,7 @@ impl Cursor<'_> { if self.is_eof() { return UnvalidatedRawStr { valid_start, + valid_end: false, n_start_hashes, n_end_hashes: max_hashes, possible_terminator_offset, @@ -727,6 +733,7 @@ impl Cursor<'_> { if n_end_hashes == n_start_hashes { return UnvalidatedRawStr { valid_start, + valid_end: true, n_start_hashes, n_end_hashes, possible_terminator_offset: None, diff --git a/src/librustc_lexer/src/tests.rs b/src/librustc_lexer/src/tests.rs index 4af435536f011..06fc159fe2516 100644 --- a/src/librustc_lexer/src/tests.rs +++ b/src/librustc_lexer/src/tests.rs @@ -23,6 +23,7 @@ mod tests { n_start_hashes: 0, n_end_hashes: 0, valid_start: true, + valid_end: true, possible_terminator_offset: None, }, Ok(ValidatedRawStr { n_hashes: 0 }), @@ -37,6 +38,7 @@ mod tests { n_start_hashes: 0, n_end_hashes: 0, valid_start: true, + valid_end: true, possible_terminator_offset: None, }, Ok(ValidatedRawStr { n_hashes: 0 }), @@ -51,6 +53,7 @@ mod tests { UnvalidatedRawStr { n_start_hashes: 1, n_end_hashes: 1, + valid_end: true, valid_start: true, possible_terminator_offset: None, }, @@ -65,6 +68,7 @@ mod tests { UnvalidatedRawStr { n_start_hashes: 1, n_end_hashes: 0, + valid_end: false, valid_start: true, possible_terminator_offset: None, }, @@ -80,6 +84,7 @@ mod tests { n_start_hashes: 2, n_end_hashes: 1, valid_start: true, + valid_end: false, possible_terminator_offset: Some(7), }, Err(LexRawStrError::NoTerminator { @@ -95,6 +100,7 @@ mod tests { n_start_hashes: 2, n_end_hashes: 0, valid_start: true, + valid_end: false, possible_terminator_offset: None, }, Err(LexRawStrError::NoTerminator { @@ -113,9 +119,30 @@ mod tests { n_start_hashes: 1, n_end_hashes: 0, valid_start: false, + valid_end: false, possible_terminator_offset: None, }, Err(LexRawStrError::InvalidStarter), ); } + + #[test] + fn test_unterminated_no_pound() { + // https://github.com/rust-lang/rust/issues/70677 + check_raw_str( + r#"""#, + UnvalidatedRawStr { + n_start_hashes: 0, + n_end_hashes: 0, + valid_start: true, + valid_end: false, + possible_terminator_offset: None, + }, + Err(LexRawStrError::NoTerminator { + expected: 0, + found: 0, + possible_terminator_offset: None, + }), + ); + } } diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index 004c5f2ebb7f4..04aa8187e1fe9 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -633,7 +633,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } fn maybe_kind(&self, item_id: DefIndex) -> Option { - self.root.per_def.kind.get(self, item_id).map(|k| k.decode(self)) + self.root.tables.kind.get(self, item_id).map(|k| k.decode(self)) } fn kind(&self, item_id: DefIndex) -> EntryKind { @@ -665,7 +665,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .expect("no name in item_ident"); let span = self .root - .per_def + .tables .ident_span .get(self, item_index) .map(|data| data.decode((self, sess))) @@ -688,7 +688,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } fn get_span(&self, index: DefIndex, sess: &Session) -> Span { - self.root.per_def.span.get(self, index).unwrap().decode((self, sess)) + self.root.tables.span.get(self, index).unwrap().decode((self, sess)) } fn load_proc_macro(&self, id: DefIndex, sess: &Session) -> SyntaxExtension { @@ -781,7 +781,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { ctor_did, data.discr, self.root - .per_def + .tables .children .get(self, index) .unwrap_or(Lazy::empty()) @@ -812,7 +812,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { let variants = if let ty::AdtKind::Enum = adt_kind { self.root - .per_def + .tables .children .get(self, item_id) .unwrap_or(Lazy::empty()) @@ -831,7 +831,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { item_id: DefIndex, tcx: TyCtxt<'tcx>, ) -> ty::GenericPredicates<'tcx> { - self.root.per_def.explicit_predicates.get(self, item_id).unwrap().decode((self, tcx)) + self.root.tables.explicit_predicates.get(self, item_id).unwrap().decode((self, tcx)) } fn get_inferred_outlives( @@ -840,7 +840,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { tcx: TyCtxt<'tcx>, ) -> &'tcx [(ty::Predicate<'tcx>, Span)] { self.root - .per_def + .tables .inferred_outlives .get(self, item_id) .map(|predicates| predicates.decode((self, tcx))) @@ -852,31 +852,31 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { item_id: DefIndex, tcx: TyCtxt<'tcx>, ) -> ty::GenericPredicates<'tcx> { - self.root.per_def.super_predicates.get(self, item_id).unwrap().decode((self, tcx)) + self.root.tables.super_predicates.get(self, item_id).unwrap().decode((self, tcx)) } fn get_generics(&self, item_id: DefIndex, sess: &Session) -> ty::Generics { - self.root.per_def.generics.get(self, item_id).unwrap().decode((self, sess)) + self.root.tables.generics.get(self, item_id).unwrap().decode((self, sess)) } fn get_type(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { - self.root.per_def.ty.get(self, id).unwrap().decode((self, tcx)) + self.root.tables.ty.get(self, id).unwrap().decode((self, tcx)) } fn get_stability(&self, id: DefIndex) -> Option { match self.is_proc_macro(id) { true => self.root.proc_macro_stability, - false => self.root.per_def.stability.get(self, id).map(|stab| stab.decode(self)), + false => self.root.tables.stability.get(self, id).map(|stab| stab.decode(self)), } } fn get_const_stability(&self, id: DefIndex) -> Option { - self.root.per_def.const_stability.get(self, id).map(|stab| stab.decode(self)) + self.root.tables.const_stability.get(self, id).map(|stab| stab.decode(self)) } fn get_deprecation(&self, id: DefIndex) -> Option { self.root - .per_def + .tables .deprecation .get(self, id) .filter(|_| !self.is_proc_macro(id)) @@ -886,7 +886,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { fn get_visibility(&self, id: DefIndex) -> ty::Visibility { match self.is_proc_macro(id) { true => ty::Visibility::Public, - false => self.root.per_def.visibility.get(self, id).unwrap().decode(self), + false => self.root.tables.visibility.get(self, id).unwrap().decode(self), } } @@ -914,7 +914,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } fn get_impl_trait(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> Option> { - self.root.per_def.impl_trait_ref.get(self, id).map(|tr| tr.decode((self, tcx))) + self.root.tables.impl_trait_ref.get(self, id).map(|tr| tr.decode((self, tcx))) } /// Iterates over all the stability attributes in the given crate. @@ -984,7 +984,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { // Iterate over all children. let macros_only = self.dep_kind.lock().macros_only(); - let children = self.root.per_def.children.get(self, id).unwrap_or(Lazy::empty()); + let children = self.root.tables.children.get(self, id).unwrap_or(Lazy::empty()); for child_index in children.decode((self, sess)) { if macros_only { continue; @@ -1004,7 +1004,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { EntryKind::ForeignMod => { let child_children = self .root - .per_def + .tables .children .get(self, child_index) .unwrap_or(Lazy::empty()); @@ -1016,7 +1016,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { vis: self.get_visibility(child_index), span: self .root - .per_def + .tables .span .get(self, child_index) .unwrap() @@ -1096,13 +1096,13 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } fn is_item_mir_available(&self, id: DefIndex) -> bool { - !self.is_proc_macro(id) && self.root.per_def.mir.get(self, id).is_some() + !self.is_proc_macro(id) && self.root.tables.mir.get(self, id).is_some() } fn get_optimized_mir(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> BodyAndCache<'tcx> { let mut cache = self .root - .per_def + .tables .mir .get(self, id) .filter(|_| !self.is_proc_macro(id)) @@ -1121,7 +1121,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { ) -> IndexVec> { let mut cache = self .root - .per_def + .tables .promoted_mir .get(self, id) .filter(|_| !self.is_proc_macro(id)) @@ -1172,7 +1172,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } fn get_item_variances(&self, id: DefIndex) -> Vec { - self.root.per_def.variances.get(self, id).unwrap_or(Lazy::empty()).decode(self).collect() + self.root.tables.variances.get(self, id).unwrap_or(Lazy::empty()).decode(self).collect() } fn get_ctor_kind(&self, node_id: DefIndex) -> CtorKind { @@ -1209,7 +1209,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { Lrc::from( self.root - .per_def + .tables .attributes .get(self, item_id) .unwrap_or(Lazy::empty()) @@ -1220,7 +1220,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { fn get_struct_field_names(&self, id: DefIndex, sess: &Session) -> Vec> { self.root - .per_def + .tables .children .get(self, id) .unwrap_or(Lazy::empty()) @@ -1236,7 +1236,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { ) -> &'tcx [DefId] { tcx.arena.alloc_from_iter( self.root - .per_def + .tables .inherent_impls .get(self, id) .unwrap_or(Lazy::empty()) @@ -1416,7 +1416,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } fn fn_sig(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> { - self.root.per_def.fn_sig.get(self, id).unwrap().decode((self, tcx)) + self.root.tables.fn_sig.get(self, id).unwrap().decode((self, tcx)) } #[inline] diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index f6e2730cb5761..3cc5fb1a991e1 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -45,7 +45,7 @@ struct EncodeContext<'tcx> { opaque: opaque::Encoder, tcx: TyCtxt<'tcx>, - per_def: PerDefTableBuilders<'tcx>, + tables: TableBuilders<'tcx>, lazy_state: LazyState, type_shorthands: FxHashMap, usize>, @@ -497,8 +497,8 @@ impl<'tcx> EncodeContext<'tcx> { }; i = self.position(); - let per_def = self.per_def.encode(&mut self.opaque); - let per_def_bytes = self.position() - i; + let tables = self.tables.encode(&mut self.opaque); + let tables_bytes = self.position() - i; // Encode the proc macro data i = self.position(); @@ -560,7 +560,7 @@ impl<'tcx> EncodeContext<'tcx> { impls, exported_symbols, interpret_alloc_index, - per_def, + tables, }); let total_bytes = self.position(); @@ -585,7 +585,7 @@ impl<'tcx> EncodeContext<'tcx> { println!(" def-path table bytes: {}", def_path_table_bytes); println!(" proc-macro-data-bytes: {}", proc_macro_data_bytes); println!(" item bytes: {}", item_bytes); - println!(" per-def table bytes: {}", per_def_bytes); + println!(" table bytes: {}", tables_bytes); println!(" zero bytes: {}", zero_bytes); println!(" total bytes: {}", total_bytes); } @@ -597,12 +597,12 @@ impl<'tcx> EncodeContext<'tcx> { impl EncodeContext<'tcx> { fn encode_variances_of(&mut self, def_id: DefId) { debug!("EncodeContext::encode_variances_of({:?})", def_id); - record!(self.per_def.variances[def_id] <- &self.tcx.variances_of(def_id)[..]); + record!(self.tables.variances[def_id] <- &self.tcx.variances_of(def_id)[..]); } fn encode_item_type(&mut self, def_id: DefId) { debug!("EncodeContext::encode_item_type({:?})", def_id); - record!(self.per_def.ty[def_id] <- self.tcx.type_of(def_id)); + record!(self.tables.ty[def_id] <- self.tcx.type_of(def_id)); } fn encode_enum_variant_info(&mut self, enum_did: DefId, index: VariantIdx) { @@ -621,12 +621,12 @@ impl EncodeContext<'tcx> { let enum_id = tcx.hir().as_local_hir_id(enum_did).unwrap(); let enum_vis = &tcx.hir().expect_item(enum_id).vis; - record!(self.per_def.kind[def_id] <- EntryKind::Variant(self.lazy(data))); - record!(self.per_def.visibility[def_id] <- + record!(self.tables.kind[def_id] <- EntryKind::Variant(self.lazy(data))); + record!(self.tables.visibility[def_id] <- ty::Visibility::from_hir(enum_vis, enum_id, self.tcx)); - record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id)); - record!(self.per_def.attributes[def_id] <- &self.tcx.get_attrs(def_id)[..]); - record!(self.per_def.children[def_id] <- variant.fields.iter().map(|f| { + record!(self.tables.span[def_id] <- self.tcx.def_span(def_id)); + record!(self.tables.attributes[def_id] <- &self.tcx.get_attrs(def_id)[..]); + record!(self.tables.children[def_id] <- variant.fields.iter().map(|f| { assert!(f.did.is_local()); f.did.index })); @@ -637,7 +637,7 @@ impl EncodeContext<'tcx> { if variant.ctor_kind == CtorKind::Fn { // FIXME(eddyb) encode signature only in `encode_enum_variant_ctor`. if let Some(ctor_def_id) = variant.ctor_def_id { - record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(ctor_def_id)); + record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(ctor_def_id)); } // FIXME(eddyb) is this ever used? self.encode_variances_of(def_id); @@ -672,14 +672,14 @@ impl EncodeContext<'tcx> { ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)); } - record!(self.per_def.kind[def_id] <- EntryKind::Variant(self.lazy(data))); - record!(self.per_def.visibility[def_id] <- ctor_vis); - record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id)); + record!(self.tables.kind[def_id] <- EntryKind::Variant(self.lazy(data))); + record!(self.tables.visibility[def_id] <- ctor_vis); + record!(self.tables.span[def_id] <- self.tcx.def_span(def_id)); self.encode_stability(def_id); self.encode_deprecation(def_id); self.encode_item_type(def_id); if variant.ctor_kind == CtorKind::Fn { - record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id)); + record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); self.encode_variances_of(def_id); } self.encode_generics(def_id); @@ -707,11 +707,11 @@ impl EncodeContext<'tcx> { }, }; - record!(self.per_def.kind[def_id] <- EntryKind::Mod(self.lazy(data))); - record!(self.per_def.visibility[def_id] <- ty::Visibility::from_hir(vis, id, self.tcx)); - record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id)); - record!(self.per_def.attributes[def_id] <- attrs); - record!(self.per_def.children[def_id] <- md.item_ids.iter().map(|item_id| { + record!(self.tables.kind[def_id] <- EntryKind::Mod(self.lazy(data))); + record!(self.tables.visibility[def_id] <- ty::Visibility::from_hir(vis, id, self.tcx)); + record!(self.tables.span[def_id] <- self.tcx.def_span(def_id)); + record!(self.tables.attributes[def_id] <- attrs); + record!(self.tables.children[def_id] <- md.item_ids.iter().map(|item_id| { tcx.hir().local_def_id(item_id.id).index })); self.encode_stability(def_id); @@ -729,10 +729,10 @@ impl EncodeContext<'tcx> { let variant_id = tcx.hir().as_local_hir_id(variant.def_id).unwrap(); let variant_data = tcx.hir().expect_variant_data(variant_id); - record!(self.per_def.kind[def_id] <- EntryKind::Field); - record!(self.per_def.visibility[def_id] <- field.vis); - record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id)); - record!(self.per_def.attributes[def_id] <- variant_data.fields()[field_index].attrs); + record!(self.tables.kind[def_id] <- EntryKind::Field); + record!(self.tables.visibility[def_id] <- field.vis); + record!(self.tables.span[def_id] <- self.tcx.def_span(def_id)); + record!(self.tables.attributes[def_id] <- variant_data.fields()[field_index].attrs); self.encode_ident_span(def_id, field.ident); self.encode_stability(def_id); self.encode_deprecation(def_id); @@ -771,14 +771,14 @@ impl EncodeContext<'tcx> { ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)); } - record!(self.per_def.kind[def_id] <- EntryKind::Struct(self.lazy(data), adt_def.repr)); - record!(self.per_def.visibility[def_id] <- ctor_vis); - record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id)); + record!(self.tables.kind[def_id] <- EntryKind::Struct(self.lazy(data), adt_def.repr)); + record!(self.tables.visibility[def_id] <- ctor_vis); + record!(self.tables.span[def_id] <- self.tcx.def_span(def_id)); self.encode_stability(def_id); self.encode_deprecation(def_id); self.encode_item_type(def_id); if variant.ctor_kind == CtorKind::Fn { - record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id)); + record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); self.encode_variances_of(def_id); } self.encode_generics(def_id); @@ -790,12 +790,12 @@ impl EncodeContext<'tcx> { fn encode_generics(&mut self, def_id: DefId) { debug!("EncodeContext::encode_generics({:?})", def_id); - record!(self.per_def.generics[def_id] <- self.tcx.generics_of(def_id)); + record!(self.tables.generics[def_id] <- self.tcx.generics_of(def_id)); } fn encode_explicit_predicates(&mut self, def_id: DefId) { debug!("EncodeContext::encode_explicit_predicates({:?})", def_id); - record!(self.per_def.explicit_predicates[def_id] <- + record!(self.tables.explicit_predicates[def_id] <- self.tcx.explicit_predicates_of(def_id)); } @@ -803,13 +803,13 @@ impl EncodeContext<'tcx> { debug!("EncodeContext::encode_inferred_outlives({:?})", def_id); let inferred_outlives = self.tcx.inferred_outlives_of(def_id); if !inferred_outlives.is_empty() { - record!(self.per_def.inferred_outlives[def_id] <- inferred_outlives); + record!(self.tables.inferred_outlives[def_id] <- inferred_outlives); } } fn encode_super_predicates(&mut self, def_id: DefId) { debug!("EncodeContext::encode_super_predicates({:?})", def_id); - record!(self.per_def.super_predicates[def_id] <- self.tcx.super_predicates_of(def_id)); + record!(self.tables.super_predicates[def_id] <- self.tcx.super_predicates_of(def_id)); } fn encode_info_for_trait_item(&mut self, def_id: DefId) { @@ -826,7 +826,7 @@ impl EncodeContext<'tcx> { hir::Defaultness::Final => span_bug!(ast_item.span, "traits cannot have final items"), }; - record!(self.per_def.kind[def_id] <- match trait_item.kind { + record!(self.tables.kind[def_id] <- match trait_item.kind { ty::AssocKind::Const => { let rendered = rustc_hir_pretty::to_string( &(&self.tcx.hir() as &dyn intravisit::Map<'_>), @@ -867,9 +867,9 @@ impl EncodeContext<'tcx> { ty::AssocKind::Type => EntryKind::AssocType(container), ty::AssocKind::OpaqueTy => span_bug!(ast_item.span, "opaque type in trait"), }); - record!(self.per_def.visibility[def_id] <- trait_item.vis); - record!(self.per_def.span[def_id] <- ast_item.span); - record!(self.per_def.attributes[def_id] <- ast_item.attrs); + record!(self.tables.visibility[def_id] <- trait_item.vis); + record!(self.tables.span[def_id] <- ast_item.span); + record!(self.tables.attributes[def_id] <- ast_item.attrs); self.encode_ident_span(def_id, ast_item.ident); self.encode_stability(def_id); self.encode_const_stability(def_id); @@ -886,7 +886,7 @@ impl EncodeContext<'tcx> { ty::AssocKind::OpaqueTy => unreachable!(), } if trait_item.kind == ty::AssocKind::Method { - record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id)); + record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); self.encode_variances_of(def_id); } self.encode_generics(def_id); @@ -919,7 +919,7 @@ impl EncodeContext<'tcx> { } }; - record!(self.per_def.kind[def_id] <- match impl_item.kind { + record!(self.tables.kind[def_id] <- match impl_item.kind { ty::AssocKind::Const => { if let hir::ImplItemKind::Const(_, body_id) = ast_item.kind { let qualifs = self.tcx.at(ast_item.span).mir_const_qualif(def_id); @@ -951,16 +951,16 @@ impl EncodeContext<'tcx> { ty::AssocKind::OpaqueTy => EntryKind::AssocOpaqueTy(container), ty::AssocKind::Type => EntryKind::AssocType(container) }); - record!(self.per_def.visibility[def_id] <- impl_item.vis); - record!(self.per_def.span[def_id] <- ast_item.span); - record!(self.per_def.attributes[def_id] <- ast_item.attrs); + record!(self.tables.visibility[def_id] <- impl_item.vis); + record!(self.tables.span[def_id] <- ast_item.span); + record!(self.tables.attributes[def_id] <- ast_item.attrs); self.encode_ident_span(def_id, impl_item.ident); self.encode_stability(def_id); self.encode_const_stability(def_id); self.encode_deprecation(def_id); self.encode_item_type(def_id); if impl_item.kind == ty::AssocKind::Method { - record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id)); + record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); self.encode_variances_of(def_id); } self.encode_generics(def_id); @@ -1005,14 +1005,14 @@ impl EncodeContext<'tcx> { fn encode_optimized_mir(&mut self, def_id: DefId) { debug!("EntryBuilder::encode_mir({:?})", def_id); if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id) { - record!(self.per_def.mir[def_id] <- self.tcx.optimized_mir(def_id)); + record!(self.tables.mir[def_id] <- self.tcx.optimized_mir(def_id)); } } fn encode_promoted_mir(&mut self, def_id: DefId) { debug!("EncodeContext::encode_promoted_mir({:?})", def_id); if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id) { - record!(self.per_def.promoted_mir[def_id] <- self.tcx.promoted_mir(def_id)); + record!(self.tables.promoted_mir[def_id] <- self.tcx.promoted_mir(def_id)); } } @@ -1021,7 +1021,7 @@ impl EncodeContext<'tcx> { debug!("EncodeContext::encode_inherent_implementations({:?})", def_id); let implementations = self.tcx.inherent_impls(def_id); if !implementations.is_empty() { - record!(self.per_def.inherent_impls[def_id] <- implementations.iter().map(|&def_id| { + record!(self.tables.inherent_impls[def_id] <- implementations.iter().map(|&def_id| { assert!(def_id.is_local()); def_id.index })); @@ -1031,21 +1031,21 @@ impl EncodeContext<'tcx> { fn encode_stability(&mut self, def_id: DefId) { debug!("EncodeContext::encode_stability({:?})", def_id); if let Some(stab) = self.tcx.lookup_stability(def_id) { - record!(self.per_def.stability[def_id] <- stab) + record!(self.tables.stability[def_id] <- stab) } } fn encode_const_stability(&mut self, def_id: DefId) { debug!("EncodeContext::encode_const_stability({:?})", def_id); if let Some(stab) = self.tcx.lookup_const_stability(def_id) { - record!(self.per_def.const_stability[def_id] <- stab) + record!(self.tables.const_stability[def_id] <- stab) } } fn encode_deprecation(&mut self, def_id: DefId) { debug!("EncodeContext::encode_deprecation({:?})", def_id); if let Some(depr) = self.tcx.lookup_deprecation(def_id) { - record!(self.per_def.deprecation[def_id] <- depr); + record!(self.tables.deprecation[def_id] <- depr); } } @@ -1066,7 +1066,7 @@ impl EncodeContext<'tcx> { self.encode_ident_span(def_id, item.ident); - record!(self.per_def.kind[def_id] <- match item.kind { + record!(self.tables.kind[def_id] <- match item.kind { hir::ItemKind::Static(_, hir::Mutability::Mut, _) => EntryKind::MutStatic, hir::ItemKind::Static(_, hir::Mutability::Not, _) => EntryKind::ImmStatic, hir::ItemKind::Const(_, body_id) => { @@ -1172,26 +1172,26 @@ impl EncodeContext<'tcx> { hir::ItemKind::ExternCrate(_) | hir::ItemKind::Use(..) => bug!("cannot encode info for item {:?}", item), }); - record!(self.per_def.visibility[def_id] <- + record!(self.tables.visibility[def_id] <- ty::Visibility::from_hir(&item.vis, item.hir_id, tcx)); - record!(self.per_def.span[def_id] <- item.span); - record!(self.per_def.attributes[def_id] <- item.attrs); + record!(self.tables.span[def_id] <- item.span); + record!(self.tables.attributes[def_id] <- item.attrs); // FIXME(eddyb) there should be a nicer way to do this. match item.kind { - hir::ItemKind::ForeignMod(ref fm) => record!(self.per_def.children[def_id] <- + hir::ItemKind::ForeignMod(ref fm) => record!(self.tables.children[def_id] <- fm.items .iter() .map(|foreign_item| tcx.hir().local_def_id( foreign_item.hir_id).index) ), - hir::ItemKind::Enum(..) => record!(self.per_def.children[def_id] <- + hir::ItemKind::Enum(..) => record!(self.tables.children[def_id] <- self.tcx.adt_def(def_id).variants.iter().map(|v| { assert!(v.def_id.is_local()); v.def_id.index }) ), hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => { - record!(self.per_def.children[def_id] <- + record!(self.tables.children[def_id] <- self.tcx.adt_def(def_id).non_enum_variant().fields.iter().map(|f| { assert!(f.did.is_local()); f.did.index @@ -1200,7 +1200,7 @@ impl EncodeContext<'tcx> { } hir::ItemKind::Impl { .. } | hir::ItemKind::Trait(..) => { let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id); - record!(self.per_def.children[def_id] <- + record!(self.tables.children[def_id] <- associated_item_def_ids.iter().map(|&def_id| { assert!(def_id.is_local()); def_id.index @@ -1225,11 +1225,11 @@ impl EncodeContext<'tcx> { _ => {} } if let hir::ItemKind::Fn(..) = item.kind { - record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id)); + record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); } if let hir::ItemKind::Impl { .. } = item.kind { if let Some(trait_ref) = self.tcx.impl_trait_ref(def_id) { - record!(self.per_def.impl_trait_ref[def_id] <- trait_ref); + record!(self.tables.impl_trait_ref[def_id] <- trait_ref); } } self.encode_inherent_implementations(def_id); @@ -1288,19 +1288,19 @@ impl EncodeContext<'tcx> { /// Serialize the text of exported macros fn encode_info_for_macro_def(&mut self, macro_def: &hir::MacroDef<'_>) { let def_id = self.tcx.hir().local_def_id(macro_def.hir_id); - record!(self.per_def.kind[def_id] <- EntryKind::MacroDef(self.lazy(macro_def.ast.clone()))); - record!(self.per_def.visibility[def_id] <- ty::Visibility::Public); - record!(self.per_def.span[def_id] <- macro_def.span); - record!(self.per_def.attributes[def_id] <- macro_def.attrs); + record!(self.tables.kind[def_id] <- EntryKind::MacroDef(self.lazy(macro_def.ast.clone()))); + record!(self.tables.visibility[def_id] <- ty::Visibility::Public); + record!(self.tables.span[def_id] <- macro_def.span); + record!(self.tables.attributes[def_id] <- macro_def.attrs); self.encode_ident_span(def_id, macro_def.ident); self.encode_stability(def_id); self.encode_deprecation(def_id); } fn encode_info_for_generic_param(&mut self, def_id: DefId, kind: EntryKind, encode_type: bool) { - record!(self.per_def.kind[def_id] <- kind); - record!(self.per_def.visibility[def_id] <- ty::Visibility::Public); - record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id)); + record!(self.tables.kind[def_id] <- kind); + record!(self.tables.visibility[def_id] <- ty::Visibility::Public); + record!(self.tables.span[def_id] <- self.tcx.def_span(def_id)); if encode_type { self.encode_item_type(def_id); } @@ -1314,7 +1314,7 @@ impl EncodeContext<'tcx> { let hir_id = self.tcx.hir().as_local_hir_id(def_id).unwrap(); let ty = self.tcx.typeck_tables_of(def_id).node_type(hir_id); - record!(self.per_def.kind[def_id] <- match ty.kind { + record!(self.tables.kind[def_id] <- match ty.kind { ty::Generator(..) => { let data = self.tcx.generator_kind(def_id).unwrap(); EntryKind::Generator(data) @@ -1324,12 +1324,12 @@ impl EncodeContext<'tcx> { _ => bug!("closure that is neither generator nor closure"), }); - record!(self.per_def.visibility[def_id] <- ty::Visibility::Public); - record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id)); - record!(self.per_def.attributes[def_id] <- &self.tcx.get_attrs(def_id)[..]); + record!(self.tables.visibility[def_id] <- ty::Visibility::Public); + record!(self.tables.span[def_id] <- self.tcx.def_span(def_id)); + record!(self.tables.attributes[def_id] <- &self.tcx.get_attrs(def_id)[..]); self.encode_item_type(def_id); if let ty::Closure(def_id, substs) = ty.kind { - record!(self.per_def.fn_sig[def_id] <- substs.as_closure().sig()); + record!(self.tables.fn_sig[def_id] <- substs.as_closure().sig()); } self.encode_generics(def_id); self.encode_optimized_mir(def_id); @@ -1343,9 +1343,9 @@ impl EncodeContext<'tcx> { let const_data = self.encode_rendered_const_for_body(body_id); let qualifs = self.tcx.mir_const_qualif(def_id); - record!(self.per_def.kind[def_id] <- EntryKind::Const(qualifs, const_data)); - record!(self.per_def.visibility[def_id] <- ty::Visibility::Public); - record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id)); + record!(self.tables.kind[def_id] <- EntryKind::Const(qualifs, const_data)); + record!(self.tables.visibility[def_id] <- ty::Visibility::Public); + record!(self.tables.span[def_id] <- self.tcx.def_span(def_id)); self.encode_item_type(def_id); self.encode_generics(def_id); self.encode_explicit_predicates(def_id); @@ -1516,7 +1516,7 @@ impl EncodeContext<'tcx> { debug!("EncodeContext::encode_info_for_foreign_item({:?})", def_id); - record!(self.per_def.kind[def_id] <- match nitem.kind { + record!(self.tables.kind[def_id] <- match nitem.kind { hir::ForeignItemKind::Fn(_, ref names, _) => { let data = FnData { asyncness: hir::IsAsync::NotAsync, @@ -1533,17 +1533,17 @@ impl EncodeContext<'tcx> { hir::ForeignItemKind::Static(_, hir::Mutability::Not) => EntryKind::ForeignImmStatic, hir::ForeignItemKind::Type => EntryKind::ForeignType, }); - record!(self.per_def.visibility[def_id] <- + record!(self.tables.visibility[def_id] <- ty::Visibility::from_hir(&nitem.vis, nitem.hir_id, self.tcx)); - record!(self.per_def.span[def_id] <- nitem.span); - record!(self.per_def.attributes[def_id] <- nitem.attrs); + record!(self.tables.span[def_id] <- nitem.span); + record!(self.tables.attributes[def_id] <- nitem.attrs); self.encode_ident_span(def_id, nitem.ident); self.encode_stability(def_id); self.encode_const_stability(def_id); self.encode_deprecation(def_id); self.encode_item_type(def_id); if let hir::ForeignItemKind::Fn(..) = nitem.kind { - record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id)); + record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); self.encode_variances_of(def_id); } self.encode_generics(def_id); @@ -1630,7 +1630,7 @@ impl EncodeContext<'tcx> { } fn encode_ident_span(&mut self, def_id: DefId, ident: Ident) { - record!(self.per_def.ident_span[def_id] <- ident.span); + record!(self.tables.ident_span[def_id] <- ident.span); } /// In some cases, along with the item itself, we also @@ -1846,7 +1846,7 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>) -> EncodedMetadata { let mut ecx = EncodeContext { opaque: encoder, tcx, - per_def: Default::default(), + tables: Default::default(), lazy_state: LazyState::NoNode, type_shorthands: Default::default(), predicate_shorthands: Default::default(), diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs index d0ad76b0fc7ea..8aa70293aab01 100644 --- a/src/librustc_metadata/rmeta/mod.rs +++ b/src/librustc_metadata/rmeta/mod.rs @@ -197,7 +197,7 @@ crate struct CrateRoot<'tcx> { impls: Lazy<[TraitImpls]>, interpret_alloc_index: Lazy<[u32]>, - per_def: LazyPerDefTables<'tcx>, + tables: LazyTables<'tcx>, /// The DefIndex's of any proc macros declared by this crate. proc_macro_data: Option>, @@ -228,22 +228,22 @@ crate struct TraitImpls { impls: Lazy<[DefIndex]>, } -/// Define `LazyPerDefTables` and `PerDefTableBuilders` at the same time. -macro_rules! define_per_def_tables { +/// Define `LazyTables` and `TableBuilders` at the same time. +macro_rules! define_tables { ($($name:ident: Table),+ $(,)?) => { #[derive(RustcEncodable, RustcDecodable)] - crate struct LazyPerDefTables<'tcx> { + crate struct LazyTables<'tcx> { $($name: Lazy!(Table)),+ } #[derive(Default)] - struct PerDefTableBuilders<'tcx> { + struct TableBuilders<'tcx> { $($name: TableBuilder),+ } - impl PerDefTableBuilders<'tcx> { - fn encode(&self, buf: &mut Encoder) -> LazyPerDefTables<'tcx> { - LazyPerDefTables { + impl TableBuilders<'tcx> { + fn encode(&self, buf: &mut Encoder) -> LazyTables<'tcx> { + LazyTables { $($name: self.$name.encode(buf)),+ } } @@ -251,7 +251,7 @@ macro_rules! define_per_def_tables { } } -define_per_def_tables! { +define_tables! { kind: Table>, visibility: Table>, span: Table>, diff --git a/src/librustc_middle/ty/flags.rs b/src/librustc_middle/ty/flags.rs index 5243e1fbf579b..99a6511b297ac 100644 --- a/src/librustc_middle/ty/flags.rs +++ b/src/librustc_middle/ty/flags.rs @@ -1,4 +1,4 @@ -use crate::ty::subst::{GenericArgKind, SubstsRef}; +use crate::ty::subst::{GenericArg, GenericArgKind}; use crate::ty::{self, InferConst, Ty, TypeFlags}; #[derive(Debug)] @@ -81,6 +81,7 @@ impl FlagComputation { &ty::Param(_) => { self.add_flags(TypeFlags::HAS_TY_PARAM); + self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); } &ty::Generator(_, ref substs, _) => { @@ -99,14 +100,17 @@ impl FlagComputation { &ty::Bound(debruijn, _) => { self.add_binder(debruijn); + self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); } &ty::Placeholder(..) => { self.add_flags(TypeFlags::HAS_TY_PLACEHOLDER); + self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); } &ty::Infer(infer) => { self.add_flags(TypeFlags::HAS_TY_INFER); + self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); match infer { ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => {} @@ -218,17 +222,23 @@ impl FlagComputation { } ty::ConstKind::Infer(infer) => { self.add_flags(TypeFlags::HAS_CT_INFER); + self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); match infer { InferConst::Fresh(_) => {} InferConst::Var(_) => self.add_flags(TypeFlags::KEEP_IN_LOCAL_TCX), } } - ty::ConstKind::Bound(debruijn, _) => self.add_binder(debruijn), + ty::ConstKind::Bound(debruijn, _) => { + self.add_binder(debruijn); + self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); + } ty::ConstKind::Param(_) => { self.add_flags(TypeFlags::HAS_CT_PARAM); + self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); } ty::ConstKind::Placeholder(_) => { self.add_flags(TypeFlags::HAS_CT_PLACEHOLDER); + self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); } ty::ConstKind::Value(_) => {} } @@ -243,7 +253,7 @@ impl FlagComputation { self.add_substs(projection_ty.substs); } - fn add_substs(&mut self, substs: SubstsRef<'_>) { + fn add_substs(&mut self, substs: &[GenericArg<'_>]) { for kind in substs { match kind.unpack() { GenericArgKind::Type(ty) => self.add_ty(ty), diff --git a/src/librustc_middle/ty/fold.rs b/src/librustc_middle/ty/fold.rs index 3f4f2407f1e6e..a3d611a132592 100644 --- a/src/librustc_middle/ty/fold.rs +++ b/src/librustc_middle/ty/fold.rs @@ -142,6 +142,13 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { self.has_type_flags(TypeFlags::HAS_RE_LATE_BOUND) } + /// Indicates whether this value still has parameters/placeholders/inference variables + /// which could be replaced later, in a way that would change the results of `impl` + /// specialization. + fn still_further_specializable(&self) -> bool { + self.has_type_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE) + } + /// A visitor that does not recurse into types, works like `fn walk_shallow` in `Ty`. fn visit_tys_shallow(&self, visit: impl FnMut(Ty<'tcx>) -> bool) -> bool { pub struct Visitor(F); diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs index 43982439d47c8..2585de07a5b4f 100644 --- a/src/librustc_middle/ty/mod.rs +++ b/src/librustc_middle/ty/mod.rs @@ -524,101 +524,106 @@ bitflags! { // Does this have parameters? Used to determine whether substitution is // required. /// Does this have [Param]? - const HAS_TY_PARAM = 1 << 0; + const HAS_TY_PARAM = 1 << 0; /// Does this have [ReEarlyBound]? - const HAS_RE_PARAM = 1 << 1; + const HAS_RE_PARAM = 1 << 1; /// Does this have [ConstKind::Param]? - const HAS_CT_PARAM = 1 << 2; + const HAS_CT_PARAM = 1 << 2; - const NEEDS_SUBST = TypeFlags::HAS_TY_PARAM.bits - | TypeFlags::HAS_RE_PARAM.bits - | TypeFlags::HAS_CT_PARAM.bits; + const NEEDS_SUBST = TypeFlags::HAS_TY_PARAM.bits + | TypeFlags::HAS_RE_PARAM.bits + | TypeFlags::HAS_CT_PARAM.bits; /// Does this have [Infer]? - const HAS_TY_INFER = 1 << 3; + const HAS_TY_INFER = 1 << 3; /// Does this have [ReVar]? - const HAS_RE_INFER = 1 << 4; + const HAS_RE_INFER = 1 << 4; /// Does this have [ConstKind::Infer]? - const HAS_CT_INFER = 1 << 5; + const HAS_CT_INFER = 1 << 5; /// Does this have inference variables? Used to determine whether /// inference is required. - const NEEDS_INFER = TypeFlags::HAS_TY_INFER.bits - | TypeFlags::HAS_RE_INFER.bits - | TypeFlags::HAS_CT_INFER.bits; + const NEEDS_INFER = TypeFlags::HAS_TY_INFER.bits + | TypeFlags::HAS_RE_INFER.bits + | TypeFlags::HAS_CT_INFER.bits; /// Does this have [Placeholder]? - const HAS_TY_PLACEHOLDER = 1 << 6; + const HAS_TY_PLACEHOLDER = 1 << 6; /// Does this have [RePlaceholder]? - const HAS_RE_PLACEHOLDER = 1 << 7; + const HAS_RE_PLACEHOLDER = 1 << 7; /// Does this have [ConstKind::Placeholder]? - const HAS_CT_PLACEHOLDER = 1 << 8; + const HAS_CT_PLACEHOLDER = 1 << 8; /// `true` if there are "names" of regions and so forth /// that are local to a particular fn/inferctxt - const HAS_FREE_LOCAL_REGIONS = 1 << 9; + const HAS_FREE_LOCAL_REGIONS = 1 << 9; /// `true` if there are "names" of types and regions and so forth /// that are local to a particular fn - const HAS_FREE_LOCAL_NAMES = TypeFlags::HAS_TY_PARAM.bits - | TypeFlags::HAS_CT_PARAM.bits - | TypeFlags::HAS_TY_INFER.bits - | TypeFlags::HAS_CT_INFER.bits - | TypeFlags::HAS_TY_PLACEHOLDER.bits - | TypeFlags::HAS_CT_PLACEHOLDER.bits - | TypeFlags::HAS_FREE_LOCAL_REGIONS.bits; + const HAS_FREE_LOCAL_NAMES = TypeFlags::HAS_TY_PARAM.bits + | TypeFlags::HAS_CT_PARAM.bits + | TypeFlags::HAS_TY_INFER.bits + | TypeFlags::HAS_CT_INFER.bits + | TypeFlags::HAS_TY_PLACEHOLDER.bits + | TypeFlags::HAS_CT_PLACEHOLDER.bits + | TypeFlags::HAS_FREE_LOCAL_REGIONS.bits; /// Does this have [Projection] or [UnnormalizedProjection]? - const HAS_TY_PROJECTION = 1 << 10; + const HAS_TY_PROJECTION = 1 << 10; /// Does this have [Opaque]? - const HAS_TY_OPAQUE = 1 << 11; + const HAS_TY_OPAQUE = 1 << 11; /// Does this have [ConstKind::Unevaluated]? - const HAS_CT_PROJECTION = 1 << 12; + const HAS_CT_PROJECTION = 1 << 12; /// Could this type be normalized further? - const HAS_PROJECTION = TypeFlags::HAS_TY_PROJECTION.bits - | TypeFlags::HAS_TY_OPAQUE.bits - | TypeFlags::HAS_CT_PROJECTION.bits; + const HAS_PROJECTION = TypeFlags::HAS_TY_PROJECTION.bits + | TypeFlags::HAS_TY_OPAQUE.bits + | TypeFlags::HAS_CT_PROJECTION.bits; /// Present if the type belongs in a local type context. /// Set for placeholders and inference variables that are not "Fresh". - const KEEP_IN_LOCAL_TCX = 1 << 13; + const KEEP_IN_LOCAL_TCX = 1 << 13; /// Is an error type reachable? - const HAS_TY_ERR = 1 << 14; + const HAS_TY_ERR = 1 << 14; /// Does this have any region that "appears free" in the type? /// Basically anything but [ReLateBound] and [ReErased]. - const HAS_FREE_REGIONS = 1 << 15; + const HAS_FREE_REGIONS = 1 << 15; /// Does this have any [ReLateBound] regions? Used to check /// if a global bound is safe to evaluate. - const HAS_RE_LATE_BOUND = 1 << 16; + const HAS_RE_LATE_BOUND = 1 << 16; /// Does this have any [ReErased] regions? - const HAS_RE_ERASED = 1 << 17; + const HAS_RE_ERASED = 1 << 17; + + /// Does this value have parameters/placeholders/inference variables which could be + /// replaced later, in a way that would change the results of `impl` specialization? + const STILL_FURTHER_SPECIALIZABLE = 1 << 18; /// Flags representing the nominal content of a type, /// computed by FlagsComputation. If you add a new nominal /// flag, it should be added here too. - const NOMINAL_FLAGS = TypeFlags::HAS_TY_PARAM.bits - | TypeFlags::HAS_RE_PARAM.bits - | TypeFlags::HAS_CT_PARAM.bits - | TypeFlags::HAS_TY_INFER.bits - | TypeFlags::HAS_RE_INFER.bits - | TypeFlags::HAS_CT_INFER.bits - | TypeFlags::HAS_TY_PLACEHOLDER.bits - | TypeFlags::HAS_RE_PLACEHOLDER.bits - | TypeFlags::HAS_CT_PLACEHOLDER.bits - | TypeFlags::HAS_FREE_LOCAL_REGIONS.bits - | TypeFlags::HAS_TY_PROJECTION.bits - | TypeFlags::HAS_TY_OPAQUE.bits - | TypeFlags::HAS_CT_PROJECTION.bits - | TypeFlags::KEEP_IN_LOCAL_TCX.bits - | TypeFlags::HAS_TY_ERR.bits - | TypeFlags::HAS_FREE_REGIONS.bits - | TypeFlags::HAS_RE_LATE_BOUND.bits - | TypeFlags::HAS_RE_ERASED.bits; + const NOMINAL_FLAGS = TypeFlags::HAS_TY_PARAM.bits + | TypeFlags::HAS_RE_PARAM.bits + | TypeFlags::HAS_CT_PARAM.bits + | TypeFlags::HAS_TY_INFER.bits + | TypeFlags::HAS_RE_INFER.bits + | TypeFlags::HAS_CT_INFER.bits + | TypeFlags::HAS_TY_PLACEHOLDER.bits + | TypeFlags::HAS_RE_PLACEHOLDER.bits + | TypeFlags::HAS_CT_PLACEHOLDER.bits + | TypeFlags::HAS_FREE_LOCAL_REGIONS.bits + | TypeFlags::HAS_TY_PROJECTION.bits + | TypeFlags::HAS_TY_OPAQUE.bits + | TypeFlags::HAS_CT_PROJECTION.bits + | TypeFlags::KEEP_IN_LOCAL_TCX.bits + | TypeFlags::HAS_TY_ERR.bits + | TypeFlags::HAS_FREE_REGIONS.bits + | TypeFlags::HAS_RE_LATE_BOUND.bits + | TypeFlags::HAS_RE_ERASED.bits + | TypeFlags::STILL_FURTHER_SPECIALIZABLE.bits; } } diff --git a/src/librustc_middle/ty/sty.rs b/src/librustc_middle/ty/sty.rs index 57df50dc1a05d..e98ea097c901e 100644 --- a/src/librustc_middle/ty/sty.rs +++ b/src/librustc_middle/ty/sty.rs @@ -1623,16 +1623,19 @@ impl RegionKind { flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS; flags = flags | TypeFlags::HAS_RE_INFER; flags = flags | TypeFlags::KEEP_IN_LOCAL_TCX; + flags = flags | TypeFlags::STILL_FURTHER_SPECIALIZABLE; } ty::RePlaceholder(..) => { flags = flags | TypeFlags::HAS_FREE_REGIONS; flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS; flags = flags | TypeFlags::HAS_RE_PLACEHOLDER; + flags = flags | TypeFlags::STILL_FURTHER_SPECIALIZABLE; } ty::ReEarlyBound(..) => { flags = flags | TypeFlags::HAS_FREE_REGIONS; flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS; flags = flags | TypeFlags::HAS_RE_PARAM; + flags = flags | TypeFlags::STILL_FURTHER_SPECIALIZABLE; } ty::ReFree { .. } | ty::ReScope { .. } => { flags = flags | TypeFlags::HAS_FREE_REGIONS; diff --git a/src/librustc_trait_selection/traits/project.rs b/src/librustc_trait_selection/traits/project.rs index aae0d46756331..3057b79547dc0 100644 --- a/src/librustc_trait_selection/traits/project.rs +++ b/src/librustc_trait_selection/traits/project.rs @@ -1028,7 +1028,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( // assume `poly_trait_ref` isn't monomorphic, if it contains any. let poly_trait_ref = selcx.infcx().resolve_vars_if_possible(&poly_trait_ref); - !poly_trait_ref.needs_infer() && !poly_trait_ref.needs_subst() + !poly_trait_ref.still_further_specializable() } else { debug!( "assemble_candidates_from_impls: not eligible due to default: \ diff --git a/src/librustc_ty/instance.rs b/src/librustc_ty/instance.rs index 47c4b1c41cdbd..e845cc9a15869 100644 --- a/src/librustc_ty/instance.rs +++ b/src/librustc_ty/instance.rs @@ -127,7 +127,11 @@ fn resolve_associated_item<'tcx>( // and the obligation is monomorphic, otherwise passes such as // transmute checking and polymorphic MIR optimizations could // get a result which isn't correct for all monomorphizations. - if param_env.reveal == Reveal::All { !trait_ref.needs_subst() } else { false } + if param_env.reveal == Reveal::All { + !trait_ref.still_further_specializable() + } else { + false + } }; if !eligible { diff --git a/src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.rs b/src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.rs new file mode 100644 index 0000000000000..bdfc29a3d57ab --- /dev/null +++ b/src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.rs @@ -0,0 +1,5 @@ +// This won't actually panic because of the error comment -- the `"` needs to be +// the last byte in the file (including not having a trailing newline) +// Prior to the fix you get the error: 'expected item, found `r" ...`' +// because the string being unterminated wasn't properly detected. +r" //~ unterminated raw string diff --git a/src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.stderr b/src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.stderr new file mode 100644 index 0000000000000..3a7e2a4b14afb --- /dev/null +++ b/src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.stderr @@ -0,0 +1,9 @@ +error[E0748]: unterminated raw string + --> $DIR/issue-70677-panic-on-unterminated-raw-str-at-eof.rs:5:1 + | +LL | r" + | ^ unterminated raw string + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0748`. diff --git a/src/tools/cargo b/src/tools/cargo index 8a0d4d9c9abc7..6e07d2dfb7fc8 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 8a0d4d9c9abc74fd670353094387d62028b40ae9 +Subproject commit 6e07d2dfb7fc87b1c9489de41da4dafa239daf03