@@ -2276,6 +2276,37 @@ fn document_stability(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item)
22762276 Ok ( ( ) )
22772277}
22782278
2279+ fn document_non_exhaustive_header ( item : & clean:: Item ) -> & str {
2280+ if item. is_non_exhaustive ( ) { " (Non-exhaustive)" } else { "" }
2281+ }
2282+
2283+ fn document_non_exhaustive ( w : & mut fmt:: Formatter , item : & clean:: Item ) -> fmt:: Result {
2284+ if item. is_non_exhaustive ( ) {
2285+ write ! ( w, "<div class='docblock non-exhaustive non-exhaustive-{}'>" , {
2286+ if item. is_struct( ) { "struct" } else if item. is_enum( ) { "enum" } else { "type" }
2287+ } ) ?;
2288+
2289+ if item. is_struct ( ) {
2290+ write ! ( w, "Non-exhaustive structs could have additional fields added in future. \
2291+ Therefore, non-exhaustive structs cannot be constructed in external crates \
2292+ using the traditional <code>Struct {{ .. }}</code> syntax; cannot be \
2293+ matched against without a wildcard <code>..</code>; and \
2294+ struct update syntax will not work.") ?;
2295+ } else if item. is_enum ( ) {
2296+ write ! ( w, "Non-exhaustive enums could have additional variants added in future. \
2297+ Therefore, when matching against variants of non-exhaustive enums, an \
2298+ extra wildcard arm must be added to account for any future variants.") ?;
2299+ } else {
2300+ write ! ( w, "This type will require a wildcard arm in any match statements or \
2301+ constructors.") ?;
2302+ }
2303+
2304+ write ! ( w, "</div>" ) ?;
2305+ }
2306+
2307+ Ok ( ( ) )
2308+ }
2309+
22792310fn name_key ( name : & str ) -> ( & str , u64 , usize ) {
22802311 // find number at end
22812312 let split = name. bytes ( ) . rposition ( |b| b < b'0' || b'9' < b) . map_or ( 0 , |s| s + 1 ) ;
@@ -3136,7 +3167,9 @@ fn item_struct(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
31363167 if let doctree:: Plain = s. struct_type {
31373168 if fields. peek ( ) . is_some ( ) {
31383169 write ! ( w, "<h2 id='fields' class='fields small-section-header'>
3139- Fields<a href='#fields' class='anchor'></a></h2>" ) ?;
3170+ Fields{}<a href='#fields' class='anchor'></a></h2>" ,
3171+ document_non_exhaustive_header( it) ) ?;
3172+ document_non_exhaustive ( w, it) ?;
31403173 for ( field, ty) in fields {
31413174 let id = derive_id ( format ! ( "{}.{}" ,
31423175 ItemType :: StructField ,
@@ -3268,7 +3301,9 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
32683301 document ( w, cx, it) ?;
32693302 if !e. variants . is_empty ( ) {
32703303 write ! ( w, "<h2 id='variants' class='variants small-section-header'>
3271- Variants<a href='#variants' class='anchor'></a></h2>\n " ) ?;
3304+ Variants{}<a href='#variants' class='anchor'></a></h2>\n " ,
3305+ document_non_exhaustive_header( it) ) ?;
3306+ document_non_exhaustive ( w, it) ?;
32723307 for variant in & e. variants {
32733308 let id = derive_id ( format ! ( "{}.{}" ,
32743309 ItemType :: Variant ,
@@ -3369,7 +3404,8 @@ const ATTRIBUTE_WHITELIST: &'static [&'static str] = &[
33693404 "must_use" ,
33703405 "no_mangle" ,
33713406 "repr" ,
3372- "unsafe_destructor_blind_to_params"
3407+ "unsafe_destructor_blind_to_params" ,
3408+ "non_exhaustive"
33733409] ;
33743410
33753411fn render_attributes ( w : & mut fmt:: Formatter , it : & clean:: Item ) -> fmt:: Result {
0 commit comments